internal ObstaclePortEntrance(ObstaclePort oport, Point unpaddedBorderIntersect, Directions outDir, ObstacleTree obstacleTree) {
            ObstaclePort = oport;
            UnpaddedBorderIntersect = unpaddedBorderIntersect;
            OutwardDirection = outDir;

            // Get the padded intersection.
            var lineSeg = new LineSegment(UnpaddedBorderIntersect, StaticGraphUtility.RectangleBorderIntersect(
                                            oport.Obstacle.VisibilityBoundingBox, UnpaddedBorderIntersect, outDir));
            IList<IntersectionInfo> xxs = Curve.GetAllIntersections(lineSeg, oport.Obstacle.VisibilityPolyline, true /*liftIntersections*/);
            Debug.Assert(1 == xxs.Count, "Expected one intersection");
            this.VisibilityBorderIntersect = ApproximateComparer.Round(SpliceUtility.RawIntersection(xxs[0], UnpaddedBorderIntersect));

            this.MaxVisibilitySegment = obstacleTree.CreateMaxVisibilitySegment(this.VisibilityBorderIntersect,
                    this.OutwardDirection, out this.pointAndCrossingsList);

            // Groups are never in a clump (overlapped) but they may still have their port entrance overlapped.
            if (this.Obstacle.IsOverlapped || (this.Obstacle.IsGroup && !this.Obstacle.IsInConvexHull)) {
                this.IsOverlapped = obstacleTree.IntersectionIsInsideAnotherObstacle(/*sideObstacle:*/ null, this.Obstacle
                        , this.VisibilityBorderIntersect, ScanDirection.GetInstance(OutwardDirection));
                if (!this.Obstacle.IsGroup || this.IsOverlapped || this.InteriorEdgeCrossesObstacle(obstacleTree)) {
                    unpaddedToPaddedBorderWeight = ScanSegment.OverlappedWeight;
                }
            }
            if (this.Obstacle.IsInConvexHull && (unpaddedToPaddedBorderWeight == ScanSegment.NormalWeight)) {
                SetUnpaddedToPaddedBorderWeightFromHullSiblingOverlaps(obstacleTree);
            }
        }
        internal static ParallelogramNodeOverICurve CreateParallelogramNodeForCurveSeg(double start, double end,
                                                                                       Ellipse seg, double eps){
            bool closedSeg = (start == seg.ParStart && end == seg.ParEnd && ApproximateComparer.Close(seg.Start, seg.End));
            if(closedSeg)
                return CreateNodeWithSegmentSplit(start, end, seg, eps);

            Point s = seg[start];
            Point e = seg[end];
            Point w = e - s;
            Point middle = seg[(start + end) / 2];
           
            if (ParallelogramNodeOverICurve.DistToSegm(middle, s, e) <= ApproximateComparer.IntersectionEpsilon &&
                w * w < Curve.LineSegmentThreshold * Curve.LineSegmentThreshold && end - start < Curve.LineSegmentThreshold) {
                var ls = new LineSegment(s, e);
                var leaf = ls.ParallelogramNodeOverICurve as ParallelogramLeaf;
                leaf.Low = start;
                leaf.High = end;
                leaf.Seg = seg;
                leaf.Chord = ls;
                return leaf;
            }

            bool we = WithinEpsilon(seg, start, end, eps);
            var box = new Parallelogram();

            if(we && CreateParallelogramOnSubSeg(start, end, seg, ref box)){
                return new ParallelogramLeaf(start, end, box, seg, eps);
            } else{
                return CreateNodeWithSegmentSplit(start, end, seg, eps);
            }
        }
 protected string LineSegmentString(LineSegment ls)
 {
     return("L " + PointToString(ls.End));
 }
        private void CreateObstaclePortEntrancesFromPoints(ObstaclePort oport) {
            var graphBox = graphGenerator.ObstacleTree.GraphBox;
            var curveBox = new Rectangle(ApproximateComparer.Round(oport.PortCurve.BoundingBox.LeftBottom)
                                             , ApproximateComparer.Round(oport.PortCurve.BoundingBox.RightTop));

            // This Port does not have a PortEntry, so we'll have visibility edges to its location
            // in the Horizontal and Vertical directions (possibly all 4 directions, if not on boundary).
            //
            // First calculate the intersection with the obstacle in all directions.  Do nothing in the
            // horizontal direction for port locations that are on the unpadded vertical extremes, because
            // this will have a path that moves alongside a rectilinear obstacle side in less than the
            // padding radius and will thus create the PaddedBorderIntersection on the side rather than top
            // (and vice-versa for the vertical direction).  We'll have an edge in the vertical direction
            // to the padded extreme boundary ScanSegment, and the Nudger will modify paths as appropriate
            // to remove unnecessary bends.
            
            // Use the unrounded port location to intersect with its curve.
            Point location = ApproximateComparer.Round(oport.PortLocation);
            Point xx0, xx1;
            bool found = false;
            if (!PointComparer.Equal(location.Y, curveBox.Top)
                    && !PointComparer.Equal(location.Y, curveBox.Bottom)) {
                found = true;
                var hSeg = new LineSegment(graphBox.Left, location.Y, graphBox.Right, location.Y);
                GetBorderIntersections(location, hSeg, oport.PortCurve, out xx0, out xx1);
                var wBorderIntersect = new Point(Math.Min(xx0.X, xx1.X), location.Y);
                if (wBorderIntersect.X < curveBox.Left) {        // Handle rounding error
                    wBorderIntersect.X = curveBox.Left;
                }
                var eBorderIntersect = new Point(Math.Max(xx0.X, xx1.X), location.Y);
                if (eBorderIntersect.X > curveBox.Right) {
                    eBorderIntersect.X = curveBox.Right;
                }
                CreatePortEntrancesAtBorderIntersections(curveBox, oport, location, wBorderIntersect, eBorderIntersect);
            } // endif horizontal pass is not at vertical extreme

            if (!PointComparer.Equal(location.X, curveBox.Left)
                    && !PointComparer.Equal(location.X, curveBox.Right)) {
                found = true;
                var vSeg = new LineSegment(location.X, graphBox.Bottom, location.X, graphBox.Top);
                GetBorderIntersections(location, vSeg, oport.PortCurve, out xx0, out xx1);
                var sBorderIntersect = new Point(location.X, Math.Min(xx0.Y, xx1.Y));
                if (sBorderIntersect.Y < graphBox.Bottom) {      // Handle rounding error
                    sBorderIntersect.Y = graphBox.Bottom;
                }
                var nBorderIntersect = new Point(location.X, Math.Max(xx0.Y, xx1.Y));
                if (nBorderIntersect.Y > graphBox.Top) {
                    nBorderIntersect.Y = graphBox.Top;
                }
                CreatePortEntrancesAtBorderIntersections(curveBox, oport, location, sBorderIntersect, nBorderIntersect);
            } // endif vertical pass is not at horizontal extreme

            if (!found) {
                // This must be on a corner, else one of the above would have matched.
                this.CreateEntrancesForCornerPort(curveBox, oport, location);
            }
        }
 bool IntersectObstacleHierarchy(LineSegment ls) {
     return
         HierarchyOfObstacles.GetAllIntersecting(ls.BoundingBox).Any(
             poly => Curve.CurveCurveIntersectionOne(ls, poly, false) != null);
 }
        private void ShowInputSegments(List<SymmetricTuple<int>> badSegs, Point[] indexToPoints) {
#if TEST_MSAGL
            var l = new List<DebugCurve>();
            foreach (var seg in _segments) {
                var p1 = indexToPoints[seg.A];
                var p2 = indexToPoints[seg.B];
                var ls = new LineSegment(p1, p2);

                string color = badSegs.Contains(seg) ? "red" : "black";
                double width = badSegs.Contains(seg) ? 3 : 1;
                l.Add(new DebugCurve(100, width, color, ls));
            }
            //foreach (var p in indexToPoints)
            //{
            //    l.Add(new DebugCurve(200, 0.1, "black", CurveFactory.CreateCircle(0.1, p)));
            //}
            LayoutAlgorithmSettings.ShowDebugCurves(l.ToArray());
#endif
        }
        static bool LineIntersectsRectangleNode(LineSegment ls, RectangleNode<Polyline> rectNode) {
            if (!ls.BoundingBox.Intersects(rectNode.Rectangle))
                return false;
            if (rectNode.UserData != null) {
                // SugiyamaLayoutSettings.Show(ls, rectNode.UserData);
                return Curve.GetAllIntersections(rectNode.UserData, ls, false).Count > 0;
            }


            return LineIntersectsRectangleNode(ls, rectNode.Left) || LineIntersectsRectangleNode(ls, rectNode.Right);
        }
 void GetXCoordinatesOfVirtualNodesOfTheProperLayeredGraphForSkeletonEdge(IntEdge intEdge, LayerArrays layerArrays) {
     if (intEdge.LayerEdges == null || intEdge.LayerEdges.Count < 2) return;
     var edgeCurve = intEdge.Edge.Curve;
     var layerIndex = layerArrays.Y[intEdge.Source] - 1;//it is the layer of the highest virtual node of the edge
     for (int i = 1; i < intEdge.LayerEdges.Count; i++) {
         var v = intEdge.LayerEdges[i].Source;
         var layerY = layerToRecoveredYCoordinates[layerIndex--];
         var layerLine = new LineSegment(new Point(originalGraph.Left, layerY), new Point(originalGraph.Right, layerY));
         var intersection=Curve.CurveCurveIntersectionOne(edgeCurve, layerLine, false);
        
         skeletonVirtualVerticesToX[v] =intersection.IntersectionPoint.X;
         
     }
 }
        void ParallelLineSegLineSegMinDist()
        {
            LineSegment l0 = curveA as LineSegment;
            LineSegment l1 = curveB as LineSegment;

            Point v0 = l0.Start;
            Point v1 = l0.End;
            Point v2 = l1.Start;
            Point v3 = l1.End;

            Point d0 = v1 - v0;

            double nd0 = d0.Length;

            double r0 = 0, r1, r2, r3;

            if (nd0 > ApproximateComparer.DistanceEpsilon)
            {
                //v0 becomes the zero point
                d0 /= nd0;
                r1  = d0 * (v1 - v0);
                r2  = d0 * (v2 - v0);
                r3  = d0 * (v3 - v0);

                bool swapped = false;
                if (r2 > r3)
                {
                    swapped = true;
                    double t = r2;
                    r2 = r3;
                    r3 = t;
                }

                if (r3 < r0)
                {
                    aSolution = 0;
                    bSolution = swapped ? 0 : 1;
                }
                else if (r2 > r1)
                {
                    aSolution = 1;
                    bSolution = swapped ? 1 : 0;
                }
                else
                {
                    double r = Math.Min(r1, r3);
                    aSolution = r / (r1 - r0);
                    bSolution = (r - r2) / (r3 - r2);
                    if (swapped)
                    {
                        bSolution = 1 - bSolution;
                    }
                }
            }
            else
            {
                Point  d1  = v3 - v2;
                double nd1 = d1.Length;
                if (nd1 > ApproximateComparer.DistanceEpsilon)
                {
                    //v2 becomes the zero point
                    d1 /= nd1;
                    r0  = 0;              //v2 position
                    r1  = d1 * (v3 - v2); //v3 position
                    r2  = d1 * (v0 - v2); //v0 position - here v0 and v1 are indistinguishable


                    if (r2 < r0)
                    {
                        bSolution = 0;
                        aSolution = 1;
                    }
                    else if (r2 > r1)
                    {
                        bSolution = 1;
                        aSolution = 0;
                    }
                    else
                    {
                        double r = Math.Min(r1, r2);
                        bSolution = r / (r1 - r0);
                        aSolution = 0;
                    }
                }
                else
                {
                    aSolution = 0;
                    bSolution = 0;
                }
            }
            aPoint = curveA[aSolution];
            bPoint = curveB[bSolution];
        }
 public static bool SegmentsIntersect(Point p1, Point p2, Point q1, Point q2)
 {
     var seg1 = new LineSegment(p1, p2);
     var seg2 = new LineSegment(q1, q2);
     var allInt = Curve.GetAllIntersections(seg1, seg2, false);
     return allInt.Any();
 }
        internal static ICurve CreateBaseSegmentForDraggingEdgeWithSource(Point delta, GeomEdge edge,
            EdgeRestoreData edgeRestoreData,
            Dictionary<GeomEdge, double> offsets) {
            double offset;
            ICurve seg;
            Point a = edgeRestoreData.UnderlyingPolyline.HeadSite.Point + delta;
            Point b = edgeRestoreData.UnderlyingPolyline.LastSite.Point;
            if (offsets.TryGetValue(edge, out offset) && offset != 0) {
                Point ab = b - a;
                Point abOrtog = ab.Normalize().Rotate(Math.PI/2)*offset;
                seg = CreateBaseSegOnSourceTargetAndOrth(ref a, ref b, ref abOrtog);
                //        SugiyamaLayoutSettings.Show(seg, edge.Curve, edge.Source.BoundaryCurve);
            }
            else
                seg = new LineSegment(a, b);

            return seg;
        }
 DebugCurve DebugSweepLine(RealNumberSpan range) {
     var ls = new LineSegment(Z * SweepDirection + DirectionPerp * range.Min, Z * SweepDirection + DirectionPerp * range.Max);
     return new DebugCurve(100,0.1,"magenta", ls);
 }
        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();
        }
 static void AdjustParameters(ParallelogramLeaf l0, LineSegment ls0, ParallelogramLeaf l1, LineSegment ls1,
     Point x, ref double asol, ref double bsol) {
     if (ls0 != l0.Seg && l0.Seg is Polyline == false) //l0.Seg is not a LineSegment and not a polyline
         asol = l0.Seg.ClosestParameter(x); //we need to find the correct parameter
     else
         asol = l0.Low + asol*(l0.High - l0.Low);
     if (ls1 != l1.Seg && l1.Seg is Polyline == false) //l1.Seg is not a LineSegment and not a polyline
         bsol = l1.Seg.ClosestParameter(x); //we need to find the correct parameter
     else
         bsol = l1.Low + bsol*(l1.High - l1.Low);
 }
        static IList<IntersectionInfo> GetAllIntersectionsOfLineAndPolyline(LineSegment lineSeg, Polyline poly) {
            var ret = new List<IntersectionInfo>();
            double offset = 0.0;
            double par0, par1;
            Point x;
            PolylinePoint polyPoint = poly.StartPoint;
            for (; polyPoint != null && polyPoint.Next != null; polyPoint = polyPoint.Next) {
                if (CrossTwoLineSegs(lineSeg.Start, lineSeg.End, polyPoint.Point, polyPoint.Next.Point, 0, 1, 0, 1,
                                     out par0, out par1, out x)) {
                    AdjustSolution(lineSeg.Start, lineSeg.End, polyPoint.Point, polyPoint.Next.Point, ref par0, ref par1,
                                   ref x);
                    if (!OldIntersection(ret, ref x))
                        ret.Add(new IntersectionInfo(par0, offset + par1, x, lineSeg, poly));
                }
                offset++;
            }
            if (poly.Closed)
                if (CrossTwoLineSegs(lineSeg.Start, lineSeg.End, polyPoint.Point, poly.Start, 0, 1, 0, 1, out par0,
                                     out par1, out x)) {
                    AdjustSolution(lineSeg.Start, lineSeg.End, polyPoint.Point, poly.Start, ref par0, ref par1, ref x);
                    if (!OldIntersection(ret, ref x))
                        ret.Add(new IntersectionInfo(par0, offset + par1, x, lineSeg, poly));
                }

            return ret;
        }
 void WriteLineSeg(LineSegment ls) {
     WriteStartElement(GeometryToken.LineSegment);
     WriteAttribute(GeometryToken.Points, PointsToString(ls.Start, ls.End));
     WriteEndElement();
 }
        static void TryToAddPointToLineCircleCrossing(LineSegment lineSeg,
            Ellipse ellipse, List<IntersectionInfo> ret, Point point, double segLength, Point lineDir) {
            Point ds = point - lineSeg.Start;
            Point de = point - lineSeg.End;
            double t = ds*lineDir;
            if (t < -ApproximateComparer.DistanceEpsilon)
                return;
            t = Math.Max(t, 0);
            if (t > segLength + ApproximateComparer.DistanceEpsilon)
                return;
            t = Math.Min(t, segLength);
            t /= segLength;

            double angle = Point.Angle(ellipse.AxisA, point - ellipse.Center);
            if (ellipse.ParStart - ApproximateComparer.Tolerance <= angle) {
                angle = Math.Max(angle, ellipse.ParStart);
                if (angle <= ellipse.ParEnd + ApproximateComparer.Tolerance) {
                    angle = Math.Min(ellipse.ParEnd, angle);
                    ret.Add(new IntersectionInfo(t, angle, point, lineSeg, ellipse));
                }
            }
        }
        public void GetPossibleSides()
        {
            for (double angle = 0; angle < 2 * Math.PI; angle += Math.PI / 4)
            {
                double lineLength = 10;
                Point targetPoint = new Point(lineLength * Math.Sin(angle), lineLength * Math.Cos(angle));
                LineSegment line = new LineSegment(new Point(0, 0), targetPoint);

                Point derivative = line.Derivative(0.5);

                double[] topSides = GetPossibleSides(Label.PlacementSide.Top, derivative).ToArray();
                Assert.AreEqual(1, topSides.Length, "Top placement side should have 1 resulting possible side");
                Point searchDir = GetSearchDirection(derivative, topSides[0]);
                Assert.IsTrue(searchDir.Y <= 0, "Top placement side should result in a Y negative search");

                double[] bottomSides = GetPossibleSides(Label.PlacementSide.Bottom, derivative).ToArray();
                Assert.AreEqual(1, bottomSides.Length, "Bottom placement side should have 1 resulting possible side");
                searchDir = GetSearchDirection(derivative, bottomSides[0]);
                Assert.IsTrue(searchDir.Y >= 0, "Bottom placement side should result in a Y positive search");

                double[] leftSides = GetPossibleSides(Label.PlacementSide.Left, derivative).ToArray();
                Assert.AreEqual(1, leftSides.Length, "Left placement side should have 1 resulting possible side");
                searchDir = GetSearchDirection(derivative, leftSides[0]);
                Assert.IsTrue(searchDir.X <= 0, "Left placement side should result in a X negative search");
                
                double[] rightSides = GetPossibleSides(Label.PlacementSide.Right, derivative).ToArray();
                Assert.AreEqual(1, rightSides.Length, "Right placement side should have 1 resulting possible side");
                searchDir = GetSearchDirection(derivative, rightSides[0]);
                Assert.IsTrue(searchDir.X >= 0, "Right placement side should result in a X positive search");

                double[] portSide = GetPossibleSides(Label.PlacementSide.Port, derivative).ToArray();
                Assert.AreEqual(1, portSide.Length, "Port placement side should have 1 resulting possible side");
                Assert.AreEqual(-1, portSide[0], "Port placement side should be -1");

                double[] starboardSide = GetPossibleSides(Label.PlacementSide.Starboard, derivative).ToArray();
                Assert.AreEqual(1, starboardSide.Length, "Starboard placement side should have 1 resulting possible side");
                Assert.AreEqual(1, starboardSide[0], "Starboard placement side should be 1");

                double[] anySide = GetPossibleSides(Label.PlacementSide.Any, derivative).ToArray();
                Assert.AreEqual(2, anySide.Length, "Any placement side should have 2 resulting possible sides");
                Assert.AreEqual(-1, anySide[0], "Any placement side should start with -1");
                Assert.AreEqual(1, anySide[1], "Any placement side should end with 1");
            }
        }
 bool LineIntersectsTightObstacles(LineSegment ls) {
     return LineIntersectsRectangleNode(ls, obstacleCalculator.RootOfTightHierararchy);
 }
        private static bool CurveIntersectsHierarchy(LineSegment lineSeg, ParallelogramNode hierarchy) {
            if (hierarchy == null)
                return false;
            if (!Parallelogram.Intersect(lineSeg.ParallelogramNodeOverICurve.Parallelogram, hierarchy.Parallelogram))
                return false;

            ParallelogramBinaryTreeNode n = hierarchy as ParallelogramBinaryTreeNode;
            if (n != null)
                return CurveIntersectsHierarchy(lineSeg, n.LeftSon) || CurveIntersectsHierarchy(lineSeg, n.RightSon);

            return Curve.GetAllIntersections(lineSeg, ((ParallelogramNodeOverICurve)hierarchy).Seg, false).Count > 0;


        }
 LineSegment TryRouteStraightLine() {
     var ls = new LineSegment(SourcePoint, TargetPoint);
     if (obstacleCalculator.ObstaclesIntersectICurve(ls))
         return null;
     return ls;
 }
 static internal bool IntervalsOverlap(LineSegment first, LineSegment second) {
     return IntervalsOverlap(first.Start, first.End, second.Start, second.End);
 }
 /// <summary>
 /// ignoring crossing at ls.Start
 /// </summary>
 /// <param name="ls"></param>
 /// <param name="rTree"></param>
 /// <param name="segsToIgnore"></param>
 /// <returns></returns>
 static bool IsCrossing(LineSegment ls, RTree<SegWithIndex> rTree, SegWithIndex[] segsToIgnore) {
     return rTree.GetAllIntersecting(ls.BoundingBox).Where(seg => !segsToIgnore.Contains(seg)).Any();
 }
 static internal bool PointIsOnSegmentInterior(LineSegment seg, Point test) {
     return PointIsOnSegmentInterior(seg.Start, seg.End, test);
 }
        /// <summary>
        /// Returns a line segment for the given edge.
        /// </summary>
        /// <returns>The line segment representing the given edge.</returns>
        public static LineSegment GetEdgeLine(Edge edge)
        {
            ValidateArg.IsNotNull(edge, "edge");
            Point sourcePoint;
            ICurve sourceBox;
            if (edge.SourcePort == null)
            {
                sourcePoint = edge.Source.Center;
                sourceBox = edge.Source.BoundaryCurve;
            }
            else
            {
                sourcePoint = edge.SourcePort.Location;
                sourceBox = edge.SourcePort.Curve;
            }
            Point targetPoint;
            ICurve targetBox;
            if (edge.TargetPort == null)
            {
                targetPoint = edge.Target.Center;
                targetBox = edge.Target.BoundaryCurve;
            }
            else
            {
                targetPoint = edge.TargetPort.Location;
                targetBox = edge.TargetPort.Curve;
            }
            LineSegment line = new LineSegment(sourcePoint, targetPoint);
            IList<IntersectionInfo> intersects = Curve.GetAllIntersections(sourceBox, line, false);

            if (intersects.Count > 0)
            {
                var trimmedLine = (LineSegment)line.Trim(intersects[0].Par1, 1.0);
                if(trimmedLine != null)
                {
                    line = trimmedLine;
                    intersects = Curve.GetAllIntersections(targetBox, line, false);
                    if (intersects.Count > 0)
                    {
                        trimmedLine = (LineSegment)line.Trim(0.0, intersects[0].Par1);
                        if(trimmedLine != null)
                        {
                            line = trimmedLine;
                        }
                    }
                }
            }

            return line;
        }
 static internal bool IsVertical(LineSegment seg) {
     return IsVertical(PointComparer.GetPureDirection(seg.Start, seg.End));
 }
 private void GetBorderIntersections(Point location, LineSegment lineSeg, ICurve curve
                             , out Point xx0, out Point xx1) {
     // Important:  the LineSegment must be the first arg to GetAllIntersections so RawIntersection works.
     IList<IntersectionInfo> xxs = Curve.GetAllIntersections(lineSeg, curve, true /*liftIntersections*/);
     StaticGraphUtility.Assert(2 == xxs.Count, "Expected two intersections", this.ObstacleTree, this.VisGraph);
     xx0 = SpliceUtility.RawIntersection(xxs[0], location);
     xx1 = SpliceUtility.RawIntersection(xxs[1], location);
 }
 static internal bool SegmentsIntersect(LineSegment first, LineSegment second, out Point intersect) {
     return IntervalsIntersect(first.Start, first.End, second.Start, second.End, out intersect);
 }
 string LineSegmentString(LineSegment ls)
 {
     return "L " + PointToString(ls.End);
 }
 public Rail CreateRail(Point ep0, Point ep1) {
     var st = new SymmetricSegment(ep0, ep1);
     Rail rail;
     if (RailDictionary.TryGetValue(st, out rail)) {
         return rail;
     }
     var ls = new LineSegment(ep0, ep1);
     rail = new Rail(ls, ZoomLevel);
     RailTree.Add(rail.BoundingBox, rail);
     RailDictionary.Add(st, rail);
     return rail;
 }
 string LineSegmentString(LineSegment ls, char previousInstruction) {
     var str= PointToString(ls.End);
     return previousInstruction == 'L' ? str : "L" + str;
 }
 EdgeGeometry CalculateEdgeInteractively(Port targetPortParameter,Polyline portLoosePolyline) {
     if(InteractiveEdgeRouter.SourcePort == null)
         InteractiveEdgeRouter.SetSourcePortAndSourceLoosePolyline(SourcePort,sourceLoosePolyline);
     ICurve curve;
     SmoothedPolyline smoothedPolyline = null;
     if(SourceOfInsertedEdge == TargetOfInsertedEdge) {
         curve = new LineSegment(SourcePort.Location,TargetPort.Location);
     } else {
         curve = InteractiveEdgeRouter.RouteEdgeToPort(targetPortParameter,portLoosePolyline,false,
                                                       out smoothedPolyline);
     }
     return new EdgeGeometry { Curve = curve,SmoothedPolyline = smoothedPolyline };
 }
 string LineSegmentString(LineSegment ls)
 {
     return "L " + PointToString(ls.End);
 }
