protected static IPolyLine2D CreatePolyline(List <IntPoint> cpolyline, bool containsCircArc, double maxCircArcAngle, bool tryRecoverCircArc = true)
        {
            IPolyLine2D polyline;

            if (containsCircArc && tryRecoverCircArc)
            {
                polyline = GeomTools2D.CreatePolyline(CreatePolygon(cpolyline), maxCircArcAngle);
            }
            else
            {
                var count = cpolyline.Count;
                polyline = new PolyLine2D(count);
                if (count > 0)
                {
                    polyline.StartPoint = new IdaComPoint2D(cpolyline[0].X / ClipperScale, cpolyline[0].Y / ClipperScale);
                    var segments = polyline.Segments;
                    for (int i = 1; i < count; ++i)
                    {
                        segments.Add(new LineSegment2D(new Point(cpolyline[i].X / ClipperScale, cpolyline[i].Y / ClipperScale)));
                    }
                }
            }

            polyline.Close();
            return(polyline);
        }
        /// <summary>
        /// Creates a circular arc segment defined by tangents and radius.
        /// </summary>
        /// <param name="p1">The first point of tangent</param>
        /// <param name="p2">The intersection of tangents (the vertex).</param>
        /// <param name="p3">The other point of second tangent.</param>
        /// <param name="radius">The radius of curcular arc.</param>
        /// <param name="validateRounding">Indicates, whether validate rounding, that is inside given points p1, p2 and p3.
        /// If true and rounding is outside given point, then ArgumentException is thrown.</param>
        /// <param name="startPoint">The start point of circular arc segment.</param>
        /// <returns>A new circular arc segment.</returns>
        public static CircularArcSegment2D CreateByTangents(Point p1, Point p2, Point p3, double radius, bool validateRounding, out Point startPoint)
        {
            var v1  = p2 - p1;
            var ptl = GeomTools2D.PointToLine(ref p3, ref p1, ref v1);

            if (ptl == PointRelatedToLine.OnLine)
            {
                throw new NotSupportedException();
            }

            var v2 = p3 - p2;

            var n1 = v1.Perpendicular();
            var n2 = v2.Perpendicular();

            n1.Normalize();
            n2.Normalize();
            n1 *= radius;
            n2 *= radius;

            if (ptl == PointRelatedToLine.LeftSide)
            {
                n1 *= -1;
                n2 *= -1;
            }

            var p11 = p1 + n1;
            var p22 = p2 + n2;

            var centre = GeomTools2D.LineIntersection(p11, v1, p22, v2);
            var c1     = centre - n1;
            var c3     = centre - n2;
            var n12    = n1 + n2;

            n12.Normalize();
            n12 *= radius;
            var c2 = centre - n12;

            if (validateRounding)
            {
                var vv1  = c1 - p1;
                var test = v1 * vv1;
                if (test < 0)
                {
                    throw new ArgumentException();
                }

                var vv2 = c3 - p3;
                test = v2 * vv2;
                if (test > 0)
                {
                    throw new ArgumentException();
                }
            }

            startPoint = c1;
            return(new CircularArcSegment2D(c3, c2));
        }
        private static bool TrySortSegments(IPolyLine2D pattern, IPolyLine2D polyline, double offset)
        {
            if (pattern.Segments.Count == polyline.Segments.Count && pattern.Segments.Count > 0)
            {
                Point patStart   = pattern.StartPoint;
                var   patSegment = pattern.Segments[0];
                var   patU       = patSegment.EndPoint - patStart;
                patU.Normalize();
                Point start = polyline.StartPoint;
                for (var i = 0; i < polyline.Segments.Count; ++i)
                {
                    var segment = polyline.Segments[i];
                    var u       = segment.EndPoint - start;
                    var t       = Vector.CrossProduct(patU, u);
                    if (t.IsZero(1e-4))
                    {
                        // jsou rovnobezne, zkusime vzdalenost
                        t = GeomTools2D.LineToPointDistance(ref patStart, ref patU, ref start);
                        if (t.IsEqual(System.Math.Abs(offset), 0.001))
                        {
                            // mam segment odpovidajici prvnimu ve vzorove geometrii
                            u.Normalize();
                            if (!u.X.IsEqual(patU.X, 0.1) || !u.Y.IsEqual(patU.Y, 0.1))
                            {
                                // jsou opracne orientovane
                                start = segment.EndPoint;
                                GeomTools2D.ReversePolyline(ref polyline);
                            }

                            if (i == 0)
                            {
                                return(true);
                            }

                            var circ    = polyline.Segments.AsCircular();
                            var rotated = circ.Skip(i).Take(polyline.Segments.Count).ToList();
                            polyline.Segments.Clear();
                            (polyline.Segments as List <ISegment2D>).AddRange(rotated);
                            polyline.StartPoint = start;
                            return(true);
                        }
                    }

                    start = segment.EndPoint;
                }
            }

            return(false);
        }
