/// <summary>
        /// Creates a curve by using the underlying polyline
        /// </summary>
        /// <returns></returns>
        public Curve CreateCurve()
        {
            Curve curve = new Curve();
            Site  a     = HeadSite; //the corner start
            Site  b;                //the corner origin
            Site  c;                //the corner other end

            while (Curve.FindCorner(a, out b, out c))
            {
                CubicBezierSegment bezierSeg = CreateBezierSegOnSite(b);
                if (curve.Segments.Count == 0)
                {
                    if (!ApproximateComparer.Close(a.Point, bezierSeg.Start))
                    {
                        Curve.AddLineSegment(curve, a.Point, bezierSeg.Start);
                    }
                }
                else if (!ApproximateComparer.Close(curve.End, bezierSeg.Start))
                {
                    Curve.ContinueWithLineSegment(curve, bezierSeg.Start);
                }
                curve.AddSegment(bezierSeg);
                a = b;
            }

            System.Diagnostics.Debug.Assert(a.Next.Next == null);

            if (curve.Segments.Count == 0)
            {
                if (!ApproximateComparer.Close(a.Point, a.Next.Point))
                {
                    Curve.AddLineSegment(curve, a.Point, a.Next.Point);
                }
                else
                {
                    double w = 5;
                    curve.Segments.Add(new CubicBezierSegment(a.Point, a.Point + new Point(w, w), a.Point + new Point(-w, w), b.Point));
                }
            }
            else if (!ApproximateComparer.Close(curve.End, a.Next.Point))
            {
                Curve.ContinueWithLineSegment(curve, a.Next.Point);
            }
            return(curve);
        }
        internal static Polyline CreateConvexHullAsClosedPolyline(IEnumerable <Point> points)
        {
            var convexHull = new Polyline(CalculateConvexHull(points))
            {
                Closed = true
            };

#if TEST_MSAGL
            foreach (var point in points)
            {
                if (Curve.PointRelativeToCurveLocation(point, convexHull) == PointLocation.Outside)
                {
                    var hullPoint = convexHull[convexHull.ClosestParameter(point)];

                    // This can be too restrictive if very close points are put into the hull.  It is probably
                    // better to clean up in the caller before doing this, but this assert can also be relaxed.
                    Debug.Assert(ApproximateComparer.Close(point, hullPoint, ApproximateComparer.IntersectionEpsilon * 20), String.Format("not CloseIntersections: initial point {0}, hull point {1}", point, hullPoint));
                }
            }
#endif // TEST_MSAGL
            return(convexHull);
        }
Пример #3
0
        /// <summary>
        /// computes orientation of three vectors with a common source
        /// (compare polar angles of v1 and v2 with respect to v0)
        /// </summary>
        /// <returns>
        ///  -1 if the orientation is v0 v1 v2
        ///   1 if the orientation is v0 v2 v1
        ///   0  if v1 and v2 are collinear and codirectinal
        /// </returns>
        static public int GetOrientationOf3Vectors(Point vector0, Point vector1, Point vector2)
        {
            const double multiplier = 1000; //TODO, need to fix it?

            vector0 *= multiplier;
            vector1 *= multiplier;
            vector2 *= multiplier;

            double xp2   = Point.CrossProduct(vector0, vector2);
            double dotp2 = vector0 * vector2;
            double xp1   = Point.CrossProduct(vector0, vector1);
            double dotp1 = vector0 * vector1;

            // v1 is collinear with v0
            if (ApproximateComparer.Close(xp1, 0.0) && ApproximateComparer.GreaterOrEqual(dotp1, 0.0))
            {
                if (ApproximateComparer.Close(xp2, 0.0) && ApproximateComparer.GreaterOrEqual(dotp2, 0.0))
                {
                    return(0);
                }
                return(1);
            }

            // v2 is collinear with v0
            if (ApproximateComparer.Close(xp2, 0.0) && ApproximateComparer.GreaterOrEqual(dotp2, 0.0))
            {
                return(-1);
            }

            if (ApproximateComparer.Close(xp1, 0.0) || ApproximateComparer.Close(xp2, 0.0) || xp1 * xp2 > 0.0)
            {
                // both on same side of v0, compare to each other
                return(ApproximateComparer.Compare(Point.CrossProduct(vector2, vector1), 0.0));
            }

            // vectors "less than" zero degrees are actually large, near 2 pi
            return(-ApproximateComparer.Compare(Math.Sign(xp1), 0.0));
        }