Esempio n. 1
0
        //throw away the segments [0,u] and [v,1] of the segment

        /// <summary>
        /// Returns the trimmed curve
        /// </summary>
        /// <param name="u"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public ICurve Trim(double u, double v)
        {
            AdjustParamTo01(ref u);
            AdjustParamTo01(ref v);

            if (u > v)
            {
                return(Trim(v, u));
            }

            if (u > 1.0 - ApproximateComparer.Tolerance)
            {
                return(new CubicBezierSegment(b[3], b[3], b[3], b[3]));
            }

            Point[] b1 = new Point[3];
            Point[] b2 = new Point[2];
            Point   pv = Casteljau(u, b1, b2);

            //this will be the trim to [v,1]
            CubicBezierSegment trimByU = new CubicBezierSegment(pv, b2[1], b1[2], b[3]);


            //1-v is not zero here because we have handled already the case v=1
            Point pu = trimByU.Casteljau((v - u) / (1.0 - u), b1, b2);

            return(new CubicBezierSegment(trimByU.b[0], b1[0], b2[0], pu));
        }
Esempio n. 2
0
        static IEnumerable <CurveTangent> TangentsOfBezier(CubicBezierSegment bez)
        {
            const int numOfTangents = 8;
            double    span          = (bez.ParEnd - bez.ParStart) / numOfTangents;

            for (int i = 0; i < numOfTangents; i++)
            {
                yield return(TangentOnICurve(span / 2 + bez.ParStart + span * i, bez));
            }
        }
