示例#1
0
        public static void RemoveOnStraightPt(Polyline poly, double straightTolerance)
        {
            List <Point3d> removed = new List <Point3d>();

            bool isClosed = poly.IsClosed;

            if (isClosed)
            {
                poly.RemoveAt(poly.Count - 1);
            }

            int pointCount = poly.Count;

            for (int i = 0; i < pointCount; i++)
            {
                if (i == 0 && !isClosed)
                {
                    removed.Add(poly[i]);
                    continue;
                }

                Vector3d preVector  = poly[(pointCount + i - 1) % pointCount] - poly[i];
                Vector3d postVector = poly[(pointCount + i + 1) % pointCount] - poly[i];

                if (preVector.Length < 0.005)
                {
                    continue;
                }

                if (i == pointCount - 1 && !isClosed)
                {
                    removed.Add(poly[i]);
                    break;
                }

                var tempConvexity = VectorTools.CheckConvexity(preVector, postVector, straightTolerance);
                if ((tempConvexity == Convexity.Convex || tempConvexity == Convexity.Concave) || postVector.Length < 0.005)
                {
                    removed.Add(poly[i]);
                }
            }

            poly.Clear();
            poly.AddRange(removed);
            if (isClosed)
            {
                poly.Add(poly.First);
            }
        }
示例#2
0
        public static Rectangle3d DrawP2PRect(Point3d pointStart, Point3d pointEnd, double perpThickness, double alignThickness)
        {
            Rectangle3d p2pRect = new Rectangle3d();

            Vector3d alignP2P = new Line(pointStart, pointEnd).UnitTangent;
            Vector3d perpP2P  = VectorTools.RotateVectorXY(alignP2P, Math.PI / 2.0);

            Point3d corner1  = pointStart - alignP2P * alignThickness / 2.0 + perpP2P * perpThickness / 2.0;
            Point3d corner2  = pointEnd + alignP2P * alignThickness / 2.0 - perpP2P * perpThickness / 2.0;
            Plane   p2pPlane = new Plane(pointStart, alignP2P, perpP2P);

            p2pRect = new Rectangle3d(p2pPlane, corner1, corner2);

            return(p2pRect);
        }
示例#3
0
        /// <summary>
        /// 반시계 방향 기준으로 경계 안에 그릴 수 있는 최장의 선을 반환합니다. 기준점이 경계를 벗어나는 경우는 PCXStrict와 동일합니다.
        /// </summary>
        public static Line PCXLongest(Point3d basePt, Polyline boundary, Vector3d direction)
        {
            double  onCurveTolerance  = 0.5;
            double  samePtTolerance   = 0.005;
            double  parallelTolerance = 0.005;
            Point3d longestEnd        = basePt;


            //Get all crossing points.
            List <Point3d> allCrossPts = GetAllCrossPoints(basePt, boundary, direction, onCurveTolerance);

            allCrossPts.Sort((a, b) => (basePt.DistanceTo(a).CompareTo(basePt.DistanceTo(b))));

            //Set compare points.
            List <Point3d> boundaryPt = new List <Point3d>(boundary);

            if (boundary.IsClosed)
            {
                boundaryPt.RemoveAt(boundaryPt.Count - 1);
            }


            //Find end point of longest line.
            foreach (Point3d i in allCrossPts)
            {
                longestEnd = i;

                //seive1: Remove same as basePt.
                if (i.DistanceTo(basePt) < samePtTolerance)
                {
                    continue;
                }


                //seive2: End if not vertex.
                int  vertexIndex = boundaryPt.FindIndex(n => n.DistanceTo(i) < samePtTolerance);
                bool isVertex    = vertexIndex != -1;

                if (!isVertex)
                {
                    break;
                }


                //seive3: End if not concave(& anti-parallel).
                Vector3d  toPre  = boundaryPt[(boundaryPt.Count + vertexIndex - 1) % boundaryPt.Count] - boundaryPt[vertexIndex];
                Vector3d  toPost = boundaryPt[(boundaryPt.Count + vertexIndex + 1) % boundaryPt.Count] - boundaryPt[vertexIndex];
                Convexity cnv    = VectorTools.CheckConvexity(toPre, toPost, parallelTolerance);

                if (cnv == Convexity.Convex || cnv == Convexity.Parallel)
                {
                    break;
                }


                //seive4: Continue if not between.
                if (!VectorTools.IsBetweenVector(toPre, toPost, -direction))
                {
                    continue;
                }


                //seive5: End if pre or post is not parallel to direction.
                bool isPreDirParallel  = Math.Abs(toPre * direction / (toPre.Length * direction.Length)) > 1 - parallelTolerance;
                bool isPostDirParallel = Math.Abs(toPost * direction / (toPost.Length * direction.Length)) > 1 - parallelTolerance;

                if (isPreDirParallel || isPostDirParallel)
                {
                    continue;
                }


                //seive6: Continue if passable.
                Vector3d perpToDir = direction;
                perpToDir.Rotate(Math.PI / 2, Vector3d.ZAxis);

                double preDirDot  = toPre * perpToDir;
                double postDirDot = toPost * perpToDir;

                if (preDirDot * postDirDot > 0)
                {
                    continue;
                }

                break;
            }

            return(new Line(basePt, longestEnd));
        }