示例#1
0
        public static bool IsTriangleInsectTriangle2(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p5, Vector2 p6, ref GeoInsectPointArrayInfo insect)
        {
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
            List <Vector2>          tri = new List <Vector2>();

            tri.Add(p1);
            tri.Add(p2);
            tri.Add(p3);
            bool inSect = false;

            for (int i = 0; i < 3; ++i)
            {
                int j = (i + 1) % 3;
                inSect = GeoSegmentUtils.IsSegmentInsectOrOverlapTriangle2(tri[i], tri[j], p4, p5, p6, ref tmp) || inSect;
            }
            if (inSect)
            {
                insect.mHitGlobalPoint.mPointArray.AddRange(tmp.mHitGlobalPoint.mPointArray);
            }
            insect.mIsIntersect = insect.mHitGlobalPoint.mPointArray.Count > 0;
            if (insect.mIsIntersect)
            {
                insect.UniquePoint();
            }
            return(insect.mIsIntersect);
        }
示例#2
0
        public static bool IsTriangleInsectPlaneCircle2(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 center, float r, GeoPlane plane, ref GeoInsectPointArrayInfo insect)
        {
            Vector3 p11 = plane.TransformToLocal(p1);
            Vector3 p21 = plane.TransformToLocal(p2);
            Vector3 p31 = plane.TransformToLocal(p3);
            Vector3 c1  = plane.TransformToLocal(center);
            Vector2 p12 = new Vector2(p11.x, p11.z);
            Vector2 p22 = new Vector2(p21.x, p21.z);
            Vector2 p32 = new Vector2(p31.x, p31.z);
            Vector2 c2  = new Vector2(c1.x, c1.z);
            GeoInsectPointArrayInfo temp = new GeoInsectPointArrayInfo();
            bool isInsect1 = IsTriangleInsectCircle2(p12, p22, p32, c2, r, ref temp);

            if (isInsect1)
            {
                insect.mIsIntersect = true;
                foreach (Vector3 v in temp.mHitGlobalPoint.mPointArray)
                {
                    Vector3 vv = new Vector3(v.x, 0.0f, v.y);
                    vv = plane.TransformToGlobal(vv);
                    insect.mHitGlobalPoint.mPointArray.Add(vv);
                }
                return(true);
            }
            return(false);
        }
示例#3
0
        public bool IsIntersect(ref GeoRay2 dist, ref GeoInsectPointArrayInfo insect)
        {
            bool isInsect = GeoRayUtils.IsRayInsectAABB2(dist.mOrigin, dist.mDirection, mAABB2.mMin, mAABB2.mMax, ref insect);

            if (isInsect)
            {
                insect.mHitObject2 = this;
                insect.mLength     = (GeoUtils.ToVector2(insect.mHitGlobalPoint.mPointArray[0]) - dist.mOrigin).magnitude;
            }
            return(isInsect);
        }
示例#4
0
        public bool IsIntersect(ref GeoRay3 dist, ref GeoInsectPointArrayInfo insect)
        {
            GeoInsectPointInfo info = new GeoInsectPointInfo();
            bool isInsect           = GeoRayUtils.IsRayInsectTriangle3(dist.mOrigin, dist.mDirection, mP1, mP2, mP3, ref info);

            if (isInsect)
            {
                insect.mHitObject2 = this;
                insect.mHitGlobalPoint.mPointArray.Add(info.mHitGlobalPoint);
                insect.mLength = (info.mHitGlobalPoint - dist.mOrigin).magnitude;
            }
            return(isInsect);
        }
示例#5
0
        public bool IsIntersect(ref GeoRay2 dist, ref GeoInsectPointArrayInfo insect)
        {
            GeoInsectPointInfo info = new GeoInsectPointInfo();
            bool isInsect           = GeoRayUtils.IsRayInsectSegment2(dist.mOrigin, dist.mDirection, mSeg.mP1, mSeg.mP2, ref info);

            insect.mIsIntersect = isInsect;
            if (isInsect)
            {
                insect.mHitObject2 = this;
                insect.mHitGlobalPoint.mPointArray.Add(info.mHitGlobalPoint);
                insect.mLength = (GeoUtils.ToVector2(info.mHitGlobalPoint) - dist.mOrigin).magnitude;
            }
            return(isInsect);
        }
示例#6
0
        public static bool IsPlaneInsectCircle(Vector3 normal, float d, Vector3 center, float r, GeoPlane plane, ref GeoInsectPointArrayInfo insect)
        {
            float tmp = Mathf.Abs(Vector3.Dot(plane.mNormal.normalized, normal.normalized));

            if (1 - tmp < 1e-5f)
            {
                return(false); // 平行 或 共面
            }
            GeoInsectPointArrayInfo tmp1 = new GeoInsectPointArrayInfo();
            bool inSect = IsPlaneInsectPlane(normal, d, plane.mNormal, plane.mD, ref tmp1);

            if (inSect)
            {
                Vector3 line1 = tmp1.mHitGlobalPoint.mPointArray[0] + tmp1.mHitGlobalPoint.mPointArray[1];
                GeoLineUtils.IsLineInsectCirclePlane2(tmp1.mHitGlobalPoint.mPointArray[0], line1, center, r, plane, ref insect);
            }
            return(insect.mIsIntersect);
        }