Esempio n. 3
0
        static IEnumerable <CurveTangent> TangentsAroundCurve(ICurve iCurve)
        {
            Curve c = iCurve as Curve;

            if (c != null)
            {
                foreach (ICurve seg in c.Segments)
                {
                    foreach (CurveTangent ct in TangentsAroundCurve(seg))
                    {
                        yield return(ct);
                    }
                }
            }
            else
            {
                LineSegment ls = iCurve as LineSegment;
                if (ls != null)
                {
                    yield return(new CurveTangent(ls.Start, ls.Derivative(0)));
                }
                else
                {
                    Ellipse ellipse = iCurve as Ellipse;
                    if (ellipse != null)
                    {
                        foreach (CurveTangent ct in TangentsOfEllipse(ellipse))
                        {
                            yield return(ct);
                        }
                    }
                    else
                    {
                        CubicBezierSegment bez = iCurve as CubicBezierSegment;
                        if (bez != null)
                        {
                            foreach (CurveTangent ct in TangentsOfBezier(bez))
                            {
                                yield return(ct);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        internal static bool CreateParallelogramOnSubSegOnBezierSeg(double start, double end, ICurve seg, ref Parallelogram box)
        {
            CubicBezierSegment trimSeg = seg.Trim(start, end) as CubicBezierSegment;


            B     b = trimSeg.B;
            Point a = b(1) - b(0);

            box = new Parallelogram(b(0), a, b(3) - b(0));

            if (box.Contains(b(2)))
            {
                return(true);
            }

            box = new Parallelogram(b(3), b(2) - b(3), b(0) - b(3));

            if (box.Contains(b(1)))
            {
                return(true);
            }

            return(false);
        }
 static bool BezierSegIntersectsBoundary(CubicBezierSegment seg, ICurve curve) {
     foreach (IntersectionInfo x in Curve.GetAllIntersections(seg, curve, false)) {
         Curve c = curve as Curve;
         if (c != null) {
             if (Curve.RealCutWithClosedCurve(x, c, false))
                 return true;
         } else {
             //curve is a line from a thin hierarchy that's forbidden to touch
             return true;
         }
     }
     return false;
 }
        private bool BezierSegIntersectsTree(CubicBezierSegment seg, ParallelogramNode tree) {
            if (tree == null)
                return false;
            if (Parallelogram.Intersect(seg.ParallelogramNodeOverICurve.Parallelogram, tree.Parallelogram)) {
                ParallelogramBinaryTreeNode n = tree as ParallelogramBinaryTreeNode;
                if (n != null) {
                    return BezierSegIntersectsTree(seg, n.LeftSon) || BezierSegIntersectsTree(seg, n.RightSon);
                } else
                    return BezierSegIntersectsBoundary(seg, ((ParallelogramNodeOverICurve)tree).Seg);

            } else return false;
        }
 private bool BezierSegIntersectsBoundary(CubicBezierSegment seg) {
     double side = Point.SignedDoubledTriangleArea(seg.B(0), seg.B(1), seg.B(2));
     if (side > 0)
         return BezierSegIntersectsTree(seg, thinLeftHierarchy) || BezierSegIntersectsTree(seg, leftHierarchy);
     else
         return BezierSegIntersectsTree(seg, thinRightHierarchy) || BezierSegIntersectsTree(seg, rightHierarchy);
 }
        internal static void DrawControlPoints(Graphics g, CubicBezierSegment bs){
            using (var pen = new Pen(Color.Green, (float) (1.0/1000.0))){
                pen.DashPattern = new[]{1, (float) 1};

                pen.DashStyle = DashStyle.Dot;
                g.DrawLine(pen, PointF(bs.B(0)), PointF(bs.B(1)));
                g.DrawLine(pen, PointF(bs.B(1)), PointF(bs.B(2)));
                g.DrawLine(pen, PointF(bs.B(2)), PointF(bs.B(3)));
            }
        }
        bool FitLonger(OrientedHubSegment longerOrientedSeg, Point del0, Point del1, Point midPointOfShorter,
                              double minDelLength, double maxDel, Point center, double radius) {
            CubicBezierSegment seg = (CubicBezierSegment)longerOrientedSeg.Segment;
            Point start = seg.Start;
            Point end = seg.End;
            // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve("green", shorterDebugOnly), new DebugCurve("red", seg));

            int steps = 0;
            const int maxSteps = 10;
            Point lowP1 = (1 - SqueezeBound) * seg.Start + SqueezeBound * seg.B(1);
            Point lowP2 = (1 - SqueezeBound) * seg.End + SqueezeBound * seg.B(2);
            Point highP1 = 2 * seg.B(1) - seg.Start;
            //originally the tangents were 0.25 of the length of seg[1]-seg[0] - so were are safe to lengthen two times
            Point highP2 = 2 * seg.B(2) - seg.End;
            PullControlPointToTheCircle(seg.Start, ref highP1, center, radius);
            int r = NicelyAligned(seg, del0, del1, midPointOfShorter, minDelLength, maxDel);
            do {
                if (r == -1) {
                    //pull the control points lower
                    Point p1 = (seg.B(1) + lowP1) / 2;
                    Point p2 = (seg.B(2) + lowP2) / 2;
                    highP1 = seg.B(1);
                    highP2 = seg.B(2);
                    seg = new CubicBezierSegment(start, p1, p2, end);
                }
                else {
                    Debug.Assert(r == 1);
                    //pull the control points higher
                    Point p1 = (seg.B(1) + highP1) / 2;
                    Point p2 = (seg.B(2) + highP2) / 2;
                    lowP1 = seg.B(1);
                    lowP2 = seg.B(2);
                    seg = new CubicBezierSegment(start, p1, p2, end);
                }


                if ((r = NicelyAligned(seg, del0, del1, midPointOfShorter, minDelLength, maxDel)) == 0) {
                    longerOrientedSeg.Other.Segment = longerOrientedSeg.Segment = seg;
                    return true;
                }
                if (steps++ > maxSteps) return false; //cannot fix it
            } while (true);
        }
 void WriteBezierSegment(CubicBezierSegment bs) {
     WriteStartElement(GeometryToken.CubicBezierSegment);
     WriteAttribute(GeometryToken.Points, PointsToString(bs.B(0), bs.B(1), bs.B(2), bs.B(3)));
     WriteEndElement();
 }
  static IEnumerable<CurveTangent> TangentsOfBezier(CubicBezierSegment bez) {
     const int numOfTangents = 8;
     double span = (bez.ParEnd - bez.ParStart) / numOfTangents;
     for (int i = 0; i < numOfTangents; i++)
         yield return TangentOnICurve(span / 2 + bez.ParStart + span * i, bez);
 }
Esempio n. 12
0
        List<ICurve> Getsegs() {
            var l = new List<ICurve>();
            var bs0 = new CubicBezierSegment(new Point(), new Point(0, 1), new Point(1, 2), new Point(1, 0));

            l.Add(bs0);
            var bs1 = new CubicBezierSegment(new Point(2,2), new Point(3, 1), new Point(4, 2), new Point(1, -5));
            bs1.Translate(new Point(10,10));
            l.Add(new LineSegment(bs0.End, bs1.Start));
            l.Add(bs1);
            var xAxis = new Point(2, 0);
            l.Add(new Ellipse(0, Math.PI/2, xAxis, new Point(0, 1), bs1.End - xAxis));

            return l;
        }
Esempio n. 13
0
        public void LengthTestingForCubucBezier() {
            var bs = new CubicBezierSegment(new Point(), new Point(0, 1), new Point(1, 1), new Point(1, 0));
            var len = bs.Length;
            Assert.IsTrue(Math.Abs(len - 2) < 0.001);
            bs = new CubicBezierSegment(new Point(), new Point(0, 1), new Point(1, 2), new Point(1, 0));

            var par = bs.GetParameterAtLength(2);
            var trimmed = bs.Trim(0, par);
            var trimmedLen =trimmed.Length;

            Assert.IsTrue(Math.Abs(trimmedLen - 2) < 0.000001);
        }
        static GraphicsPath CreatePathOnCurvaturePoint(Tuple<double, double> t, CubicBezierSegment cubic){
            var gp = new GraphicsPath();
            P2 center = cubic[t.Item1];
            int radius = 10;
            gp.AddEllipse((float) (center.X - radius), (float) (center.Y - radius),
                          (2*radius), (2*radius));

            return gp;
        }
 static GraphicsPath CreateControlPointPolygon(Tuple<double, double> t, CubicBezierSegment cubic){
     var gp = new GraphicsPath();
     gp.AddLines(new[]{PP(cubic.B(0)), PP(cubic.B(1)), PP(cubic.B(2)), PP(cubic.B(3))});
     return gp;
 }
Esempio n. 16
0
 static PathGeometry CreateControlPointPolygon(Tuple<double, double> t, CubicBezierSegment cubic)
 {
     throw new NotImplementedException();
     /*
     var gp = new GraphicsPath();
     gp.AddLines(new[] { PP(cubic.B(0)), PP(cubic.B(1)), PP(cubic.B(2)), PP(cubic.B(3)) });
     return gp;
     */
 }
Esempio n. 17
0
        static PathGeometry CreatePathOnCurvaturePoint(Tuple<double, double> t, CubicBezierSegment cubic)
        {
            throw new NotImplementedException();
            /*
            var gp = new GraphicsPath();
            Point center = cubic[t.First];
            int radius = 10;
            gp.AddEllipse((float)(center.X - radius), (float)(center.Y - radius),
                          (2 * radius), (2 * radius));

            return gp; //*/
        }
        //throw away the segments [0,u] and [v,1] of the segment

        /// <summary>
        /// Returns the trimmed curve
        /// </summary>
        /// <param name="u"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public ICurve Trim(double u, double v) {

            AdjustParamTo01(ref u);
            AdjustParamTo01(ref v);

            if (u > v)
                return Trim(v, u);

            if (u > 1.0 - ApproximateComparer.Tolerance)
                return new CubicBezierSegment(b[3], b[3], b[3], b[3]);

            Point[] b1 = new Point[3];
            Point[] b2 = new Point[2];
            Point pv = Casteljau(u, b1, b2);

            //this will be the trim to [v,1]
            CubicBezierSegment trimByU = new CubicBezierSegment(pv, b2[1], b1[2], b[3]);


            //1-v is not zero here because we have handled already the case v=1
            Point pu = trimByU.Casteljau((v - u) / (1.0 - u), b1, b2);

            return new CubicBezierSegment(trimByU.b[0], b1[0], b2[0], pu);

        }
 string CubicBezierSegmentToString(CubicBezierSegment cubic)
 {
     return "C" + PointsToString(cubic.B(1), cubic.B(2), cubic.B(3));
 }
        Rail ContinueReadingRail(LgEdgeInfo topRankedEdgoInfo, int zoomLevel, LgLevel level) {
            XmlRead();
            string pointString;
            if (TokenIs(GeometryToken.Arrowhead)) {
                Point arrowheadPosition = TryGetPointAttribute(GeometryToken.ArrowheadPosition);
                Point attachmentPoint = TryGetPointAttribute(GeometryToken.CurveAttachmentPoint);
                Arrowhead ah = new Arrowhead {
                    TipPosition = arrowheadPosition,
                    Length = (attachmentPoint - arrowheadPosition).Length
                };
                XmlRead();
                ReadEndElement();
                var rail = new Rail(ah, attachmentPoint, topRankedEdgoInfo, zoomLevel);
                var tuple = new SymmetricSegment(arrowheadPosition, attachmentPoint);
                level._railDictionary[tuple] = rail;
                return rail;
            }

            if (TokenIs(GeometryToken.LineSegment)) {
                pointString = GetAttribute(GeometryToken.Points);
                var linePoints = ParsePoints(pointString);
                Debug.Assert(linePoints.Length == 2);
                LineSegment ls = new LineSegment(linePoints[0], linePoints[1]);
                XmlRead();
                ReadEndElement();
                var rail = new Rail(ls, topRankedEdgoInfo, zoomLevel);
                var tuple = new SymmetricSegment(ls.Start, ls.End);
                level._railDictionary[tuple] = rail;
                level._railTree.Add(ls.BoundingBox, rail);
                return rail;
            }
            if (TokenIs(GeometryToken.CubicBezierSegment)) {
                pointString = GetAttribute(GeometryToken.Points);
                var controlPoints = ParsePoints(pointString);
                Debug.Assert(controlPoints.Length == 4);
                var bs = new CubicBezierSegment(controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3]);
                XmlRead();
                ReadEndElement();
                var rail = new Rail(bs, topRankedEdgoInfo, zoomLevel);
                var tuple = new SymmetricSegment(bs.Start, bs.End);
                level._railDictionary[tuple] = rail;
                return rail;
            }
            throw new Exception();
        }
 string CubicBezierSegmentToString(CubicBezierSegment cubic, char previousInstruction) {
     var str = PointsToString(cubic.B(1), cubic.B(2), cubic.B(3));
     return previousInstruction=='C'?str:"C"+str;
 }
 static ICurve CreateBaseSegOnSourceTargetAndOrth(ref Point a, ref Point b, ref Point abOrtog) {
     ICurve seg = new CubicBezierSegment(a, a*3.0/4 + b/4 + abOrtog, b*3.0/4.0 + a/4.0 + abOrtog, b);
     return seg;
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="longerSeg"></param>
 /// <param name="del0"></param>
 /// <param name="del1"></param>
 /// <param name="midPointOfShorter"></param>
 /// <param name="minDelLength"></param>
 /// <param name="maxDelLen"></param>
 /// <returns> 1 - need to stretch, -1 - need to squeze, 0 - OK </returns>
 int NicelyAligned(CubicBezierSegment longerSeg, Point del0, Point del1, Point midPointOfShorter,
                          double minDelLength, double maxDelLen) {
     const double eps = 0.001;
     Point midDel = longerSeg[0.5] - midPointOfShorter;
     double midDelLen = midDel.Length;
     if (del0 * midDel < 0 || del1 * midDel < 0)
         return 1;
     if (midDelLen < minDelLength - eps)
         return 1;
     if (midDelLen > maxDelLen + eps)
         return -1;
     return 0;
 }
 static void DrawBezier(DGraph graphToDraw, Pen myPen, Graphics g, CubicBezierSegment bs){
     g.DrawBezier(myPen, (float) bs.B(0).X, (float) bs.B(0).Y,
                  (float) bs.B(1).X, (float) bs.B(1).Y,
                  (float) bs.B(2).X, (float) bs.B(2).Y,
                  (float) bs.B(3).X, (float) bs.B(3).Y);
     if(graphToDraw.DrawingGraph.ShowControlPoints)
         DrawControlPoints(g, bs);
 }