bool HavCrossPoint(Poly poly, PolySide sideAB, IgnoreSideInfo[] ignoreSideInfos)
        {
            int      result;
            Vector3d pt;

            for (int i = 0; i < poly.sidesList.Count; i++)
            {
                PolySide[] sides = poly.sidesList[i];

                for (int j = 0; j < sides.Length; j++)
                {
                    if (InIgnoreSides(i, j, ignoreSideInfos))
                    {
                        continue;
                    }

                    //求解ab线段和多边形边sides[j]的交点
                    result = geoAlgor.SolvePolySideCrossPoint2D(sides[j], sideAB, out pt);
                    if (result == 1)  //存在交点
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #2
0
        public Poly Copy()
        {
            Poly poly = new Poly();

            poly.faceNormal = faceNormal;

            for (int i = 0; i < sidesList.Count; i++)
            {
                PolySide[] polySides = new PolySide[sidesList[i].Length];
                for (int j = 0; j < sidesList[i].Length; j++)
                {
                    polySides[j] = sidesList[i][j].Copy();
                }
                poly.sidesList.Add(polySides);
            }

            for (int i = 0; i < sidesList.Count; i++)
            {
                Vector3d[] verts = new Vector3d[vertexsList[i].Length];
                for (int j = 0; j < sidesList[i].Length; j++)
                {
                    verts[j] = vertexsList[i][j];
                }
                poly.vertexsList.Add(verts);
            }

            return(poly);
        }
        /// <summary>
        /// 求解多边形边的交点,
        /// 是否比较边的端点(比较边的端点一般用于点是否在多边形中的判断)
        /// </summary>
        /// <param name="polySide1">多边形的一条边</param>
        /// <param name="polySide2">多边形的一条边</param>
        /// <param name="isCmpSideEndPoint">是否比较边的端点(比较边的端点一般用于点是否在多边形中的判断)</param>
        /// <param name="crossPt">两条边的交点</param>
        /// <returns>返回值为 1: 有1个交点, 0:没有交点</returns>
        public int SolvePolySideCrossPoint2D(PolySide polySide1, PolySide polySide2, bool isCmpSideEndPoint, out Vector3d crossPt)
        {
            Vector3d m            = new Vector3d(polySide1.dir.z, 0, -polySide1.dir.x);
            bool     isHavCrossPt = SolveCrossPoint2D(polySide2.startpos, polySide2.dir, polySide1.startpos, m, out crossPt);

            //两条边互相平行
            if (!isHavCrossPt)
            {
                return(0);
            }

            double   step;
            Vector3d crossPtToPtVec = crossPt - polySide2.startpos;

            CmpParallelVecDir(crossPtToPtVec, polySide2.dir, out step);
            //交点crossPt不在polySide2边的范围内
            if (step < 0 || step > polySide2.step + esp)
            {
                return(0);
            }

            crossPtToPtVec = crossPt - polySide1.startpos;

            //交点与端点重合
            if (IsZero(crossPtToPtVec))
            {
                if (isCmpSideEndPoint)
                {
                    Vector3d sideEndPt = polySide1.startpos + polySide1.dir * polySide1.step;
                    double   v         = Cross2D(sideEndPt - polySide2.startpos, polySide2.dir);
                    return(v < 0 ? 1 : 0);
                }

                return(1);
            }
            else if (IsEqual(crossPtToPtVec, polySide1.dir * polySide1.step))
            {
                if (isCmpSideEndPoint)
                {
                    double v = Cross2D(polySide1.startpos - polySide2.startpos, polySide2.dir);
                    return(v < 0 ? 1 : 0);
                }

                return(1);
            }

            CmpParallelVecDir(crossPtToPtVec, polySide1.dir, out step);
            //交点crossPt不在polySide1边的范围内
            if (step < 0 || step > polySide1.step + esp)
            {
                return(0);
            }

            return(1);
        }
Пример #4
0
        /// <summary>
        /// 生成PolySide
        /// </summary>
        /// <param name="startVertex"></param>
        /// <param name="endVertex"></param>
        /// <returns></returns>
        public PolySide CreatePolySide(Vector3d startVertex, Vector3d endVertex)
        {
            PolySide side = new PolySide();

            side.startpos = startVertex;
            side.dir      = endVertex - startVertex;
            side.step     = side.dir.magnitude;
            side.dir     /= side.step;

            return(side);
        }
Пример #5
0
        /// <summary>
        /// 判断点pointMustInPloyPlane是否在多边形中,
        /// pointMustInPloyPlane必须在多边形的同一平面中,但不一定在多边形中
        /// </summary>
        /// <param name="polySides">多边形中所有点共面</param>
        /// <param name="pointMustInPloyPlane"></param>
        /// <returns></returns>
        public bool IsInsidePoly(Poly poly, Vector3d pointMustInPloyPlane, PloySideType checkSideType = PloySideType.Allside)
        {
            PolySide[]        polySides;
            List <PolySide[]> polySidesList  = poly.sidesList;
            Vector3d          pt             = pointMustInPloyPlane;
            Vector3d          polyFaceNormal = poly.faceNormal;

            //判断从点引出的平行于sides[0]方向的正向射线是否与其它边相交
            Vector3d n            = polySidesList[0][0].startpos - pt;
            int      crossPtCount = 0;
            Vector3d crossPt;
            PolySide polySide2 = new PolySide();

            polySide2.startpos = pt;
            polySide2.dir      = n;
            polySide2.step     = 1000000;

            for (int j = 0; j < polySidesList.Count; j++)
            {
                if (checkSideType == PloySideType.Outside)
                {
                    if (j == 1)
                    {
                        break;
                    }
                }
                else if (checkSideType == PloySideType.Inside)
                {
                    if (j == 0)
                    {
                        continue;
                    }
                }

                polySides = polySidesList[j];

                for (int i = 0; i < polySides.Length; i++)
                {
                    crossPtCount += SolvePolySideCrossPoint(polySides[i], polySide2, polyFaceNormal, true, out crossPt);
                }
            }

            //判断是偶数个交点,还是奇数个交点
            if (crossPtCount % 2 == 0)
            {
                return(false);
            }

            return(true);
        }
Пример #6
0
        /// <summary>
        /// 生成基础数据的PolySide组
        /// </summary>
        /// <param name="polyVertexs"></param>
        /// <returns></returns>
        public PolySide[] CreatePolySides(Vector3d[] polyVertexs)
        {
            PolySide[] sides = new PolySide[polyVertexs.Length];

            for (int i = 0; i < polyVertexs.Length; i++)
            {
                if (i == polyVertexs.Length - 1)
                {
                    sides[i] = CreatePolySide(polyVertexs[i], polyVertexs[0]);
                }
                else
                {
                    sides[i] = CreatePolySide(polyVertexs[i], polyVertexs[i + 1]);
                }
            }

            return(sides);
        }
Пример #7
0
        public PolySide Copy()
        {
            PolySide polySide = new PolySide();

            polySide.startpos = startpos;
            polySide.dir      = dir;
            polySide.step     = step;
            polySide.vertDir  = vertDir;

            if (crossPointInfoList != null)
            {
                polySide.crossPointInfoList = new List <CrossPointInfo>();

                for (int i = 0; i < crossPointInfoList.Count; i++)
                {
                    polySide.crossPointInfoList[i] = crossPointInfoList[i].Copy();
                }
            }
            return(polySide);
        }
Пример #8
0
        /// <summary>
        /// 求解多边形边的交点,
        /// 是否比较边的端点(比较边的端点一般用于点是否在多边形中的判断)
        /// </summary>
        /// <param name="polySide1">多边形的一条边</param>
        /// <param name="polySide2">多边形的一条边</param>
        /// <param name="polyFaceNormal">多边形面向法线</param>
        /// <param name="isCmpSideEndPoint">是否比较边的端点(比较边的端点一般用于点是否在多边形中的判断)</param>
        /// <param name="crossPt">两条边的交点</param>
        /// <returns>返回值为 1: 有1个交点, 0:没有交点</returns>
        public int SolvePolySideCrossPoint(
            PolySide polySide1, PolySide polySide2, Vector3d polyFaceNormal,
            bool isCmpSideEndPoint, out Vector3d crossPt)
        {
            //m为新的平面的法向,要求m和 polySide1.dir互相垂直,同时m不能与poly的法向平行
            //既由m确认的平面不能是poly的平面
            Vector3d m            = Vector3d.Cross(polySide1.dir, polyFaceNormal);
            bool     isHavCrossPt = SolveCrossPoint(polySide2.startpos, polySide2.dir, polySide1.startpos, m, out crossPt);

            //两条边互相平行
            if (!isHavCrossPt)
            {
                return(0);
            }

            double   step;
            Vector3d crossPtToPtVec = crossPt - polySide2.startpos;

            CmpParallelVecDir(crossPtToPtVec, polySide2.dir, out step);
            //交点crossPt不在polySide2边的范围内
            if (step < 0 || step > polySide2.step + esp)
            {
                return(0);
            }

            crossPtToPtVec = crossPt - polySide1.startpos;

            //交点与端点重合
            if (IsZero(crossPtToPtVec))
            {
                if (isCmpSideEndPoint)
                {
                    Vector3d sideEndPt = polySide1.startpos + polySide1.dir * polySide1.step;
                    Vector3d v         = Vector3d.Cross(sideEndPt - polySide2.startpos, polySide2.dir);
                    if (CmpParallelVecDir(v, polyFaceNormal, out step) != 1)
                    {
                        return(1);
                    }
                    return(0);
                }

                return(1);
            }
            else if (IsEqual(crossPtToPtVec, polySide1.dir * polySide1.step))
            {
                if (isCmpSideEndPoint)
                {
                    Vector3d v = Vector3d.Cross(polySide1.startpos - polySide2.startpos, polySide2.dir);
                    if (CmpParallelVecDir(v, polyFaceNormal, out step) != 1)
                    {
                        return(1);
                    }
                    return(0);
                }

                return(1);
            }

            CmpParallelVecDir(crossPtToPtVec, polySide1.dir, out step);
            //交点crossPt不在polySide1边的范围内
            if (step < 0 || step > polySide1.step + esp)
            {
                return(0);
            }

            return(1);
        }
Пример #9
0
 /// <summary>
 /// 求解多边形边的交点(此功能不比较边的方向,一般比较边的方向用于点是否在多边形中的判断)
 /// </summary>
 /// <param name="polySide1">多边形的一条边</param>
 /// <param name="polySide2">多边形的一条边</param>
 /// <param name="polyFaceNormal">多边形面向法线</param>
 /// <param name="crossPt">输出射线和边的交点</param>
 /// <returns>返回值为 1: 有1个交点, 0:没有交点</returns>
 public int SolvePolySideCrossPoint(PolySide polySide1, PolySide polySide2, Vector3d polyFaceNormal, out Vector3d crossPt)
 {
     return(SolvePolySideCrossPoint(polySide1, polySide2, polyFaceNormal, false, out crossPt));
 }
 /// <summary>
 /// 求解多边形边的交点(此功能不比较边的方向,一般比较边的方向用于点是否在多边形中的判断)
 /// </summary>
 /// <param name="polySide1">多边形的一条边</param>
 /// <param name="polySide2">多边形的一条边</param>
 /// <param name="polyFaceNormal">多边形面向法线</param>
 /// <param name="crossPt">输出射线和边的交点</param>
 /// <returns>返回值为 1: 有1个交点, 0:没有交点</returns>
 public int SolvePolySideCrossPoint2D(PolySide polySide1, PolySide polySide2, out Vector3d crossPt)
 {
     return(SolvePolySideCrossPoint2D(polySide1, polySide2, false, out crossPt));
 }
        /// <summary>
        /// 生成去除一个内环后的多边形
        /// </summary>
        /// <param name="poly">原始多边形</param>
        /// <param name="ringIdx">内环在原始多边形中的编号</param>
        /// <param name="ringVertexIdx">内环分切点编号</param>
        /// <param name="outVertexIdx">外环分切点编号</param>
        /// <param name="endLinkSide">连接线段</param>
        /// <returns></returns>
        Poly CreatePolyByRemoveRing(
            Poly poly,
            int ringIdx,
            int ringSplitVertIdx,
            int outSplitVertIdx,
            PolySide endLinkSide)
        {
            List <Vector3d> resultPolyVertexList = new List <Vector3d>();
            List <PolySide> resultPolySideList   = new List <PolySide>();
            Vector3d        outVert   = poly.vertexsList[0][outSplitVertIdx];
            Vector3d        startVert = poly.vertexsList[ringIdx][ringSplitVertIdx];

            for (int i = outSplitVertIdx; i < poly.vertexsList[0].Length; i++)
            {
                resultPolyVertexList.Add(poly.vertexsList[0][i]);
            }
            for (int i = 0; i <= outSplitVertIdx; i++)
            {
                resultPolyVertexList.Add(poly.vertexsList[0][i]);
            }

            for (int i = ringSplitVertIdx; i < poly.vertexsList[ringIdx].Length; i++)
            {
                resultPolyVertexList.Add(poly.vertexsList[ringIdx][i]);
            }
            for (int i = 0; i <= ringSplitVertIdx; i++)
            {
                resultPolyVertexList.Add(poly.vertexsList[ringIdx][i]);
            }

            //
            for (int i = outSplitVertIdx; i < poly.sidesList[0].Length; i++)
            {
                resultPolySideList.Add(poly.sidesList[0][i]);
            }
            for (int i = 0; i < outSplitVertIdx; i++)
            {
                resultPolySideList.Add(poly.sidesList[0][i]);
            }


            PolySide linkSide = geoAlgor.CreatePolySide(outVert, startVert);

            resultPolySideList.Add(linkSide);

            for (int i = ringSplitVertIdx; i < poly.sidesList[ringIdx].Length; i++)
            {
                resultPolySideList.Add(poly.sidesList[ringIdx][i]);
            }
            for (int i = 0; i < ringSplitVertIdx; i++)
            {
                resultPolySideList.Add(poly.sidesList[ringIdx][i]);
            }

            resultPolySideList.Add(endLinkSide);


            //
            Poly resultPoly = new Poly();

            resultPoly.sidesList.Add(resultPolySideList.ToArray());

            for (int i = 1; i < poly.sidesList.Count; i++)
            {
                if (i == ringIdx)
                {
                    continue;
                }

                resultPoly.sidesList.Add(poly.sidesList[i]);
            }


            //
            resultPoly.vertexsList.Add(resultPolyVertexList.ToArray());

            for (int i = 1; i < poly.vertexsList.Count; i++)
            {
                if (i == ringIdx)
                {
                    continue;
                }

                resultPoly.vertexsList.Add(poly.vertexsList[i]);
            }

            resultPoly.faceNormal = poly.faceNormal;
            return(resultPoly);
        }