Beispiel #1
0
        /// <summary>
        /// Creates a bounding parallelogram on a curve segment
        /// We suppose here that the segment is convex or concave from start to end,
        /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex
        /// </summary>
        internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box,
                                                         Point startPoint, Point endPoint)
        {
            if (seg is CubicBezierSegment)
            {
                return(CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box));
            }

            Point tan1 = seg.Derivative(start);

            Point tan2     = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);



            Point p = endPoint - startPoint;

            double numerator   = p * tan2Perp;
            double denumerator = (tan1 * tan2Perp);
            double x;// = (p * tan2Perp) / (tan1 * tan2Perp);

            if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
            {
                x = 0;
            }
            else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon)
            {
                //it is degenerated; adjacent sides are parallel, but
                //since p * tan2Perp is big it does not contain e
                return(false);
            }
            else
            {
                x = numerator / denumerator;
            }

            tan1 *= x;

            box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1);
#if DEBUGCURVES
            if (!box.Contains(seg[end]))
            {
                throw new InvalidOperationException();//"the box does not contain the end of the segment");
            }
#endif

            double delta = (end - start) / 64;
            for (int i = 1; i < 64; i++)
            {
                if (!box.Contains(seg[start + delta * i]))
                {
                    return(false);
                }
            }
            return(true);
        }
 void InitValues()
 {
     a   = curveA[si];
     b   = curveB[ti];
     a_b = a - b;
     ad  = curveA.Derivative(si);
     add = curveA.SecondDerivative(si);
     bd  = curveB.Derivative(ti);
     bdd = curveB.SecondDerivative(ti);
 }
Beispiel #3
0
 /// <summary>
 /// in general works for convex curves
 /// </summary>
 /// <param name="iCurve"></param>
 /// <param name="pointInside"></param>
 /// <returns></returns>
 internal static bool CurveIsClockwise(ICurve iCurve, Point pointInside)
 {
     return
         (Point.GetTriangleOrientation(pointInside, iCurve.Start,
                                       iCurve.Start + iCurve.Derivative(iCurve.ParStart)) ==
          TriangleOrientation.Clockwise);
 }
        /// <summary>
        ///     Places the label at the first position requested.  Ignores all overlaps.
        /// </summary>
        void PlaceLabelAtFirstPosition(Label label)
        {
            var    edge  = (Edge)label.GeometryParent;
            ICurve curve = edge.Curve ?? new LineSegment(edge.Source.Center, edge.Target.Center);

            List <KeyValuePair <double, Point> > points = edgePoints[edge];

            int   index      = StartIndex(label, points);
            Point point      = points[index].Value;
            Point derivative = curve.Derivative(points[index].Key);

            // If the curve is a line of length (close to) 0, the derivative may be (close to) 0.
            // Pick a direction in that case.
            if (derivative.Length < ApproximateComparer.Tolerance)
            {
                derivative = new Point(1, 1);
            }

            var    widthHeight = new Point(label.Width, label.Height);
            double side        = GetPossibleSides(label.Side, derivative).First();

            Rectangle bounds = GetLabelBounds(point, derivative, widthHeight, side);

            SetLabelBounds(label, bounds);
        }