Example #34
0
        private static void UpdateConnectors(GeometryGraph graph)
        {
            foreach (Edge edge in graph.Edges)
            {
                BinaryLinkShape linkShape = (BinaryLinkShape)edge.UserData;

                // need to mark the connector as dirty. this is the easiest way to do this
                linkShape.ManuallyRouted = !linkShape.ManuallyRouted;
                linkShape.FixedFrom      = VGFixedCode.NotFixed;
                linkShape.FixedTo        = VGFixedCode.NotFixed;

                // make the labels follow the lines
                foreach (LineLabelShape lineLabelShape in linkShape.RelativeChildShapes.OfType <LineLabelShape>())
                {
                    lineLabelShape.ManuallySized  = false;
                    lineLabelShape.ManuallyPlaced = false;
                }

                linkShape.EdgePoints.Clear();

                // MSAGL deals in line segments; DSL deals in points
                // with the segments, tne end of one == the beginning of the next, so we can use just the beginning point
                // of each segment.
                // But we have to hang on to the end point so that, when we hit the last segment, we can finish off the
                // set of points
                if (edge.Curve is LineSegment lineSegment)
                {
                    // When curve is a single line segment.
                    linkShape.EdgePoints.Add(new EdgePoint(lineSegment.Start.X, lineSegment.Start.Y, VGPointType.Normal));
                    linkShape.EdgePoints.Add(new EdgePoint(lineSegment.End.X, lineSegment.End.Y, VGPointType.Normal));
                }
                else if (edge.Curve is Curve curve)
                {
                    //// When curve is a complex segment.
                    EdgePoint lastPoint = null;

                    foreach (ICurve segment in curve.Segments)
                    {
                        switch (segment.GetType().Name)
                        {
                        case "LineSegment":
                            LineSegment line = segment as LineSegment;
                            linkShape.EdgePoints.Add(new EdgePoint(line.Start.X, line.Start.Y, VGPointType.Normal));
                            lastPoint = new EdgePoint(line.End.X, line.End.Y, VGPointType.Normal);

                            break;

                        case "CubicBezierSegment":
                            CubicBezierSegment bezier = segment as CubicBezierSegment;

                            // there are 4 segments. Store all but the last one
                            linkShape.EdgePoints.Add(new EdgePoint(bezier.B(0).X, bezier.B(0).Y, VGPointType.Normal));
                            linkShape.EdgePoints.Add(new EdgePoint(bezier.B(1).X, bezier.B(1).Y, VGPointType.Normal));
                            linkShape.EdgePoints.Add(new EdgePoint(bezier.B(2).X, bezier.B(2).Y, VGPointType.Normal));
                            lastPoint = new EdgePoint(bezier.B(3).X, bezier.B(3).Y, VGPointType.Normal);

                            break;

                        case "Ellipse":
                            // rather than draw a curved line, we'll bust the curve into 5 parts and draw those as straight lines
                            Ellipse ellipse  = segment as Ellipse;
                            double  interval = (ellipse.ParEnd - ellipse.ParStart) / 5.0;
                            lastPoint = null;

                            for (double i = ellipse.ParStart; i <= ellipse.ParEnd; i += interval)
                            {
                                Point p = ellipse.Center
                                          + (Math.Cos(i) * ellipse.AxisA)
                                          + (Math.Sin(i) * ellipse.AxisB);

                                // we'll remember the one we just calculated, but store away the one we calculated last time around
                                // (if there _was_ a last time around). That way, when we're done, we'll have stored all of them except
                                // for the last one
                                if (lastPoint != null)
                                {
                                    linkShape.EdgePoints.Add(lastPoint);
                                }

                                lastPoint = new EdgePoint(p.X, p.Y, VGPointType.Normal);
                            }

                            break;
                        }
                    }

                    // finally tuck away the last one. Now we don't have duplicate points in our list
                    if (lastPoint != null)
                    {
                        linkShape.EdgePoints.Add(lastPoint);
                    }
                }

                // since we're not changing the nodes this edge connects, this really doesn't do much.
                // what it DOES do, however, is call ConnectEdgeToNodes, which is an internal method we'd otherwise
                // be unable to access
                linkShape.Connect(linkShape.FromShape, linkShape.ToShape);
                linkShape.ManuallyRouted = false;
            }
        }