示例#7
0
        public static bool IsTriangleInsectCircle3(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 center, float r, GeoPlane plane, ref GeoInsectPointArrayInfo insect)
        {
            bool isInsect = GeoPlaneUtils.IsPlaneInsectTriangle(plane.mNormal, plane.mD, p1, p2, p3, ref insect);

            if (isInsect)
            {
                if (insect.mHitGlobalPoint.mPointArray.Count == 3) // 共面, 转化成 2d
                {
                    insect.Clear();
                    return(IsTriangleInsectPlaneCircle2(p1, p2, p3, center, r, plane, ref insect));
                }
                else if (insect.mHitGlobalPoint.mPointArray.Count == 1)
                {
                    if (GeoCircleUtils.IsInSphere(center, r, insect.mHitGlobalPoint.mPointArray[0]))
                    {
                        return(true);
                    }
                }
                else if (insect.mHitGlobalPoint.mPointArray.Count == 2)
                {
                    Vector3 seg1 = plane.TransformToLocal(insect.mHitGlobalPoint.mPointArray[0]);
                    Vector3 seg2 = plane.TransformToLocal(insect.mHitGlobalPoint.mPointArray[1]);
                    Vector3 c1   = plane.TransformToLocal(center);
                    Vector2 p12  = new Vector2(seg1.x, seg1.z);
                    Vector2 p22  = new Vector2(seg2.x, seg2.z);
                    Vector2 c2   = new Vector2(c1.x, c1.z);
                    insect.Clear();
                    GeoInsectPointArrayInfo temp = new GeoInsectPointArrayInfo();
                    if (GeoSegmentUtils.IsSegmentInsectCircle2(p12, p22, c2, r, ref temp))
                    {
                        insect.mIsIntersect = true;
                        foreach (Vector3 v in temp.mHitGlobalPoint.mPointArray)
                        {
                            Vector3 vv = new Vector3(v.x, 0.0f, v.y);
                            vv = plane.TransformToGlobal(vv);
                            insect.mHitGlobalPoint.mPointArray.Add(vv);
                        }
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#8
0
        public static bool IsPlaneInsectAABB2(Vector3 normal, float d, Vector3 min, Vector3 max, GeoPlane plane, ref GeoInsectPointArrayInfo insect)
        {
            float dot = Vector3.Dot(normal, plane.mNormal);

            if (1 - Mathf.Abs(dot) < 1e-5f)
            {
                return(false);
            }
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
            bool isInsect = GeoPlaneUtils.IsPlaneInsectPlane(normal, d, plane.mNormal, plane.mD, ref tmp);

            if (isInsect)
            {
                Vector3 l1 = tmp.mHitGlobalPoint.mPointArray[0];
                Vector3 l2 = l1 + tmp.mHitGlobalPoint.mPointArray[1];
                isInsect = GeoLineUtils.IsLineInsectAABBPlane2(l1, l2, min, max, plane, ref insect);
            }
            return(insect.mIsIntersect);
        }
示例#9
0
        public bool IsIntersect(ref GeoRay2 dist, ref GeoInsectPointArrayInfo insect)
        {
            bool isInsect = GeoRayUtils.IsRayInsectTriangle2(dist.mOrigin, dist.mDirection, mP1, mP2, mP3, ref insect);

            if (isInsect)
            {
                insect.mHitObject2 = this;
                float min = 1e5f;
                foreach (Vector3 v in insect.mHitGlobalPoint.mPointArray)
                {
                    float len = (GeoUtils.ToVector2(v) - dist.mOrigin).magnitude;
                    if (len < min)
                    {
                        min = len;
                    }
                }
                insect.mLength = min;
            }
            return(isInsect);
        }
示例#10
0
        public static bool IsTriangleInsectCircle2(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 center, float r, ref GeoInsectPointArrayInfo insect)
        {
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();

            if (GeoSegmentUtils.IsSegmentInsectCircle2(p1, p2, center, r, ref tmp))
            {
                insect.mHitGlobalPoint.mPointArray.AddRange(tmp.mHitGlobalPoint.mPointArray);
            }
            tmp.Clear();
            if (GeoSegmentUtils.IsSegmentInsectCircle2(p3, p2, center, r, ref tmp))
            {
                insect.mHitGlobalPoint.mPointArray.AddRange(tmp.mHitGlobalPoint.mPointArray);
            }
            tmp.Clear();
            if (GeoSegmentUtils.IsSegmentInsectCircle2(p1, p3, center, r, ref tmp))
            {
                insect.mHitGlobalPoint.mPointArray.AddRange(tmp.mHitGlobalPoint.mPointArray);
            }
            tmp.Clear();
            return(false);
        }
示例#11
0
        // 两三角面 共面的情况
        private static bool IsTriangleInsectTrianglePlane2(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Vector3 p5, Vector3 p6, ref GeoInsectPointArrayInfo insect)
        {
            GeoPlane plane = GeoPlaneUtils.CreateFromTriangle(p1, p2, p3);
            Vector2  p11, p21, p31, p41, p51, p61;

            GeoPlaneUtils.PlaneTransformLocalTriangle(p1, p2, p3, plane, out p11, out p21, out p31);
            GeoPlaneUtils.PlaneTransformLocalTriangle(p4, p5, p6, plane, out p41, out p51, out p61);
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
            bool isInsect = IsTriangleInsectTriangle2(p11, p21, p31, p41, p51, p61, ref tmp);

            if (isInsect)
            {
                foreach (Vector3 v in tmp.mHitGlobalPoint.mPointArray)
                {
                    Vector3 vt = new Vector3(v.x, 0.0f, v.z);
                    vt = plane.TransformToGlobal(vt);
                    insect.mHitGlobalPoint.mPointArray.Add(vt);
                }
                insect.mIsIntersect = insect.mHitGlobalPoint.mPointArray.Count > 0;
            }
            return(insect.mIsIntersect);
        }
示例#12
0
        public static bool IsCircleInsectCircle3(Vector3 center1, float r1, GeoPlane plane1, Vector3 center2, float r2, GeoPlane plane2, ref GeoInsectPointArrayInfo insect)
        {
            float dot = Mathf.Abs(Vector3.Dot(plane1.mNormal, plane2.mNormal));

            if (1 - dot < 1e-5f)
            {
                if (GeoPlaneUtils.IsPointOnPlane(plane2.mNormal, plane2.mD, center1)) // 共面
                {
                    return(IsCircleInsectCirclePlane2(center1, r1, center2, r2, plane2, ref insect));
                }
                return(false);
            }
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
            bool isInsect = GeoPlaneUtils.IsPlaneInsectCircle(plane1.mNormal, plane1.mD, center2, r2, plane2, ref tmp);

            if (isInsect)
            {
                Vector3 lin1 = tmp.mHitGlobalPoint.mPointArray[0];
                Vector3 lin2 = lin1 + tmp.mHitGlobalPoint.mPointArray[1];
                GeoLineUtils.IsLineInsectCirclePlane2(lin1, lin2, center1, r1, plane1, ref insect);
            }
            return(insect.mIsIntersect);
        }
示例#13
0
        public static bool IsAABBInsectCircle3(Vector3 min, Vector3 max, GeoPlane plane1, Vector3 center, float r, GeoPlane plane2, ref GeoInsectPointArrayInfo insect)
        {
            float dot = Vector3.Dot(plane1.mNormal, plane2.mNormal);

            if (1 - Mathf.Abs(dot) < 1e-5f)
            {
                if (GeoPlaneUtils.IsPointOnPlane(plane2.mNormal, plane2.mD, min))
                {
                    return(IsAABBInsectCirclePlane2(min, max, center, r, plane1, ref insect)); // should use plane1
                }
                return(false);
            }
            GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
            bool isInsect = GeoPlaneUtils.IsPlaneInsectCircle(plane1.mNormal, plane1.mD, center, r, plane2, ref tmp);

            if (isInsect)
            {
                if (tmp.mHitGlobalPoint.mPointArray.Count == 1)
                {
                    Vector3 line1 = tmp.mHitGlobalPoint.mPointArray[0];
                    if (GeoAABBUtils.IsPointInAABB2Plane(min, max, plane1, ref line1))
                    {
                        insect.mIsIntersect = true;
                        insect.mHitGlobalPoint.mPointArray.Add(line1);
                        return(true);
                    }
                }
                else
                {
                    Vector3 seg1 = tmp.mHitGlobalPoint.mPointArray[0];
                    Vector3 seg2 = seg1 + tmp.mHitGlobalPoint.mPointArray[1];
                    return(GeoSegmentUtils.IsSegmentInsectAABB2Plane(seg1, seg2, min, max, plane1, ref insect));
                }
            }
            return(false);
        }
示例#14
0
        public static bool IsTriangleInsectSphere(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 center, float r, ref GeoInsectPointArrayInfo insect)
        {
            GeoPlane plane   = GeoPlaneUtils.CreateFromTriangle(p1, p2, p3);
            bool     isInsec = GeoPlaneUtils.IsPlaneInsectSphere(plane, center, r, ref insect);

            if (isInsec)
            {
                Vector3 c1  = insect.mHitGlobalPoint.mPointArray[0];
                float   rad = insect.mHitGlobalPoint.mPointArray[0][0];
                insect.Clear();
                return(IsTriangleInsectPlaneCircle2(p1, p2, p3, c1, rad, plane, ref insect));
            }
            return(false);
        }
示例#15
0
        public static bool IsPlaneInsectTriangle(Vector3 normal, float d, Vector3 p1, Vector3 p2, Vector3 p3, ref GeoInsectPointArrayInfo insect)
        {
            // 414
            List <Vector3> tri = new List <Vector3>();

            tri.Add(p1);
            tri.Add(p2);
            tri.Add(p3);
            List <Vector3> pPos = new List <Vector3>();
            List <Vector3> pOn  = new List <Vector3>();

            foreach (Vector3 p in tri)
            {
                bool p1P = IsPointInPositiveHalf(normal, d, p);
                if (p1P)
                {
                    pPos.Add(p);
                }
                else
                {
                    p1P = IsPointOnPlane(normal, d, p);
                    if (p1P)
                    {
                        pOn.Add(p);
                    }
                }
            }
            if (pPos.Count == 3 && pOn.Count == 0) // 三点都在 一侧
            {
                return(false);
            }
            if (pPos.Count == 2 && pOn.Count == 1) // 一点在上,另两点同侧
            {
                insect.mIsIntersect = true;
                insect.mHitGlobalPoint.mPointArray.Add(pOn[0]);
                return(true);
            }
            if (pPos.Count == 1 && pOn.Count == 2)
            {
                insect.mIsIntersect = true;
                insect.mHitGlobalPoint.mPointArray.Add(pOn[0]);
                insect.mHitGlobalPoint.mPointArray.Add(pOn[1]);
                return(true);
            }
            if (pPos.Count == 0 && pOn.Count == 3) // 共面
            {
                insect.mIsIntersect = true;
                insect.mHitGlobalPoint.mPointArray.Add(pOn[0]);
                insect.mHitGlobalPoint.mPointArray.Add(pOn[1]);
                insect.mHitGlobalPoint.mPointArray.Add(pOn[2]);
                return(true);
            }
            insect.mIsIntersect = true;
            GeoInsectPointInfo temp = new GeoInsectPointInfo();

            for (int i = 0; i < 3; ++i)
            {
                if (IsPlaneInsectSegment(normal, d, tri[i], tri[(i + 1) % 3], ref temp))
                {
                    insect.mHitGlobalPoint.mPointArray.Add(temp.mHitGlobalPoint);
                }
            }
            return(true);
        }
示例#16
0
        public static bool IsLineInsectTriangle2(Vector2 line1, Vector2 line2, Vector2 p1, Vector2 p2, Vector2 p3, ref GeoInsectPointArrayInfo insect)
        {
            // 转化为 线 与 线段 相交
            List <Vector2> tri = new List <Vector2>();

            tri.Add(p1);
            tri.Add(p2);
            tri.Add(p3);
            List <Vector3>     ins  = new List <Vector3>();
            GeoInsectPointInfo info = new GeoInsectPointInfo();

            for (int i = 0; i < 3; ++i)
            {
                bool isSeg = IsLineInsectSegment2(line1, line2, tri[i], tri[(i + 1) % 3], ref info);
                if (isSeg)
                {
                    ins.Add(info.mHitGlobalPoint);
                }
            }
            if (ins.Count > 0)
            {
                insect.mIsIntersect = true;
                insect.mHitGlobalPoint.mPointArray = ins;
            }
            return(insect.mIsIntersect);
        }
示例#17
0
        public static bool IsPlaneInsectPlane(Vector3 normal1, float d1, Vector3 normal2, float d2, ref GeoInsectPointArrayInfo insect)
        {
            // 410 所有的法向量必须先单位化
            Vector3 lineDirection = Vector3.Cross(normal1, normal2);

            if (lineDirection.magnitude < 1e-5f) // 平行
            {
                return(false);
            }
            float   n1n2 = Vector3.Dot(normal1, normal2);
            float   m    = n1n2 * n1n2 - 1;
            float   a    = (-d2 * n1n2 + d1) / m;
            float   b    = (-d1 * n1n2 + d2) / m;
            Vector3 p    = a * normal1 + b * normal2;

            insect.mIsIntersect = true;
            insect.mHitGlobalPoint.mPointArray.Add(p);             // 直线 上一点
            insect.mHitGlobalPoint.mPointArray.Add(lineDirection); // 直线 方向
            return(true);
        }
示例#18
0
        /*
         *   矩形:R(t1, t2) = C + t1 * e1 + t2 * e2, -w < t1 < w, -h < t2 < h . C 为 矩形 中心点
         *
         *  作者:张建龙
         *  链接:https://www.zhihu.com/question/31763307/answer/53259121
         *  来源:知乎
         *  轴对齐的矩形对线段的裁剪算法,大致有五种算法,可以解决轴对齐的矩形对线段的裁剪算法。
         * 最早由Danny Cohen&Ivan Sutherland提出的一种算法,称为Cohen-Sutherlad裁剪算法(简称CS算法),
         * 该算法把平面分成9个区域,根据点的位置确定与矩形的相交边。后来,Cyrus&Beck[1](1978)提出了Cyrus-Beck裁剪算法(简称CB算法),
         * 线段用参数方程来表示,计算与矩形的每条边所在的直线的交点,但是该算法的效率相对较低。
         * Liang&Barsky[2](1984)尝试对CS算法进行改进,提出了该算法的一种变种,称为Liang-Barsky裁剪算法(简称为LB算法),
         * Liang和Barsky[3](1992)进一步对LB算法进行了改进。Sobkow&Pospisil&Yang[4](1987)描述了另外一种线段的裁剪算法,称为快速裁剪算法(简称为SPY算法)。
         * Nicholl,Lee&Nicholl[5]对前面四种线段裁剪算法进行了较为深入地分析和比较,并且描述了一种更加高效的算法,称为Nicholl-Lee-Nicholl算法(简称为NLN算法)。
         * 对比五种算法的性能,它们并不是在数量级上的差别,只是算法中运算个数的差别,比如NLN算法拥有最少的除法次数。
         * CS、LB和SPY在不同机器、不同的数据集上,会显示出不同的算法性能。在算法实现上,NLN和SPY算法较为复杂,CS和LB相对简单。
         * 如果不会特别苛求算法的性能,建议选择CS或者LB算法
         *
         *
         * 很多实现并没有 垂直和水平的处理,因为默认相交的几何体都是在
         * 第一象限
         */
        public static bool IsLineInsectAABB2(Vector2 line1, Vector2 line2, Vector2 min, Vector2 max, ref GeoInsectPointArrayInfo insect)
        {
            // 转化为 线 与 线段 相交
            // 对角线 快速 判断
            Vector2 dir = line2 - line1;

            if (dir[0] == 0.0f)                               // 垂直
            {
                if (line1[0] >= min[0] && line1[0] <= max[0]) // 相交
                {
                    insect.mIsIntersect = true;
                    insect.mHitGlobalPoint.mPointArray.Add(new Vector3(line1[0], min[1], 0.0f));
                    insect.mHitGlobalPoint.mPointArray.Add(new Vector3(line1[0], max[1], 0.0f));
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            if (dir[1] == 0.0f)                               // 平行
            {
                if (line1[1] >= min[1] && line1[1] <= max[1]) // 相交
                {
                    insect.mIsIntersect = true;
                    insect.mHitGlobalPoint.mPointArray.Add(new Vector3(min[0], line1[1], 0.0f));
                    insect.mHitGlobalPoint.mPointArray.Add(new Vector3(max[0], line1[1], 0.0f));
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            float invx = 1.0f / dir[0];
            float t1;
            float t2;
            float dnear;
            float dfar;

            if (invx > 0)
            {
                t1 = (min[0] - line1[0]) * invx;
                t2 = (max[0] - line1[0]) * invx;
            }
            else
            {
                t2 = (min[0] - line1[0]) * invx;
                t1 = (max[0] - line1[0]) * invx;
            }
            dnear = t1;
            dfar  = t2;
            if (dnear > dfar || dfar < 0.0f)
            {
                return(false);
            }
            float invy = 1.0f / dir[1];

            if (invy > 0)
            {
                t1 = (min[1] - line1[1]) * invy;
                t2 = (max[1] - line1[1]) * invy;
            }
            else
            {
                t2 = (min[1] - line1[1]) * invy;
                t1 = (max[1] - line1[1]) * invy;
            }
            if (t1 > dnear)
            {
                dnear = t1;
            }
            if (t2 < dfar)
            {
                dfar = t2;
            }
            dnear = t1;
            dfar  = t2;
            if (dnear > dfar || dfar < 0.0f)
            {
                return(false);
            }
            insect.mIsIntersect = true;
            insect.mHitGlobalPoint.mPointArray.Add(line1 + dnear * dir);
            if (dnear != dfar)
            {
                insect.mHitGlobalPoint.mPointArray.Add(line1 + dfar * dir);
            }
            return(true);
        }
示例#19
0
        public static bool IsLineInsectAABBPlane2(Vector3 line1, Vector3 line2, Vector3 min, Vector3 max, GeoPlane plane, ref GeoInsectPointArrayInfo insect)
        {
            Vector3 min1     = plane.TransformToLocal(min);
            Vector3 max1     = plane.TransformToLocal(max);
            Vector3 l1       = plane.TransformToLocal(line1);
            Vector3 l2       = plane.TransformToLocal(line2);
            bool    isInsect = IsLineInsectAABB2(new Vector2(l1.x, l1.z), new Vector2(l2.x, l2.z), new Vector2(min1.x, min1.z), new Vector2(max1.x, max1.z), ref insect);

            if (isInsect)
            {
                insect.mHitGlobalPoint.mPointArray = GeoPlaneUtils.PlaneTransformGlobal(insect.mHitGlobalPoint.mPointArray, plane);
            }
            return(isInsect);
        }
示例#20
0
        public bool GetIntersection(GeoRay2 ray, ref GeoInsectPointArrayInfo intersection, bool occlusion)
        {
            if (mFlatTreeList.Count == 0)
            {
                return(false);
            }
            intersection.mIsIntersect = false;
            intersection.mLength      = 999999999.0f;
            intersection.mHitObject2  = null;
            int closer, other;

            BVHTraversal[] todo = new BVHTraversal[64];
            todo[0] = new BVHTraversal();
            int stackptr = 0;

            todo[stackptr].mIndex  = 0;
            todo[stackptr].mLength = -9999999.0f;
            while (stackptr >= 0)
            {
                int   ni   = todo[stackptr].mIndex;
                float near = todo[stackptr].mLength;
                stackptr--;
                BVHFlatNode2 node = mFlatTreeList[ni];
                // 对叶节点做相交测试
                if (node.mRightOffset == 0)
                {
                    bool hit = false;
                    for (int o = 0; o < node.mLeafCount; ++o)
                    {
                        GeoInsectPointArrayInfo current = new GeoInsectPointArrayInfo();
                        BVHObject2 obj = mBuildPrims[(int)node.mStartIndex + o];
                        hit = obj.IsIntersect(ref ray, ref current);
                        if (hit)
                        {
                            if (occlusion)
                            {
                                intersection = current;
                                return(true);
                            }
                            if (current.mLength < intersection.mLength)
                            {
                                intersection = current;
                            }
                        }
                    }
                }
                else
                {
                    closer = ni + 1;
                    other  = ni + (int)node.mRightOffset;
                    // 对父结点做测试
                    GeoInsectPointArrayInfo in1 = new GeoInsectPointArrayInfo();
                    GeoInsectPointArrayInfo in2 = new GeoInsectPointArrayInfo();
                    bool hitc0 = GeoRayUtils.IsRayInsectAABB2(ray.mOrigin, ray.mDirection, mFlatTreeList[closer].mBox.mMin, mFlatTreeList[closer].mBox.mMax, ref in1);
                    bool hitc1 = GeoRayUtils.IsRayInsectAABB2(ray.mOrigin, ray.mDirection, mFlatTreeList[other].mBox.mMin, mFlatTreeList[other].mBox.mMax, ref in2);

                    if (hitc0 && hitc1)
                    {
                        float l0 = (GeoUtils.ToVector2(in1.mHitGlobalPoint[0]) - ray.mOrigin).magnitude;
                        float l2 = (GeoUtils.ToVector2(in2.mHitGlobalPoint[0]) - ray.mOrigin).magnitude;
                        if (l2 < l0)
                        {
                            float temp = l0;
                            l0 = l2;
                            l2 = temp;
                            int itemp = closer;
                            closer = other;
                            other  = itemp;
                        }
                        todo[++stackptr] = new BVHTraversal(other, l2);
                        todo[++stackptr] = new BVHTraversal(closer, l0);
                    }
                    else if (hitc0)
                    {
                        float l0 = (GeoUtils.ToVector2(in1.mHitGlobalPoint[0]) - ray.mOrigin).magnitude;
                        todo[++stackptr] = new BVHTraversal(closer, l0);
                    }
                    else if (hitc1)
                    {
                        float l2 = (GeoUtils.ToVector2(in2.mHitGlobalPoint[0]) - ray.mOrigin).magnitude;
                        todo[++stackptr] = new BVHTraversal(other, l2);
                    }
                }
            }
            if (intersection.mHitObject2 != null)
            {
                intersection.mHitGlobalPoint.Clear();
                intersection.mHitGlobalPoint.Add(ray.mOrigin + ray.mDirection * intersection.mLength);
            }
            return(intersection.mHitObject2 != null);
        }
示例#21
0
        public static bool IsLineInsectAABB3(Vector3 line1, Vector3 line2, Vector3 min, Vector3 max, ref GeoInsectPointArrayInfo insect)
        {
            // 转化为 线 与 线段 相交
            // 对角线 快速 判断
            Vector3 dir = line2 - line1;

            if (dir[0] == 0.0f)                               // 平行 YOZ
            {
                if (line1[0] >= min[0] && line1[0] <= max[0]) // 相交 转换到 2d
                {
                    // (line1[0], min[1], min[2]) (line1[0], max[1], max[2]);
                    Vector2 line11 = new Vector2(line1[1], line1[2]);
                    Vector2 line21 = new Vector2(line2[1], line2[2]);
                    Vector2 min1   = new Vector2(min[1], min[2]);
                    Vector2 max1   = new Vector2(max[1], max[2]);
                    GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
                    bool isInsect = IsLineInsectAABB2(line11, line21, min1, max1, ref tmp);
                    if (isInsect)
                    {
                        insect.mIsIntersect = true;
                        foreach (Vector3 v in tmp.mHitGlobalPoint.mPointArray)
                        {
                            insect.mHitGlobalPoint.mPointArray.Add(new Vector3(line1[0], v[0], v[1]));
                        }
                    }
                    return(isInsect);
                }
            }
            if (dir[1] == 0.0f)                               // 平行
            {
                if (line1[1] >= min[1] && line1[1] <= max[1]) // 相交 转换到 2d
                {
                    // (min[0], line1[1], min[2]) (max[0], line1[1], max[2]);
                    Vector2 line11 = new Vector2(line1[0], line1[2]);
                    Vector2 line21 = new Vector2(line2[0], line2[2]);
                    Vector2 min1   = new Vector2(min[0], min[2]);
                    Vector2 max1   = new Vector2(max[0], max[2]);
                    GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
                    bool isInsect = IsLineInsectAABB2(line11, line21, min1, max1, ref tmp);
                    if (isInsect)
                    {
                        insect.mIsIntersect = true;
                        foreach (Vector3 v in tmp.mHitGlobalPoint.mPointArray)
                        {
                            insect.mHitGlobalPoint.mPointArray.Add(new Vector3(v[0], line1[1], v[1]));
                        }
                    }
                    return(isInsect);
                }
            }
            if (dir[2] == 0.0f)                               // 平行
            {
                if (line1[2] >= min[2] && line1[2] <= max[2]) // 相交 转换到 2d
                {
                    // (min[0], min[1], line1[2]) (max[0], max[1], line1[2]);
                    Vector2 line11 = new Vector2(line1[0], line1[1]);
                    Vector2 line21 = new Vector2(line2[0], line2[1]);
                    Vector2 min1   = new Vector2(min[0], min[1]);
                    Vector2 max1   = new Vector2(max[0], max[1]);
                    GeoInsectPointArrayInfo tmp = new GeoInsectPointArrayInfo();
                    bool isInsect = IsLineInsectAABB2(line11, line21, min1, max1, ref tmp);
                    if (isInsect)
                    {
                        insect.mIsIntersect = true;
                        foreach (Vector3 v in tmp.mHitGlobalPoint.mPointArray)
                        {
                            insect.mHitGlobalPoint.mPointArray.Add(new Vector3(v[0], v[1], line1[2]));
                        }
                    }
                    return(isInsect);
                }
            }
            float invx = 1.0f / dir[0];
            float t1;
            float t2;
            float dnear;
            float dfar;

            if (invx > 0)
            {
                t1 = (min[0] - line1[0]) * invx;
                t2 = (max[0] - line1[0]) * invx;
            }
            else
            {
                t2 = (min[0] - line1[0]) * invx;
                t1 = (max[0] - line1[0]) * invx;
            }
            dnear = t1;
            dfar  = t2;
            if (dnear > dfar || dfar < 0.0f)
            {
                return(false);
            }
            float invy = 1.0f / dir[1];

            if (invy > 0)
            {
                t1 = (min[1] - line1[1]) * invy;
                t2 = (max[1] - line1[1]) * invy;
            }
            else
            {
                t2 = (min[1] - line1[1]) * invy;
                t1 = (max[1] - line1[1]) * invy;
            }
            if (t1 > dnear)
            {
                dnear = t1;
            }
            if (t2 < dfar)
            {
                dfar = t2;
            }
            dnear = t1;
            dfar  = t2;
            if (dnear > dfar || dfar < 0.0f)
            {
                return(false);
            }
            float invz = 1.0f / dir[2];

            if (invz > 0)
            {
                t1 = (min[2] - line1[2]) * invz;
                t2 = (max[2] - line1[2]) * invz;
            }
            else
            {
                t2 = (min[2] - line1[2]) * invz;
                t1 = (max[2] - line1[2]) * invz;
            }
            if (t1 > dnear)
            {
                dnear = t1;
            }
            if (t2 < dfar)
            {
                dfar = t2;
            }
            dnear = t1;
            dfar  = t2;
            if (dnear > dfar || dfar < 0.0f)
            {
                return(false);
            }
            insect.mIsIntersect = true;
            insect.mHitGlobalPoint.mPointArray.Add(line1 + dnear * dir);
            if (dnear != dfar)
            {
                insect.mHitGlobalPoint.mPointArray.Add(line1 + dfar * dir);
            }
            return(true);
        }
示例#22
0
 // 三角面
 public static bool IsTriangleInsectSegment2(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 seg1, Vector2 seg2, ref GeoInsectPointArrayInfo insect)
 {
     return(GeoSegmentUtils.IsSegmentInsectTriangle2(seg1, seg2, p1, p2, p3, ref insect));
 }
示例#23
0
        public static bool IsLineInsectSphere(Vector3 line1, Vector3 line2, Vector3 center, float r, ref GeoInsectPointArrayInfo insect)
        {
            // 389 公式存在问题, 按照代码来
            Vector3 direction = line2 - line1;
            float   a         = Vector3.Dot(direction, direction);
            Vector3 c1        = line1 - center;
            float   b         = 2 * Vector3.Dot(direction, c1);
            float   c         = Vector3.Dot(c1, c1) - r * r;
            float   discrm    = b * b - 4 * a * c;

            if (discrm < 0)
            {
                return(false);
            }
            discrm = Mathf.Sqrt(discrm);
            float t1 = -b + discrm;
            float t2 = -b - discrm;

            insect.mIsIntersect = true;
            if (discrm == 0)
            {
                insect.mHitGlobalPoint.mPointArray.Add(line1 + t1 * direction);
            }
            else
            {
                insect.mHitGlobalPoint.mPointArray.Add(line1 + t1 * direction);
                insect.mHitGlobalPoint.mPointArray.Add(line1 + t2 * direction);
            }
            return(true);
        }
示例#24
0
        public static bool IsLineInsectCircle2(Vector2 line1, Vector2 line2, Vector2 center, float r, ref GeoInsectPointArrayInfo insect)
        {
            // 389 公式存在问题, 按照代码来
            Vector2 direction = line2 - line1;
            float   a         = Vector2.Dot(direction, direction);
            Vector2 c1        = line1 - center;
            float   b         = 2 * Vector2.Dot(direction, c1);
            float   c         = Vector2.Dot(c1, c1) - r * r;
            float   discrm    = b * b - 4 * a * c;

            if (discrm < 0)
            {
                return(false);
            }
            discrm = Mathf.Sqrt(discrm);
            float t1 = -b + discrm;
            float t2 = -b - discrm;

            insect.mIsIntersect = true;
            if (discrm == 0)
            {
                Vector2 temp = line1 + t1 * direction;
                insect.mHitGlobalPoint.mPointArray.Add(new Vector3(temp.x, temp.y, 0.0f));
            }
            else
            {
                Vector2 temp = line1 + t1 * direction;
                insect.mHitGlobalPoint.mPointArray.Add(new Vector3(temp.x, temp.y, 0.0f));
                temp = line1 + t2 * direction;
                insect.mHitGlobalPoint.mPointArray.Add(new Vector3(temp.x, temp.y, 0.0f));
            }
            return(true);
        }
示例#25
0
 public static bool IsTriangleInsectAABB3(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 min, Vector2 max, ref GeoInsectPointArrayInfo insect)
 {
     return(GeoAABBUtils.IsAABBInsectTriangle3(min, max, p1, p2, p3, ref insect));
 }
示例#26
0
 public static bool IsPlaneInsectAABB3(Vector3 normal, float d, Vector3 min, Vector3 max, ref GeoInsectPointArrayInfo insect)
 {
     return(false);
 }
示例#27
0
        public static bool IsTriangleInsectTriangle3(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Vector3 p5, Vector3 p6, ref GeoInsectPointArrayInfo insect)
        {
            /*
             * // 外面进行 剔除 处理
             * Vector3 min1 = Vector3.Min(p1, p2);
             * min1 = Vector3.Min(min1, p3);
             * Vector3 max1 = Vector3.Max(p1, p2);
             * max1 = Vector3.Max(max1, p3);
             * Vector3 min2 = Vector3.Min(p4, p5);
             * min2 = Vector3.Min(min2, p6);
             * Vector3 max2 = Vector3.Max(p4, p5);
             * max2 = Vector3.Max(max2, p6);
             * if (!GeoAABBUtils.IsAABBInsectAABB3(min1, max1, min2, max2))
             * {
             *  return false;
             * }
             */
            // 417
            Vector3 p12     = p2 - p1;
            Vector3 p13     = p3 - p1;
            Vector3 normal1 = Vector3.Cross(p12, p13);
            Vector3 p45     = p5 - p4;
            Vector3 p46     = p6 - p4;
            Vector3 normal2 = Vector3.Cross(p45, p46);

            normal1.Normalize();
            normal2.Normalize();
            float dot = Vector3.Dot(normal1, normal2);

            if (1 - Mathf.Abs(dot) < 1e-5f) // 共面
            {
                return(IsTriangleInsectTrianglePlane2(p1, p2, p3, p4, p5, p6, ref insect));
            }
            float d1 = -Vector3.Dot(normal1, p1);
            float d2 = -Vector3.Dot(normal2, p4);
            GeoInsectPointArrayInfo temp1 = new GeoInsectPointArrayInfo();

            if (GeoPlaneUtils.IsPlaneInsectTriangle(normal1, d1, p4, p5, p6, ref temp1))
            {
                GeoInsectPointArrayInfo temp2 = new GeoInsectPointArrayInfo();
                if (GeoPlaneUtils.IsPlaneInsectTriangle(normal2, d2, p1, p2, p3, ref temp2))
                {
                    int count1 = temp1.mHitGlobalPoint.mPointArray.Count;
                    int count2 = temp2.mHitGlobalPoint.mPointArray.Count;
                    if (count1 == 1 && count2 == 1)
                    {
                        bool isEq = temp1.mHitGlobalPoint.mPointArray[0] == temp2.mHitGlobalPoint.mPointArray[0];
                        if (isEq)
                        {
                            insect.mIsIntersect = true;
                            insect.mHitGlobalPoint.mPointArray.Add(temp1.mHitGlobalPoint.mPointArray[0]);
                            return(true);
                        }
                    }
                    else if (count1 == 2 && count2 == 2)
                    {
                        Vector3 s1 = temp1.mHitGlobalPoint.mPointArray[0];
                        Vector3 s2 = temp1.mHitGlobalPoint.mPointArray[1];
                        Vector3 s3 = temp2.mHitGlobalPoint.mPointArray[0];
                        Vector3 s4 = temp2.mHitGlobalPoint.mPointArray[1];
                        GeoSegmentUtils.IsSegmentOverlapSegment3(s1, s2, s3, s4, ref insect);
                    }
                }
            }
            return(insect.mIsIntersect);
        }
示例#28
0
        public bool TestAABBIntersect(GeoAABB2 aabb)
        {
            GeoInsectPointArrayInfo insect = new GeoInsectPointArrayInfo();

            return(GeoSegmentUtils.IsSegmentInsectAABB2(mSeg.mP1, mSeg.mP2, aabb.mMin, aabb.mMax, ref insect));
        }
示例#29
0
        public static bool IsPlaneInsectSphere(GeoPlane plane, Vector3 center, float r, ref GeoInsectPointArrayInfo insect)
        {
            Vector3 close = new Vector3();
            float   dist  = PointClosestToPlaneAbs(plane.mNormal, plane.mD, center, ref close);

            if (dist > r)
            {
                return(false);
            }
            float rad = Mathf.Sqrt(r * r - dist * dist);

            insect.mIsIntersect = true;
            insect.mHitGlobalPoint.mPointArray.Add(close);
            insect.mHitGlobalPoint.mPointArray.Add(Vector3.one * rad);  // 相交为一个圆,所在平明为 plane
            return(true);
        }
示例#30
0
 public static bool IsTriangleInsectLine2(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 line1, Vector2 line2, ref GeoInsectPointArrayInfo insect)
 {
     return(GeoLineUtils.IsLineInsectTriangle2(line1, line2, p1, p2, p3, ref insect));
 }