Beispiel #5
0
        static public bool edge_rendering_delegate(Edge edge, object edgeLine_path)
        {
            Path   path = edgeLine_path as Path;
            ICurve cv   = edge.EdgeCurve;

            var   t_middle = cv.GetParameterAtLength(cv.Length / 2);
            var   dva = cv.Derivative(t_middle); //求中点的导数
            var   midPoint = cv[t_middle];       // Common.WpfPoint( cv[t_middle]);
            float x = (float)midPoint.X, y = (float)midPoint.Y;

            var                   geo2    = DataDefine.get_svg2();
            MatrixTransform       mt      = new MatrixTransform();
            Func <double, double> rad2Deg = v => { return(v * 180 / Math.PI); };
            //mt.Matrix.
            var deg = rad2Deg(Math.Atan2(dva.Y, dva.X));
            var mat = Matrix.Identity;

            mat.TranslatePrepend(x, y);
            mat.RotatePrepend(deg);
            mat.ScalePrepend(-0.2f, 0.2f);
            mt.Matrix      = mat;
            geo2.Transform = mt;

            var          circle = new EllipseGeometry(new WpfPoint(x, y), 2, 2);
            PathGeometry pp     = new PathGeometry();

            pp.FillRule = FillRule.EvenOdd;

            pp.AddGeometry(Common.GetICurveWpfGeometry(cv));
            pp.AddGeometry(circle);
            pp.AddGeometry(geo2);
            path.Data = pp;

            return(true);
        }
        static ICurve GetSidesAndEdgeCurve(Label label, Edge e, List <KeyValuePair <double, Point> > curvePoints, int index, out double[] sides)
        {
            ICurve curve      = e.Curve ?? new LineSegment(e.Source.Center, e.Target.Center);
            Point  initialDer = curve.Derivative(curvePoints[index].Key);

            sides = GetPossibleSides(label.Side, initialDer);
            return(curve);
        }
        ///// <summary>
        ///// Gets the closest point on the curve to the point
        ///// </summary>
        ///// <param name="curve"></param>
        ///// <param name="coeff"></param>
        ///// <param name="hint">will return Double.MaxVal if Newton iterations fail</param>
        ///// <param name="closestPointParam"></param>
        internal static double ClosestPoint(ICurve curve, Point a, double hint, double low, double high)
        {
            /*
             * Let F=(c(t)-a)^2. We try to bring to zero the first derivative of F, Ft. Denote it by f(t).
             * Applying the Newton method we see that dt=-f(t)/der(f(t)
             * The first derivative of F, f, has the form (c-a)*ct. We discarded a multiplier here.
             * The second derivative has the form ct*ct+(c-a)*ctt
             * The new t becomes t-dt
             */
            const int numberOfIterationsMax = 5;
            const int numberOfOverShootsMax = 5;
            double    t = hint;

            int    numberOfIteration  = 0;
            int    numberOfOvershoots = 0;
            double dt;
            bool   abort = false;

            do
            {
                Point c   = curve[t];
                Point ct  = curve.Derivative(t);
                Point ctt = curve.SecondDerivative(t);

                double secondDerivative = ct * ct + (c - a) * ctt;

                if (Math.Abs(secondDerivative) < ApproximateComparer.Tolerance)
                {
                    return(t);
                }

                dt = (c - a) * ct / secondDerivative;

                t -= dt;

                if (t > high + ApproximateComparer.Tolerance)
                {
                    t = high;
                    numberOfOvershoots++;
                }
                else if (t < low - ApproximateComparer.Tolerance)
                {
                    t = low;
                    numberOfOvershoots++;
                }
                numberOfIteration++;
            } while (Math.Abs(dt) > ApproximateComparer.Tolerance && !
                     (abort = (numberOfIteration >= numberOfIterationsMax || numberOfOvershoots >= numberOfOverShootsMax)));

            //may be the initial value was just fine
            if (abort && (curve[hint] - a).Length < ApproximateComparer.DistanceEpsilon)
            {
                t = hint;
            }

            return(t);
        }
        ///// <summary>
        ///// Gets the closest point on the curve to the point
        ///// </summary>
        ///// <param name="curve"></param>
        ///// <param name="coeff"></param>
        ///// <param name="hint">will return Double.MaxVal if Newton iterations fail</param>
        ///// <param name="closestPointParam"></param>
        internal static double ClosestPoint(ICurve curve, Point a, double hint, double low, double high)
        {
            const int numberOfIterationsMax = 5;
            const int numberOfOverShootsMax = 5;
            double    t = hint;

            int    numberOfIteration  = 0;
            int    numberOfOvershoots = 0;
            double dt;
            bool   abort = false;

            do
            {
                Point c   = curve[t];
                Point ct  = curve.Derivative(t);
                Point ctt = curve.SecondDerivative(t);

                double secondDerivative = ct * ct + (c - a) * ctt;

                if (Math.Abs(secondDerivative) < ApproximateComparer.Tolerance)
                {
                    return(t);
                }

                dt = (c - a) * ct / secondDerivative;

                t -= dt;

                if (t > high + ApproximateComparer.Tolerance)
                {
                    t = high;
                    numberOfOvershoots++;
                }
                else if (t < low - ApproximateComparer.Tolerance)
                {
                    t = low;
                    numberOfOvershoots++;
                }
                numberOfIteration++;
            } while (Math.Abs(dt) > ApproximateComparer.Tolerance && !
                     (abort = (numberOfIteration >= numberOfIterationsMax || numberOfOvershoots >= numberOfOverShootsMax)));

            //may be the initial value was just fine
            if (abort && (curve[hint] - a).Length < ApproximateComparer.DistanceEpsilon)
            {
                t = hint;
            }

            return(t);
        }
        ///// <summary>
        ///// Gets the closest point on the curve to the point
        ///// </summary>
        ///// <param name="curve"></param>
        ///// <param name="coeff"></param>
        ///// <param name="hint">will return Double.MaxVal if Newton iterations fail</param>
        ///// <param name="closestPointParam"></param>
        internal static double ClosestPoint(ICurve curve, Point a, double hint, double low, double high) {
            /*
              * Let F=(c(t)-a)^2. We try to bring to zero the first derivative of F, Ft. Denote it by f(t).
              * Applying the Newton method we see that dt=-f(t)/der(f(t)
              * The first derivative of F, f, has the form (c-a)*ct. We discarded a multiplier here.
              * The second derivative has the form ct*ct+(c-a)*ctt
              * The new t becomes t-dt
              */
            const int numberOfIterationsMax = 5;
            const int numberOfOverShootsMax = 5;
            double t = hint;
      
            int numberOfIteration = 0;
            int numberOfOvershoots = 0;
            double dt;
            bool abort = false;
            do {
                Point c = curve[t];
                Point ct = curve.Derivative(t);
                Point ctt = curve.SecondDerivative(t);

                double secondDerivative = ct * ct + (c - a) * ctt;

                if (Math.Abs(secondDerivative) < ApproximateComparer.Tolerance) 
                    return t;

                dt = (c - a) * ct / secondDerivative;
               
                t -= dt;
                
                if (t > high + ApproximateComparer.Tolerance) {
                    t = high;
                    numberOfOvershoots++;
                } else if (t < low - ApproximateComparer.Tolerance) {
                    t = low;
                    numberOfOvershoots++;
                }
                numberOfIteration++;
            } while (Math.Abs(dt) > ApproximateComparer.Tolerance &&!
                (abort = (numberOfIteration >= numberOfIterationsMax || numberOfOvershoots >= numberOfOverShootsMax)));

            //may be the initial value was just fine
            if (abort && (curve[hint] - a).Length < ApproximateComparer.DistanceEpsilon) 
                t = hint;
            
            return t;

           }
