/// <summary> /// checks if an edge intersects obstacles /// otherwise it calulates distances to the closest obstacles /// </summary> internal bool EdgeIsLegal(Station v, Station u, Point vPosition, Point uPosition, Set <Polyline> obstaclesToIgnore) { var start = v.Position; CdtTriangle currentTriangle = v.CdtTriangle; Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle)); Point end = u.Position; if (Cdt.PointIsInsideOfTriangle(end, currentTriangle)) { return(true); } var threader = new CdtThreader(currentTriangle, start, end); while (threader.MoveNext()) { var piercedEdge = threader.CurrentPiercedEdge; if (piercedEdge.Constrained) { Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner); var poly = (Polyline)piercedEdge.lowerSite.Owner; if (!obstaclesToIgnore.Contains(poly)) { return(false); } } } return(true); }
/// <summary> /// /// </summary> public static void Test() { #if DEBUG && !SHARPKIT int count = 100; var random = new Random(3); var points = new List <Point>(); for (int i = 0; i < count; i++) { points.Add(20 * new Point(random.NextDouble(), random.NextDouble())); } var cdt = new Cdt(points, null, null); cdt.Run(); var ret = GetMstOnCdt(cdt, e => (e.lowerSite.Point - e.upperSite.Point).Length); var l = new List <DebugCurve>(); foreach (var s in cdt.PointsToSites.Values) { foreach (var e in s.Edges) { l.Add(new DebugCurve(100, 0.1, "black", new LineSegment(e.lowerSite.Point, e.upperSite.Point))); } } foreach (var e in ret) { l.Add(new DebugCurve(100, 0.12, "red", new LineSegment(e.lowerSite.Point, e.upperSite.Point))); } LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l); #endif }
internal MetroGraphData(EdgeGeometry[] regularEdges, RectangleNode <Polyline> looseTree, RectangleNode <Polyline> tightTree, BundlingSettings bundlingSettings, Cdt cdt, Dictionary <EdgeGeometry, Set <Polyline> > edgeLooseEnterable, Dictionary <EdgeGeometry, Set <Polyline> > edgeTightEnterable, Func <Port, Polyline> loosePolylineOfPort) { //Debug.Assert(cdt != null); this.regularEdges = regularEdges; if (cdt != null) { Cdt = cdt; } else { Cdt = BundleRouter.CreateConstrainedDelaunayTriangulation(looseTree); } EdgeLooseEnterable = edgeLooseEnterable; EdgeTightEnterable = edgeTightEnterable; LoosePolylineOfPort = loosePolylineOfPort; looseIntersections = new Intersections(this, bundlingSettings, looseTree, station => station.EnterableLoosePolylines); tightIntersections = new Intersections(this, bundlingSettings, tightTree, station => station.EnterableTightPolylines); cdtIntersections = new CdtIntersections(this, bundlingSettings); Initialize(false); }
static Cdt GetConstrainedDelaunayTriangulation(IEnumerable <Polyline> obstacles) { var constrainedDelaunayTriangulation = new Cdt(null, obstacles, null); constrainedDelaunayTriangulation.Run(); return(constrainedDelaunayTriangulation); }
void RestoreCapacities() { if (Cdt != null) { Cdt.RestoreEdgeCapacities(); } }
private CdtEdge FindEdge(PolylinePoint a, PolylinePoint b, Cdt cdt) { int aIsAboveB = Cdt.Above(a.Point, b.Point); System.Diagnostics.Debug.Assert(aIsAboveB != 0); if (aIsAboveB > 0) { foreach (var e in cdt.FindSite(a.Point).Edges) { if (e.lowerSite.Point == b.Point) { return(e); } } } else { foreach (var e in cdt.FindSite(b.Point).Edges) { if (e.lowerSite.Point == a.Point) { return(e); } } } throw new InvalidOperationException("cannot find an edge of a polyline in the tessellation"); }
public IntersectionCache(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, CostCalculator costCalculator, Cdt cdt) { Debug.Assert(cdt != null); this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; this.costCalculator = costCalculator; this.cdt = cdt; }
private void CleanUpTriangles(Shape shape, ref Set <CdtTriangle> triangles, Cdt cdt) { CleanUpExternalTriangles(shape, ref triangles, cdt); foreach (var sh in shape.Children) { CleanUpInternalTriangles(sh, ref triangles, cdt); } }
public void SmallTriangulation() { #if TEST_MSAGL && TEST_MSAGL GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions(); #endif var cdt = new Cdt(Points(), null, new [] { new SymmetricTuple <Point>(new Point(109, 202), new Point(506, 135)), new SymmetricTuple <Point>(new Point(139, 96), new Point(452, 96)) }.ToList()); cdt.Run(); }
/// <summary> /// returns false iff the edge overlap an obstacle /// </summary> bool ThreadLineSegmentThroughTriangles(CdtTriangle currentTriangle, Point start, Point end, Set <Polyline> obstaclesToIgnore, out List <CdtTriangle> triangles) { Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle)); triangles = new List <CdtTriangle>(); if (Cdt.PointIsInsideOfTriangle(end, currentTriangle)) { triangles.Add(currentTriangle); return(true); } var threader = new CdtThreader(currentTriangle, start, end); triangles.Add(currentTriangle); while (threader.MoveNext()) { triangles.Add(threader.CurrentTriangle); var piercedEdge = threader.CurrentPiercedEdge; if (piercedEdge.Constrained) { Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner); var poly = (Polyline)piercedEdge.lowerSite.Owner; if (!obstaclesToIgnore.Contains(poly)) { return(false); } } } if (threader.CurrentTriangle != null) { triangles.Add(threader.CurrentTriangle); } // // int positiveSign, negativeSign; // CdtEdge piercedEdge = FindFirstPiercedEdge(currentTriangle, start, end, out negativeSign, out positiveSign, null); // // Debug.Assert(positiveSign > negativeSign); // // Debug.Assert(piercedEdge != null); // // do { // triangles.Add(currentTriangle); // if (piercedEdge.Constrained) { // Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner); // Polyline poly = (Polyline)piercedEdge.lowerSite.Owner; // if (!obstaclesToIgnore.Contains(poly)) return false; // } // } // while (FindNextPierced(start, end, ref currentTriangle, ref piercedEdge, ref negativeSign, ref positiveSign)); // if (currentTriangle != null) // triangles.Add(currentTriangle); return(true); }
private static void GetProximityRelations(GeometryGraph graphOriginal, out HashSet <Tuple <int, int> > proximityEdges, out HashSet <Tuple <int, int, int> > proximityTriangles) { // triangulation needed for statistics Cdt cdt = new Cdt(graphOriginal.Nodes.Select((v, index) => new Tuple <Point, object>( v.Center, (object)(index)))); cdt.Run(); proximityTriangles = GetProximityTriangles(cdt); proximityEdges = GetProximityEdges(cdt); }
void Triangulate(int n, double size) { var random = new Random(n); var w = n * size; var cdt = new Cdt(PointsForCdt(random, n, w), null, SegmentsForCdt(w).ToList()); cdt.Run(); #if TEST_MSAGL && TEST_MSAGL CdtSweeper.ShowFront(cdt.GetTriangles(), null, null, null); #endif }
static void TestTriangulationOnPolys() { FileStream stream = File.Open("polys", FileMode.Open); var bformatter = new BinaryFormatter(); var polys = (Polyline[])bformatter.Deserialize(stream); stream.Close(); var cdt = new Cdt(null, polys, null); cdt.Run(); }
void TryToAssigenTriangleToVertex(CdtTriangle triangle, SdVertex vertex) { if (vertex.Triangle != null) { return; } if (Cdt.PointIsInsideOfTriangle(vertex.Point, triangle)) { vertex.Triangle = triangle; } }
public void TestRepeatedSite() { //in this method the triangulation is such that a repeated site appears in EdgeEvent var stream = File.Open("polys", FileMode.Open); var bformatter = new BinaryFormatter(); var polys = (Polyline[])bformatter.Deserialize(stream); stream.Close(); var cdt = new Cdt(null, polys, null); cdt.Run(); TestTriangles(cdt.GetTriangles()); }
bool DoSingleIteration(int currentIteration, ref bool scanlinePhase) { List <Tuple <Point, object> > sites = nodePositions.Select((p, index) => new Tuple <Point, object>(p, index)).ToList(); var triangulation = new Cdt(sites); triangulation.Run(); List <Tuple <int, int, double, double> > proximityEdgesWithDistance; int numCrossings = GetProximityEdgesWithDistance(Graph, triangulation, nodeSizes, out proximityEdgesWithDistance); if (scanlinePhase || numCrossings == 0) { scanlinePhase = true; numCrossings = CompleteProximityGraphWithRTree(ref numCrossings, proximityEdgesWithDistance); } #if DEBUG int realCrossings = CountCrossingsWithRTree(nodeSizes); crossingsOverTime.Add(realCrossings); if (currentIteration % 10 == 0) { Console.WriteLine("Scanline: {0}, Crossings: {1}", scanlinePhase, numCrossings); } #endif if (numCrossings == 0) { return(true); } AddStressFromProximityEdges(StressSolver, proximityEdgesWithDistance); List <Point> newPositions = StressSolver.IterateAll(); ShowCurrentMovementVectors(currentIteration, nodeSizes, nodePositions, newPositions, proximityEdgesWithDistance, null); UpdatePointsAndBoxes(newPositions); //clear the data structures StressSolver.ClearVotings(); #if DEBUG for (int i = 0; i < nodePositions.Length; i++) { trajectories[i].AddPoint(newPositions[i]); } #endif return(false); }
private static HashSet <Tuple <int, int, int> > GetProximityTriangles(Cdt cdt) { HashSet <Tuple <int, int, int> > proxTriangles = new HashSet <Tuple <int, int, int> >(); foreach (var triangle in cdt.GetTriangles()) { int a = (int)triangle.Sites[0].Owner; int b = (int)triangle.Sites[1].Owner; int c = (int)triangle.Sites[2].Owner; proxTriangles.Add(Tuple.Create(a, b, c)); } return(proxTriangles); }
static void Triangulation(bool reverseX) { #if TEST_MSAGL DisplayGeometryGraph.SetShowFunctions(); #endif int r = reverseX ? -1 : 1; IEnumerable <Point> points = Points().Select(p => new Point(r * p.X, p.Y)); var poly = (Polyline)RussiaPolyline.GetTestPolyline().ScaleFromOrigin(1, 1); var cdt = new Cdt(null, new[] { poly }, null); cdt.Run(); #if TEST_MSAGL CdtSweeper.ShowFront(cdt.GetTriangles(), null, null, null); #endif }
internal CdtEdge EdgeBetweenUpperSiteAndLowerSite(CdtSite b) { Debug.Assert(Cdt.Above(this, b) > 0); if (Edges != null) { foreach (var edge in Edges) { if (edge.lowerSite == b) { return(edge); } } } return(null); }
void SetVertexTriangles() { var triangleTree = RectangleNode <CdtTriangle> .CreateRectangleNodeOnEnumeration( Cdt.GetTriangles().Select(t => new RectangleNode <CdtTriangle>(t, t.BoundingBox()))); var vertexTree = RectangleNode <SdVertex> .CreateRectangleNodeOnEnumeration( vertexArray.Select(v => new RectangleNode <SdVertex>(v, new Rectangle(v.Point)))); RectangleNodeUtils.CrossRectangleNodes(triangleTree, vertexTree, TryToAssigenTriangleToVertex); foreach (var v in vertexArray) { Debug.Assert(v.Triangle != null); } }
internal IEnumerable <Point> Calculate() { if (BoundingBox.Width == 0) { FillBoundingBoxWithSites(); } Cdt cdt = new Cdt(cites, null, null); cdt.Run(); var triangles = cdt.GetTriangles(); foreach (var triangle in triangles) { AddVoronoiCite(triangle); } return(voronoiSiteTree.GetAllLeaves()); }
/// <summary> /// Determines the edges of the triangulation together with their desired length (distance between nodes). /// </summary> /// <param name="originalGraph"></param> /// <param name="cdt"></param> /// <param name="targetSizes"></param> /// <param name="desiredEdgeDistances"></param> /// <returns></returns> public static int GetProximityEdgesWithDistance(GeometryGraph originalGraph, Cdt cdt, Size[] targetSizes, out List <Tuple <int, int, double, double> > desiredEdgeDistances) { desiredEdgeDistances = new List <Tuple <int, int, double, double> >(); int numberOverlappingPairs = 0; var edgeSet = new HashSet <CdtEdge>(); //add edges foreach (CdtTriangle triangle in cdt.GetTriangles()) { foreach (CdtEdge triangleEdge in triangle.Edges) { CdtSite site1 = triangleEdge.upperSite; CdtSite site2 = triangleEdge.lowerSite; var nodeId1 = (int)site1.Owner; var nodeId2 = (int)site2.Owner; if (edgeSet.Contains(triangleEdge)) { continue; //edge already included } edgeSet.Add(triangleEdge); Point point1 = site1.Point; Point point2 = site2.Point; double t; double distance = GetIdealDistanceBetweenNodes(nodeId1, nodeId2, point1, point2, targetSizes, out t); if (t > 1) { numberOverlappingPairs++; } int nodeIdSmall = nodeId1; int nodeIdBig = nodeId2; if (nodeId1 > nodeId2) { nodeIdSmall = nodeId2; nodeIdBig = nodeId1; } var tuple = new Tuple <int, int, double, double>(nodeIdSmall, nodeIdBig, distance, t); desiredEdgeDistances.Add(tuple); } } return(numberOverlappingPairs); }
private void TesselateUnderShape(Shape shape) { var polys = new List <Polyline>(shape.Children.Select(sh => (Polyline)sh.BoundaryCurve)); polys.Add(shape.BoundaryCurve as Polyline); var cdt = new Cdt(shapesToInnerPoints[shape], polys, null); cdt.Run(); Set <CdtTriangle> triangles = cdt.GetTriangles(); cdt.SetInEdges(); CleanUpTriangles(shape, ref triangles, cdt); foreach (var t in triangles) { AddTriangleToCanvas(t); } }
static void TestTriangulationOnSmallGraph(ArgsParser.ArgsParser parser) { var polyline = new Polyline( new Point(20.8211097717285, 40.9088821411133), new Point(21.4894065856934, 46.6845321655273), new Point(22.9755554199219, 41.3355484008789), new Point(20.8211097717285, 40.9088821411133)); var polylines = new List <Polyline>(); polylines.Add(polyline); var points = new List <Point>(); var centroid = new Point(21.7620239257813, 42.9763209025065); points.Add(centroid); var testCdt = new Cdt(points, polylines, null); testCdt.Run(); }
/// <summary> /// Computes the minimum spanning tree on a DT with given weights. /// </summary> /// <param name="cdt"></param> /// <param name="weights"></param> /// <returns></returns> static internal List <CdtEdge> GetMstOnCdt(Cdt cdt, Func <CdtEdge, double> weights) { var siteArray = cdt.PointsToSites.Values.ToArray(); var siteIndex = new Dictionary <CdtSite, int>(); for (int i = 0; i < siteArray.Length; i++) { siteIndex[siteArray[i]] = i; } Dictionary <IntPair, CdtEdge> intPairsToCdtEdges = GetEdges(siteArray, siteIndex); var graph = new BasicGraph <IEdge>(intPairsToCdtEdges.Keys, siteArray.Length); var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weights(intPairsToCdtEdges[(IntPair)intPair]), 0); return(new List <CdtEdge>(mstOnBasicGraph.GetTreeEdges().Select(e => intPairsToCdtEdges[(IntPair)e]))); }
///<summary> ///</summary> ///<param name="a"></param> ///<param name="b"></param> public CdtEdge(CdtSite a, CdtSite b) { var above = Cdt.Above(a.Point, b.Point); if (above == 1) { upperSite = a; lowerSite = b; } else { Debug.Assert(above != 0); lowerSite = a; upperSite = b; } upperSite.AddEdgeToSite(this); }
public void InitCdt() { InitSegmentTree(); for (int i = 0; i < fixedRectangles.Length; i++) { Point p = Round(fixedRectangles[i].Center); var node = new TreeNode { isFixed = true, rectId = i, rect = fixedRectangles[i], sitePoint = p, type = SiteType.RectFixed }; if (nodeLabelsFixed != null) { node.label = nodeLabelsFixed[i]; } pointToTreeNode[p] = node; _rectNodesRtree.Add(node.rect, node); _fixedRectanglesTree.Add(fixedRectangles[i], node); } for (int i = 0; i < moveableRectangles.Length; i++) { Point p = Round(moveableRectangles[i].Center); var node = new TreeNode { isFixed = false, rectId = i, rect = moveableRectangles[i], sitePoint = p, type = SiteType.RectMoveable }; if (nodeLabelsMoveable != null) { node.label = nodeLabelsMoveable[i]; } pointToTreeNode[p] = node; _rectNodesRtree.Add(node.rect, node); _moveableRectanglesTree.Add(moveableRectangles[i], node); } var sites = pointToTreeNode.Keys.ToList(); //AddSitesForBoxSegmentOverlaps(sites); cdt = new Cdt(sites, null, null); cdt.Run(); }
private static HashSet <Tuple <int, int> > GetProximityEdges(Cdt cdt) { HashSet <Tuple <int, int> > proxEdges = new HashSet <Tuple <int, int> >(); foreach (var triangle in cdt.GetTriangles()) { foreach (var edge in triangle.Edges) { int a = (int)edge.lowerSite.Owner; int b = (int)edge.upperSite.Owner; if (!proxEdges.Contains(Tuple.Create(a, b)) && !proxEdges.Contains(Tuple.Create(b, a))) { proxEdges.Add(Tuple.Create(a, b)); } } } return(proxEdges); }
Set <CdtEdge> ThreadBoneEdgeThroughCdt(SdBoneEdge boneEdge) { var start = boneEdge.SourcePoint; var currentTriangle = boneEdge.Source.Triangle; Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle)); var crossedEdges = new Set <CdtEdge>(); var end = boneEdge.TargetPoint; if (Cdt.PointIsInsideOfTriangle(end, currentTriangle)) { return(crossedEdges); } var threader = new CdtThreader(currentTriangle, start, end); while (threader.MoveNext()) { CdtEdge piercedEdge = threader.CurrentPiercedEdge; Debug.Assert(piercedEdge != null); if (Gates.Contains(piercedEdge)) { crossedEdges.Insert(piercedEdge); } } /* * CdtEdge piercedEdge = CdtIntersections.FindFirstPiercedEdge(currentTriangle, start, end, out negativeSign, out positiveSign, this.Cdt ); * Debug.Assert(piercedEdge != null); * * do { * if (Gates.Contains(piercedEdge)) * crossedEdges.Insert(piercedEdge); * } * while (CdtIntersections.FindNextPierced(start, end, ref currentTriangle, ref piercedEdge, ref negativeSign, ref positiveSign)); */ //if(ddd(boneEdge)) //CdtSweeper.ShowFront(Cdt.GetTriangles(),null,new []{new LineSegment(boneEdge.SourcePoint,boneEdge.TargetPoint)}, crossedEdges.Select(e=>new LineSegment(e.upperSite.Point,e.lowerSite.Point))); return(crossedEdges); }
internal SdShortestPath(Func <EdgeGeometry, List <Shape> > makeTransparentShapesOfEdgeGeometryAndGetTheShapes, Cdt cdt, Set <CdtEdge> gates) { MakeTransparentShapesOfEdgeGeometry = makeTransparentShapesOfEdgeGeometryAndGetTheShapes; Cdt = cdt; Gates = gates; }