Exemple #4
0
        public static void SortSegments(IPolyLine2D polyline, IPolyLine2D pattern)
        {
            var patternStart = (Point)pattern.StartPoint;
            var patternCount = pattern.Segments.Count;
            int patternInx = -1, inx = -1;

            for (var i = 0; i < patternCount; ++i)
            {
                var patternSegment = pattern.Segments[i];

                var start = (Point)polyline.StartPoint;
                var count = polyline.Segments.Count;
                for (var j = 0; j < count; ++j)
                {
                    var segment = polyline.Segments[j];

                    if (start.IsEqualWithTolerance(patternStart, 1e-6) &&
                        segment.EndPoint.IsEqualWithTolerance(patternSegment.EndPoint, 1e-6) &&
                        segment.GetType() == patternSegment.GetType())
                    {
                        patternInx = i;
                        inx        = j;
                        break;
                    }

                    start = segment.EndPoint;
                }

                if (inx >= 0)
                {
                    break;
                }

                patternStart = patternSegment.EndPoint;
            }

            if (patternInx != inx)
            {
                GeomTools2D.RotateSegments(polyline, inx - patternInx);
            }
        }
Exemple #5
0
        private static IList <ISegment2D> FindSecondSideOfPlate(Point plateSideBegPt, ISegment2D plateSide, IPolyLine2D outline, double distance, double tolerance = 0.0001)
        {
            Vector            vec2            = new Vector(plateSideBegPt.X - plateSide.EndPoint.X, plateSideBegPt.Y - plateSide.EndPoint.Y);
            List <ISegment2D> foundCandidates = new List <ISegment2D>();
            Point             begPt           = outline.StartPoint;

            foreach (ISegment2D seg in outline.Segments)
            {
                if (seg != plateSide)
                {
                    Vector vec1  = new Vector(begPt.X - seg.EndPoint.X, begPt.Y - seg.EndPoint.Y);
                    double angle = Math.Abs(GeomTools2D.AngleBetweenVectors(vec1, vec2));
                    if (angle.IsEqual(0.0, 0.035) || angle.IsEqual(Math.PI, 0.035))
                    {
                        if (GeomTools2D.Distance(plateSideBegPt, plateSide.EndPoint, seg.EndPoint).IsEqual(distance, tolerance))
                        {
                            Vector vector  = new Vector(1.0, 0.0);
                            Vector vector2 = new Vector(plateSide.EndPoint.X - plateSideBegPt.X, plateSide.EndPoint.Y - plateSideBegPt.Y);
                            double angle2  = Vector.AngleBetween(vector, vector2);                           //GeomTools2D.AngleBetweenVectors(vector, vector2);
                            Matrix mx      = Matrix.Identity;
                            mx.Rotate(-angle2);
                            Point a1   = mx.Transform(plateSideBegPt);
                            Point a2   = mx.Transform(plateSide.EndPoint);
                            Point b1   = mx.Transform(begPt);
                            Point b2   = mx.Transform(seg.EndPoint);
                            bool  test = false;

                            if (b1.X.IsEqual(a1.X) || b1.X.IsEqual(a2.X) || b2.X.IsEqual(a1.X) || b2.X.IsEqual(a2.X))
                            {
                                test = true;
                            }
                            else
                            {
                                if (Math.Sign(b1.X - a1.X) != Math.Sign(b1.X - a2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(b2.X - a1.X) != Math.Sign(b2.X - a2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(a1.X - b1.X) != Math.Sign(a1.X - b2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(a2.X - b1.X) != Math.Sign(a2.X - b2.X))
                                {
                                    test = true;
                                }
                            }

                            if (test)
                            {
                                foundCandidates.Add(seg);
                            }
                        }
                    }
                }

                begPt = seg.EndPoint;
            }

            return(foundCandidates);
        }