Beispiel #10
0
        void ProcessExpandingSearchOnSide(int index, List <KeyValuePair <double, Point> > curvePoints, ICurve curve,
                                          double side, double radius,
                                          double distanceFromCurve, Point wh, ref double coveredLength,
                                          PointSetList placedPoints,
                                          double labelLength)
        {
            foreach (int i in ExpandingSearch(index, 0, curvePoints.Count))
            {
                KeyValuePair <double, Point> p = curvePoints[i];
                Point der = curve.Derivative(p.Key);

                if (der.LengthSquared < ApproximateComparer.DistanceEpsilon)
                {
                    continue;
                }

                Point o        = der.Rotate(Math.PI / 2).Normalize() * side;
                Point labelPos = p.Value + (radius + distanceFromCurve) * o;
                if (!Conflict(labelPos, radius, wh))
                {
                    // found a valid candidate position
                    var ps = new PointSet
                    {
                        Key    = p.Key,
                        Center = labelPos,
                        Inner  = p.Value + distanceFromCurve * o,
                        Outer  = p.Value + (2.0 * radius + distanceFromCurve) * o
                    };
                    coveredLength = i <= index
                                        ? placedPoints.AddFirst(ps)
                                        : placedPoints.AddLast(ps);

                    Debug.Assert(Math.Abs(PointSetLength(placedPoints.Points) - coveredLength) < 0.01);
                    if (coveredLength >= labelLength)
                    {
                        break;
                    }
                }
                else
                {
                    // not going to work!
                    break;
                }
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        public bool PlaceEdgeLabelHorizontally(Label label)
        {
            ValidateArg.IsNotNull(label, "label");
            var e = (Edge)label.GeometryParent;

            // approximate label with a rectangle
            // process candidate points for label ordered by priority
            // check candidate point for conflicts - if none then stop and keep placement
            label.InnerPoints = null;
            List <KeyValuePair <double, Point> > curvePoints = edgePoints[e];
            var wh = new Point(label.Width, label.Height);

            int bestConflictIndex = -1;
            var bestRectangle     = new Rectangle();

            foreach (int index in ExpandingSearch(StartIndex(label, curvePoints), 0, curvePoints.Count))
            {
                KeyValuePair <double, Point> cp = curvePoints[index];

                ICurve curve = e.Curve ?? new LineSegment(e.Source.Center, e.Target.Center);
                Point  der   = curve.Derivative(cp.Key);
                if (der.LengthSquared < ApproximateComparer.DistanceEpsilon)
                {
                    continue;
                }

                foreach (double side in GetPossibleSides(label.Side, der))
                {
                    Rectangle queryRect = GetLabelBounds(cp.Value, der, wh, side);

                    int conflictIndex = ConflictIndex(queryRect, label);
                    if (conflictIndex > bestConflictIndex)
                    {
                        bestConflictIndex = conflictIndex;
                        bestRectangle     = queryRect;

                        // If the best location was found, we're done
                        if (bestConflictIndex == int.MaxValue)
                        {
                            break;
                        }
                    }
                }

                // If the best location was found, we're done
                if (bestConflictIndex == int.MaxValue)
                {
                    break;
                }
            }

            if (bestConflictIndex >= 0)
            {
                SetLabelBounds(label, bestRectangle);

                var r = new RectangleObstacle(bestRectangle);
                AddLabelObstacle(r);

#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371
                if (bestConflictIndex == 0)
                {
                    label.PlacementResult = LabelPlacementResult.OverlapsOtherLabels;
                }
                else if (bestConflictIndex == 1)
                {
                    label.PlacementResult = LabelPlacementResult.OverlapsNodes;
                }
                else if (bestConflictIndex == 2)
                {
                    label.PlacementResult = LabelPlacementResult.OverlapsEdges;
                }
                else
                {
                    label.PlacementResult = LabelPlacementResult.OverlapsNothing;
                }
#else
                label.PlacementResult = (LabelPlacementResult)bestConflictIndex;
#endif
                return(true);
            }

            return(false);
        }
Beispiel #12
0
 internal Point Derivative()
 {
     return(_curve.Derivative(_parameter));
 }
 static bool CurvesAreCloseAtParams(ICurve c0, ICurve c1, double c0S, double c1S) {
     return Close(c0[c0S], c1[c1S]) && Close(c0.Derivative(c0S), c1.Derivative(c1S));
 }
        /// <summary>
        /// Creates a bounding parallelogram on a curve segment
        /// We suppose here that the segment is convex or concave from start to end,
        /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex
        /// </summary>
        internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box,  
            Point startPoint, Point endPoint) {

            if (seg is CubicBezierSegment)
                return CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box);

            Point tan1 = seg.Derivative(start);

            Point tan2 = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);

           

            Point p = endPoint - startPoint;

            double numerator = p * tan2Perp;
            double denumerator = (tan1 * tan2Perp);
            double x;// = (p * tan2Perp) / (tan1 * tan2Perp);
            if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
                x = 0;
            else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon) {
                //it is degenerated; adjacent sides are parallel, but 
                //since p * tan2Perp is big it does not contain e
                return false;
            } else x = numerator / denumerator;

            tan1 *= x;

            box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1);
#if DEBUGCURVES
      if (!box.Contains(seg[end]))
      {
      
        throw new InvalidOperationException();//"the box does not contain the end of the segment");
      }
#endif

            double delta = (end - start) / 64;
            for (int i = 1; i < 64; i++) {
                if (!box.Contains(seg[start + delta * i])) 
                    return false;
               }
            return true;


        }
Beispiel #15
0
 static CurveTangent TangentOnICurve(double p, ICurve iCurve)
 {
     return(new CurveTangent(iCurve[p], iCurve.Derivative(p)));
 }
  static CurveTangent TangentOnICurve(double p, ICurve iCurve) {
     return new CurveTangent(iCurve[p], iCurve.Derivative(p));
 }