一种3D空间的柱状多边形检测实现

最近无意中拓展出这个东西,基于之前写的2D多边形检测:

http://www.cnblogs.com/hont/p/6105997.html

而判断两条线相交的方法也替换成了我后来写的差乘判断:

http://www.cnblogs.com/hont/p/6106043.html

应用还是比较广泛的,特别是多边形选区和地形处理上

代码:

using UnityEngine;
using System.Linq;
using System.Collections;

public class Test : MonoBehaviour
{
    public Transform testComparePoint;
    public Transform[] pointsArray;
    public float height = 4;

    public bool IsInRange(Vector3 comparePoint)
    {
        if (comparePoint != null)
        {
            var flag = true;
            flag &= comparePoint.y <= height;
            flag &= comparePoint.y >= -height;
            flag &= IsConcaveContain2D(pointsArray, comparePoint);

            if (flag)
                return true;
        }

        return false;
    }

    public bool IsConcaveContain2D(Transform[] points, Vector3 compare)
    {
        const float VIRTUAL_RAYCAST_LEN = 100000;

        var comparePoint = (points[1].localPosition + points[0].localPosition) * 0.5f;
        var originPoint = compare;
        comparePoint += (comparePoint - originPoint).normalized * VIRTUAL_RAYCAST_LEN;

        int count = 0;
        for (int i = 0; i < points.Length; i++)
        {
            var a = points[i % points.Length];
            var b = points[(i + 1) % points.Length];

            var r = IsLineSegmentIntersection(a.localPosition, b.localPosition, originPoint, comparePoint);

            if (r) count++;
        }

        return count % 2 == 1;
    }

    public bool IsLineSegmentIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
    {
        var crossA = Mathf.Sign(Vector3.Cross(d - c, a - c).y);
        var crossB = Mathf.Sign(Vector3.Cross(d - c, b - c).y);

        if (crossA == crossB) return false;

        var crossC = Mathf.Sign(Vector3.Cross(b - a, c - a).y);
        var crossD = Mathf.Sign(Vector3.Cross(b - a, d - a).y);

        if (crossC == crossD) return false;

        return true;
    }

    void OnDrawGizmos()
    {
        if (pointsArray == null) return;

        if (testComparePoint != null)
        {
            var comparePoint = transform.InverseTransformPoint(testComparePoint.transform.position);
            if (IsInRange(comparePoint))
            {
                Gizmos.color = Color.red;
            }
        }

        var cacheMatrix = Gizmos.matrix;
        Gizmos.matrix = transform.localToWorldMatrix;

        for (int i = 0; i < pointsArray.Length; i++)
        {
            var a = pointsArray[i];
            var b = pointsArray[(i + 1) % pointsArray.Length];

            if (a == null) continue;
            if (b == null) continue;

            var minA = a.localPosition;
            var minB = b.localPosition;

            var maxA = a.localPosition;
            var maxB = b.localPosition;

            minA.y = -height;
            minB.y = -height;

            maxA.y = height;
            maxB.y = height;

            Gizmos.DrawLine(minA, minB);
            Gizmos.DrawLine(maxA, maxB);

            Gizmos.DrawLine(minA, maxA);
            Gizmos.DrawLine(minB, maxB);
        }

        Gizmos.color = Color.clear;

        Gizmos.matrix = cacheMatrix;
    }
}
时间: 2024-10-13 21:03:31

一种3D空间的柱状多边形检测实现的相关文章

NeHe OpenGL教程 第五课:3D空间

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. 第五课:3D空间 3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的2D对象.我们给三角形增加一

第05课 OpenGL 3D空间

3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的2D对象.我们给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金字塔(四棱锥).给正方形增加左.右.上.下及背面生成一个立方体. 我们混合金字塔上的颜色,创建一个平滑着色的对象.给立方体的每一面则来个不同的颜色. int DrawGLScene(GLvoid) // 此过程中包括所有

OpenGl学习进程(9)在3D空间的绘制实例

    本节将演示在3D空间中绘制图形的几个简单实例:     (1)在3D空间内绘制圆锥体: #include <GL/glut.h> #include <math.h> #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") #define PI 3.1416 GLfloat xRot = 0; GLfloat yRot =

在3D空间中绘制四边形

在3D空间中绘制四边形 四边形 GL_QUADS OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形. 注意,在使用四边形时,必需记住一个重要规则:一个四边形的四个角必须位于同一个平面中(不存在弯曲的四边形).如图所示 四边形带 GL_QUAD_STRIP 该图元指定一个连接的四边形带.它们都保持相同方向的环绕.如图所示 通用多边形 GL_POLYGON 我们可以用它绘制任意数量的多边形.与四边形一样,多边形的所有顶点也必须位于同一平面中.如果想越过这个规则,可以采

jquery实现的竖向动态柱状条效果

jquery实现的竖向动态柱状条效果:很多数据统计效果中,柱状条方式的算是比较常见的一种,形象直观,下面就是一段能够实现此功能的代码实例,并且具有一定的动态效果,下面就对代码做一下分享,并详细介绍一下它的实现过程.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://

WinForm Chart控件使用记录(由于制作饼装,柱状,折线图)

由于公司的winform项目需要用到Chart图表,抽空研究了一下,特地发上来给大家做个参考,就目前而言用到的属性说明都做了注释: 主要用到Chart控件图表区域的属性有五个属性 Annotations 批注集合(我没怎么用到,但是配置的话会在图标区域出现一些可以备注的东西吧) ChartAreas 图表区属性:主要设置图标数据的背景,比如3D或者隐藏还是显示横纵轴交叉线,分块颜色显示等 Lengends 图表图例集合 主要设置图表边说明的一些东西,这次项目没什么用到,但是觉得这个基本没啥用,有

3D空间包围球(Bounding Sphere)的求法

引言 在3D碰撞检測中,为了加快碰撞检測的效率,降低不必要的碰撞检測,会使用基本几何体作为物体的包围体(Bounding Volume, BV)进行測试.基本包围体的碰撞检測相对来说廉价也easy的多,所以假设在基本包围体的碰撞检測中都没有通过的话,那么就没有必要进行更加复杂的碰撞检測了. 而对于不同性质,不同形状的模型,须要依据情况选择不同的包围体,一般来说,包围体分为例如以下的几种: Sphere, AABB, OBB, 8-DOP, Convex Hull这几种常见的. 接下来将向大家讲述

iOS 使用Charts框架 折线,柱状,K线,饼状,雷达全攻略

我是前言: 大约几个月前我在某平台写了一篇文章, 文中简单地介绍了Charts两种图表的样式的使用, 不过有种意犹未尽的感觉, 利用周末的空闲时间再次看了看, 有了新的收获, 今天发出来,分享给大家, 来稍加详细的再次走进Charts的世界. 完全纯代码. 经过测试: 1.1使用cocoa pods集成(只能在9.3之后运行), 有知道原因的请在下方评论 1.2 这篇文章的例子我是使用手动加入的framework进行测试的. 如果你不清楚如何加入三方框架请点击看看这篇文章http://www.j

3D空间中射线与三角形的交叉检测算法

引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如何进行Ray-Triangle的交叉检测. Ray-Triangle交叉检测算法 在Tomas Moller的MT97论文中,提出了一种新的算法.这种算法能够减少以前进行Ray-Triangle交叉检测所需要的内存消耗.在以前,进行Ray-Triangle交叉检测,主要是计算射线与三角形所构成的平面