public void MinimumSizeIsRespected() { // Setup string filePath = Path.Combine(this.TestContext.TestDir, "Out\\Dots", "chat.dot"); GeometryGraph graph = this.LoadGraph(filePath); const double DesiredHeight = 100000; const double DesiredWidth = 100000; SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); settings.MinimalHeight = DesiredHeight; settings.MinimalWidth = DesiredWidth; // Execute LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); // Verify the graph is the correct size Assert.IsTrue(DesiredHeight < graph.Height, "Graph height should be the minimal height."); Assert.IsTrue(DesiredWidth < graph.Width, "Graph width should be the minimal width."); // Verify the nodes were spread apart to fill the space Rectangle nodeBounds = new Rectangle(graph.Nodes.Select(n => n.BoundingBox)); Assert.IsTrue(DesiredWidth < nodeBounds.Height, "The graph nodes weren't scaled vertically to fill the space."); Assert.IsTrue(DesiredWidth < nodeBounds.Width, "The graph nodes weren't scaled horizontally to fill the space."); }
internal PreGraph(EdgeGeometry[] egs, Set<ICurve> nodeBoundaries) { edgeGeometries = new List<EdgeGeometry>(egs); this.nodeBoundaries = new Set<ICurve>(nodeBoundaries); boundingBox = Rectangle.CreateAnEmptyBox(); foreach (var curve in nodeBoundaries) boundingBox.Add(curve.BoundingBox); }
void SetTransformOnViewport(double scale, Point graphCenter, Rectangle vp) { var dx = vp.Width / 2 - scale * graphCenter.X; var dy = vp.Height / 2 + scale * graphCenter.Y; SetTransform(scale, dx, dy); }
internal void AddToAdjacentVertex(TransientGraphUtility transUtil , VisibilityVertex targetVertex, Directions dirToExtend, Rectangle limitRect) { if (!PointComparer.Equal(this.Point, targetVertex.Point)) { transUtil.FindOrAddEdge(this.Vertex, targetVertex, InitialWeight); } ExtendEdgeChain(transUtil, targetVertex, dirToExtend, limitRect); }
private bool InteriorEdgeCrossesObstacle(ObstacleTree obstacleTree) { // File Test: Nudger_Overlap4 // Use the VisibilityBoundingBox for groups because those are what the tree consists of. var rect = new Rectangle(this.UnpaddedBorderIntersect, this.VisibilityBorderIntersect); return InteriorEdgeCrossesObstacle(rect, obs => obs.VisibilityPolyline, obstacleTree.Root.GetLeafRectangleNodesIntersectingRectangle(rect) .Where(node => !node.UserData.IsGroup && (node.UserData != this.Obstacle)).Select(node => node.UserData)); }
static double CommonArea(ref Rectangle a, ref Rectangle b) { double l = Math.Min(a.Left, b.Left); double r = Math.Max(a.Right, b.Right); double t = Math.Max(a.Top, b.Top); double bt = Math.Min(a.Bottom, b.Bottom); return (r - l) * (t - bt); }
public GridTraversal(Rectangle boundingBox, int iLevel) { _boundingBox = boundingBox; _iLevel = iLevel; _numberOfTilesOnSide = (ulong)Math.Pow(2, iLevel); TileWidth = boundingBox.Width / _numberOfTilesOnSide; TileHeight = boundingBox.Height / _numberOfTilesOnSide; }
internal bool IntersectsOnY(Rectangle r){ if (r.Bottom > top + ApproximateComparer.DistanceEpsilon) return false; if (r.Top < bottom - ApproximateComparer.DistanceEpsilon) return false; return true; //return ApproximateComparer.Compare(r.bottom, top) <= 0 && ApproximateComparer.Compare(bottom, r.top) <= 0; }
Rect ToSceneRect(Rectangle rect, Rectangle from, Rect to) { var absWidth = rect.Width / from.Width; var absHeight = rect.Height / from.Height; var left = (rect.Left - from.Left) / from.Width; var top = 1 - (rect.Bottom - from.Bottom) / from.Height - absHeight; return(new Rect((float)(to.x + left * to.width), (float)(to.y + top * to.height), (float)absWidth * to.width, (float)absHeight * to.height)); }
public Rectangle GetInitialBoundingBox() { Rectangle bbox = new Rectangle(); bbox.SetToEmpty(); foreach (var rect in _fixedRectangles) { bbox.Add(rect); } foreach (var rect in _moveableRectangles) { bbox.Add(rect); } return bbox; }
Rectangle GetCommonRectangle(Size[] sizes, Point[] points) { var rect = Rectangle.CreateAnEmptyBox(); Debug.Assert(sizes.Length == points.Length); for (int i = 0; i < sizes.Length; i++) { rect.Add(sizes[i], points[i]); } return(rect); }
/// <summary> /// Additionally needed area of nodes compared to the optimal packing of the nodes. /// </summary> /// <param name="graphOriginal"></param> /// <param name="graphNew"></param> /// <returns></returns> public static Tuple<String, double> Area(GeometryGraph graph) { double minimalArea = graph.Nodes.Sum(v => v.BoundingBox.Area); Rectangle boundingBoxNew=new Rectangle(graph.Nodes.Select(v=>v.BoundingBox)); double areaNew = boundingBoxNew.Area; double ratio = areaNew/minimalArea; // return Tuple.Create("AreaIncreaseToMinPacking",ratio - 1);//we are interested in increase compared to optimal packing. return Tuple.Create("AreaAbsolute/(1E6)", areaNew / (1E6));//we are interested in increase compared to optimal packing. }
private void insertNodeToolStripMenuItem_Click(object sender, EventArgs e) { if (gViewer == null || gViewer.Graph == null) { MessageBox.Show("Please create graph first.", "Insert Node Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } var tree = RectangleNode <object> .CreateRectangleNodeOnEnumeration(GetRectangleNodesFromGraph()); if (tree == null) { return; } var numberOfTries = 10000; Random random = new Random(1); double rectWidth = 100; double rectHeight = 100; var delta = new Point(rectWidth / 2, rectHeight / 2); Rectangle bestRectangle = Rectangle.CreateAnEmptyBox(); Point hint = (gViewer.Graph.BoundingBox.LeftBottom + gViewer.Graph.BoundingBox.RightTop) / 2; double minDistance = double.PositiveInfinity; for (int i = 0; i < numberOfTries; i++) { Point randomCenter = GetRandomCenter(rectHeight, rectWidth, random); Rectangle r = new Rectangle(randomCenter); r.Add(randomCenter + delta); r.Add(randomCenter - delta); if (tree.GetNodeItemsIntersectingRectangle(r).Any()) { } else { var len = (randomCenter - hint).LengthSquared; if (len < minDistance) { minDistance = len; bestRectangle = r; } } } if (bestRectangle.IsEmpty == false) { InsertNodeIntoGraph(bestRectangle); } else { MessageBox.Show("cannot insert"); } }
void DrawRectDilated(Rectangle rect) { Point d = new Point(_insertRectSize / 2, _insertRectSize / 2); var leftBottom = _worldToMap * (rect.LeftBottom - d); var rightTop = _worldToMap * (rect.RightTop + d); int ix1 = (int)leftBottom.X; int iy1 = (int)leftBottom.Y; int iw = (int)(rightTop.X - leftBottom.X); int ih = (int)(rightTop.Y - leftBottom.Y); _bitmap.FillRectangle(ix1, iy1, iw, ih); }
internal bool IntersectsOnX(Rectangle r){ //return ApproximateComparer.Compare(r.left, right) <= 0 && ApproximateComparer.Compare(left, r.right) <= 0; if (r.Left > right + ApproximateComparer.DistanceEpsilon) return false; if (r.Right < left - ApproximateComparer.DistanceEpsilon) return false; return true; //return ApproximateComparer.Compare(r.left, right) <= 0 && ApproximateComparer.Compare(left, r.right) <= 0; }
private void AddStringToShape(Shape shape, Point p, Microsoft.Msagl.Core.Geometry.Rectangle box, double l, Set <Point> points) { while (p.X <= box.Right) { if (IsInsideShape(shape, p)) { points.Insert(p); } p.X += l; } }
// Adds an edge from this.Vertex to a (possibly new) vertex at an intersection with an // existing Edge that adjoins the point. We take 'dir' as an input parameter for edge // extension because we may be on the edge so can't calculate the direction. internal VisibilityVertex AddEdgeToAdjacentEdge(TransientGraphUtility transUtil , VisibilityEdge targetEdge, Directions dirToExtend, Rectangle limitRect) { Point targetIntersect = StaticGraphUtility.SegmentIntersection(targetEdge, this.Point); VisibilityVertex targetVertex = transUtil.VisGraph.FindVertex(targetIntersect); if (null != targetVertex) { AddToAdjacentVertex(transUtil, targetVertex, dirToExtend, limitRect); } else { targetVertex = transUtil.AddEdgeToTargetEdge(this.Vertex, targetEdge, targetIntersect); } ExtendEdgeChain(transUtil, targetVertex, dirToExtend, limitRect); return targetVertex; }
/// <summary> /// intersection (possibly empty) of rectangles /// </summary> /// <param name="rectangle"></param> /// <returns></returns> public Rectangle Intersection(Rectangle rectangle) { Rectangle intersection = new Rectangle(); if (!Intersects(rectangle)) { intersection.SetToEmpty(); return intersection; } double l = Math.Max(Left, rectangle.Left); double r = Math.Min(Right, rectangle.Right); double b = Math.Max(Bottom, rectangle.Bottom); double t = Math.Min(Top, rectangle.Top); return new Rectangle(l,b,r,t); }
public OverlapRemovalFixedSegmentsBitmap(Rectangle[] moveableRectangles, Rectangle[] fixedRectangles, SymmetricSegment[] fixedSegments) { _moveableRectangles = moveableRectangles; _fixedRectangles = fixedRectangles; _fixedSegments = fixedSegments; _bbox = GetInitialBoundingBox(); _bbox.ScaleAroundCenter(1.25); InitBitmap(); InitTransform(); movedRectangles = new Rectangle[moveableRectangles.Length]; }
/* * void SubscribeToChangeVisualsEvents() { * // foreach(var cluster in drawingGraph.RootSubgraph.AllSubgraphsDepthFirstExcludingSelf()) * // cluster.Attr.VisualsChanged += AttrVisualsChanged; * foreach (var edge in drawingGraph.Edges) { * DrawingEdge edge1 = edge; * edge.Attr.VisualsChanged += (a, b) => AttrVisualsChangedForEdge(edge1); * } * * foreach (var node in drawingGraph.Nodes) { * Drawing.Node node1 = node; * node.Attr.VisualsChanged += (a, b) => AttrVisualsChangedForNode(node1); * } * } */ /* * void AttrVisualsChangedForNode(Drawing.Node node) { * IViewerObject viewerObject; * if (drawingObjectsToIViewerObjects.TryGetValue(node, out viewerObject)) { * var vNode = (VNode) viewerObject; * if (vNode != null) * vNode.Invalidate(); * } * } */ // void SetupTimerOnViewChangeEvent(object sender, EventArgs e) { // SetupRoutingTimer(); // } /* * void TestCorrectness(GeometryGraph oGraph, Set<Drawing.Node> oDrawingNodes, Set<DrawingEdge> oDrawgingEdges) { * if (Entities.Count() != oGraph.Nodes.Count + oGraph.Edges.Count) { * foreach (var newDrawingNode in oDrawingNodes) { * if (!drawingObjectsToIViewerObjects.ContainsKey(newDrawingNode)) * Console.WriteLine(); * } * foreach (var drawingEdge in oDrawgingEdges) { * if (!drawingObjectsToIViewerObjects.ContainsKey(drawingEdge)) * Console.WriteLine(); * } * foreach (var viewerObject in Entities) { * if (viewerObject is VEdge) { * Debug.Assert(oDrawgingEdges.Contains(viewerObject.DrawingObject)); * } else { * if (viewerObject is VNode) { * Debug.Assert(oDrawingNodes.Contains(viewerObject.DrawingObject)); * } else { * Debug.Fail("expecting a node or an edge"); * } * } * } * } * } */ /* * void StartLayoutCalculationInThread() { * PushGeometryIntoLayoutGraph(); * graphCanvas.RaiseEvent(new RoutedEventArgs(LayoutStartEvent)); * * layoutThread = * new Thread( * () => * LayoutHelpers.CalculateLayout(geometryGraphUnderLayout, graph.LayoutAlgorithmSettings)); * * layoutThread.Start(); * * //the timer monitors the thread and then pushes the data from layout graph to the framework * layoutThreadCheckingTimer.IsEnabled = true; * layoutThreadCheckingTimer.Tick += LayoutThreadCheckingTimerTick; * layoutThreadCheckingTimer.Interval = new TimeSpan((long) 10e6); * layoutThreadCheckingTimer.Start(); * } */ /* * void LayoutThreadCheckingTimerTick(object sender, EventArgs e) { * if (layoutThread.IsAlive) * return; * * if (Monitor.TryEnter(layoutThreadCheckingTimer)) { * if (layoutThreadCheckingTimer.IsEnabled == false) * return; //somehow it is called on more time after stopping and disabling * layoutThreadCheckingTimer.Stop(); * layoutThreadCheckingTimer.IsEnabled = false; * * TransferLayoutDataToWpf(); * * graphCanvas.RaiseEvent(new RoutedEventArgs(LayoutEndEvent)); * if (LayoutComplete != null) * LayoutComplete(this, new EventArgs()); * } * } */ // void TransferLayoutDataToWpf() { // PushDataFromLayoutGraphToFrameworkElements(); // graphCanvas.Visibility = Visibility.Visible; // SetInitialTransform(); // } /// <summary> /// zooms to the default view /// </summary> public void SetInitialTransform() { if (drawingGraph == null || GeometryGraph == null) { return; } var scale = FitFactor; var graphCenter = GeometryGraph.BoundingBox.Center; var vp = new Rectangle(new Point(0, 0), new Point(GraphCanvas.RenderSize.Width, GraphCanvas.RenderSize.Height)); SetTransformOnViewportWithoutRaisingViewChangeEvent(scale, graphCenter, vp); }
public static void DrawNode(Microsoft.Msagl.Drawing.Node n, Pen pen, Graphics graphics) { Brush selPen1 = new SolidBrush(System.Drawing.Color.Blue); Microsoft.Msagl.Core.Geometry.Point p = n.GeometryNode.Center; Microsoft.Msagl.Core.Geometry.Rectangle rec = n.BoundingBox; double w = n.Width; double h = n.Height; ICurve curve = n.GeometryNode.BoundaryCurve; graphics.DrawLine(pen, (float)(p.X - w / 2), (float)(p.Y - h / 2 + WIDTH), (float)(p.X + w / 2), (float)(p.Y - h / 2 + WIDTH)); graphics.FillRectangle(selPen1, getHeaderRectangle(n)); }
public void PlaceNodesOnly(Rectangle bbox) { BoundingBox = bbox; int numInserted = 0; int level = 1; int iLevel = 0; while (numInserted < SortedLgNodeInfos.Count && level <= MaxLevel) { numInserted = DrawNodesOnlyOnLevel(level, numInserted); AddAllToNodeLevel(iLevel); level *= 2; iLevel++; } }
void AddVoronoiCite(CdtTriangle triangle) { Point p; var goodTriangle = GetCenterOfDescribedCircle(triangle, out p); if (!goodTriangle) return; if (!BoundingBox.Contains(p)) return; var rect=new Rectangle(p); rect.Pad(eps); if (voronoiSiteTree.GetAllIntersecting(rect).Count() > 0) return; voronoiSiteTree.Add(rect, p); }
public Rectangle GetInitialBoundingBox() { Rectangle bbox = new Rectangle(); bbox.SetToEmpty(); foreach (var rect in _fixedRectangles) { bbox.Add(rect); } foreach (var rect in _moveableRectangles) { bbox.Add(rect); } return(bbox); }
public static int GetOutCode(Rectangle rect, Point p) { int code = INSIDE; if (p.X < rect.Left) code |= LEFT; else if (p.X > rect.Right) code |= RIGHT; if (p.Y < rect.Bottom) code |= BOTTOM; else if (p.Y > rect.Top) code |= TOP; return code; }
/// <summary> /// Verifies that the graph conforms to the correct aspect ratio. /// </summary> private static void VerifyAspectRatio(GeometryGraph graph, double aspectRatio) { double ratioTolerance = aspectRatio * 0.05; // Verify the graph is the correct size Assert.AreEqual(aspectRatio, (graph.Width-(graph.Margins*2)) / (graph.Height-(graph.Margins*2)), ratioTolerance, "The graph does not conform to the aspect ratio."); // Verify the nodes were spread apart to fill the space IEnumerable<Rectangle> nodeBoxes = graph.Nodes.Select(n => n.BoundingBox); IEnumerable<Rectangle> edgeBoxes = graph.Edges.Select(e => e.BoundingBox); IEnumerable<Rectangle> labelBoxes = graph.CollectAllLabels().Select(l => l.BoundingBox); Rectangle itemBounds = new Rectangle(nodeBoxes.Concat(edgeBoxes).Concat(labelBoxes)); Assert.AreEqual(aspectRatio, itemBounds.Width / itemBounds.Height, ratioTolerance, "The graph's nodes do not conform to the aspect ratio."); }
public OverlapRemovalFixedSegmentsBitmap(Rectangle[] moveableRectangles, Rectangle[] fixedRectangles, SymmetricSegment[] fixedSegments) { _moveableRectangles = moveableRectangles; _fixedRectangles = fixedRectangles; _fixedSegments = fixedSegments; _bbox = GetInitialBoundingBox(); _bbox.ScaleAroundCenter(1.25); InitBitmap(); InitTransform(); movedRectangles = new Rectangle[moveableRectangles.Length]; }
public static void RunTest2() { Point p1, p2; Rectangle rect1 = new Rectangle(1, 1, 4, 4); Point pc1, pc2; double a; p1 = new Point(-1, 0); p2 = new Point(2, 3); RectSegIntersection.ClipOnRect(rect1, p1, p2, out pc1, out pc2); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(1, 0); p2 = new Point(5, 4); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(0, 4); p2 = new Point(4, 0); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(0, 4); p2 = new Point(4, 0); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(1, 5); p2 = new Point(5, 1); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(0, 1); p2 = new Point(5, 4); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); p1 = new Point(-1, 3); p2 = new Point(2, 6); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); bool intersect; p1 = new Point(-1, 3); p2 = new Point(2, 6); intersect = RectSegIntersection.Intersect(rect1, p1, p2); p1 = new Point(1, 2); p2 = new Point(1, 3); intersect = RectSegIntersection.Intersect(rect1, p1, p2); a = RectSegIntersection.GetOverlapAmount(rect1, p1, p2); }
/*Vector2 TransformPoint(Vector2 point, Rect from, Rect to, bool invertY) * { * * * float absoluteX = Mathf.Abs(point.x - from.x) / from.width, * absoluteY = Mathf.Abs(point.y - from.y) / from.height; * * if (invertY) * { * absoluteY = 1 - absoluteY; * } * * return new Vector2(absoluteX * to.width + to.x, absoluteY * to.height + to.y); * }*/ Rectangle ToGraphRect(Rect rect, Rect from, Rectangle to) { var absWidth = rect.width / from.width; var absHeight = rect.height / from.height; var left = (rect.x - from.x) / from.width; var bottom = 1 - (rect.y - from.y) / from.height - absHeight; var x0 = to.Left + left * to.Width; var x1 = x0 + absWidth * to.Width; var y0 = to.Bottom + bottom * to.Height; var y1 = y0 + absHeight * to.Height; return(new Rectangle(x0, y0, x1, y1)); }
internal static void PositionElement(FrameworkElement fe, Rectangle object_box, Rectangle bounding_box, double scale) { Microsoft.Msagl.Core.Geometry.Point origin = bounding_box.Center; double desiredH = object_box.Height * scale - fe.Margin.Top - fe.Margin.Bottom, desiredW = object_box.Width * scale + fe.Margin.Left + fe.Margin.Right; if (bounding_box.Height < desiredH) { origin.Y += object_box.Center.Y * scale - fe.Margin.Top; } else { if (fe.VerticalAlignment == VerticalAlignment.Top) { origin.Y = bounding_box.Top; } else if (fe.VerticalAlignment == VerticalAlignment.Bottom) { origin.Y -= bounding_box.Height / 2 - object_box.Height * scale; } else { origin.Y += object_box.Center.Y * scale; } } if (bounding_box.Width < desiredW) { origin.X -= object_box.Center.X * scale; } else { if (fe.HorizontalAlignment == HorizontalAlignment.Left) { origin.X -= bounding_box.Width / 2 - fe.Margin.Left; } else if (fe.HorizontalAlignment == HorizontalAlignment.Right) { origin.X -= bounding_box.Width / 2 - object_box.Width * scale; } else { origin.X -= object_box.Center.X * scale; } } PositionElement(fe, origin, scale); }
// double GetAverageOverlap(List<Tuple<int, int, double, double>> proximityEdgesWithDistance, // Point[] positions, Rectangle[] rectangles) { // double overlap = 0; // int counter = 0; // foreach (Tuple<int, int, double, double> tuple in proximityEdgesWithDistance) { // int nodeId1 = tuple.Item1; // int nodeId2 = tuple.Item2; // Point point1 = positions[nodeId1]; // Point point2 = positions[nodeId2]; // // if (nodeBoxes == null) throw new ArgumentNullException("nodeBoxes"); // if (nodeBoxes.Length <= nodeId1) return 0; // if (nodeBoxes.Length <= nodeId2) return 0; // double box1Width = nodeBoxes[nodeId1].Width; // double box1Height = nodeBoxes[nodeId1].Height; // double box2Width = nodeBoxes[nodeId2].Width; // double box2Height = nodeBoxes[nodeId2].Height; // // //Gansner et. al Scaling factor of distance // double tw = (box1Width/2 + box2Width/2)/Math.Abs(point1.X - point2.X); // double th = (box1Height/2 + box2Height/2)/Math.Abs(point1.Y - point2.Y); // double t = Math.Max(Math.Min(tw, th), 1); // // if (t == 1) continue; // no overlap between the bounding boxes // // double distance = (t - 1)*(point1 - point2).Length; // overlap += distance; // counter++; // } // // overlap /= counter; // return overlap; // } /// <summary> /// For debugging only /// </summary> /// <param name="currentIteration"></param> /// <param name="nodeSizes"></param> /// <param name="nodePositions"></param> /// <param name="newPositions"></param> /// <param name="proximityEdgesWithDistance"></param> /// <param name="finalGridVectors"></param> static void ShowCurrentMovementVectors(int currentIteration, Size[] nodeSizes, Point[] nodePositions, List <Point> newPositions, List <Tuple <int, int, double, double> > proximityEdgesWithDistance, Point[] finalGridVectors) { #if DEBUG && !SILVERLIGHT && !SHARPKIT if (DebugMode && currentIteration % 1 == 0) { List <DebugCurve> curveList = new List <DebugCurve>(); var nodeBoxes = new Rectangle[nodeSizes.Length]; for (int i = 0; i < nodeBoxes.Length; i++) { nodeBoxes[i] = new Rectangle(nodeSizes[i], nodePositions[i]); } var nodeCurves = nodeBoxes.Select( v => new DebugCurve(220, 1, "black", Curve.PolylineAroundClosedCurve(CurveFactory.CreateRectangle(v)))); curveList.AddRange(nodeCurves); var vectors = nodePositions.Select( (p, i) => new DebugCurve(220, 2, "red", new Polyline(p, newPositions[i]))).ToList(); foreach (Tuple <int, int, double, double> tuple in proximityEdgesWithDistance) { if (tuple.Item3 > 0) { curveList.Add(new DebugCurve(220, 1, "gray", new Polyline(nodePositions[tuple.Item1], nodePositions[tuple.Item2]))); } } curveList.AddRange(vectors); if (finalGridVectors != null) { var gridFlowVectors = nodePositions.Select((p, i) => new DebugCurve(220, 2, "blue", new Polyline(p, p + finalGridVectors[i]))) .ToList(); curveList.AddRange(gridFlowVectors); } LayoutAlgorithmSettings.ShowDebugCurves(curveList.ToArray()); } #endif }
internal static void PositionElement(FrameworkElement fe, Rectangle object_box, Rectangle bounding_box, double scale) { Microsoft.Msagl.Core.Geometry.Point origin = bounding_box.Center; double desiredH = object_box.Height * scale - fe.Margin.Top - fe.Margin.Bottom, desiredW = object_box.Width * scale + fe.Margin.Left + fe.Margin.Right; if (bounding_box.Height < desiredH) { origin.Y += object_box.Center.Y * scale - fe.Margin.Top; } else { if (fe.VerticalAlignment == VerticalAlignment.Top) { origin.Y = bounding_box.Top; } else if (fe.VerticalAlignment == VerticalAlignment.Bottom) { origin.Y -= bounding_box.Height / 2 - object_box.Height * scale; } else { origin.Y += object_box.Center.Y * scale; } } if (bounding_box.Width < desiredW) { origin.X -= object_box.Center.X * scale; } else { if (fe.HorizontalAlignment == HorizontalAlignment.Left) { origin.X -= bounding_box.Width / 2 - fe.Margin.Left; } else if (fe.HorizontalAlignment == HorizontalAlignment.Right) { origin.X -= bounding_box.Width / 2 - object_box.Width * scale; } else { origin.X -= object_box.Center.X * scale; } } PositionElement(fe, origin, scale); }
void InsertNodeIntoGraph(Rectangle rectangle) { Node node = new Node("testNode"); node.Attr.FillColor = Color.Red; node.Attr.Shape = Shape.DrawFromGeometry; node.Label = null; var geomNode = node.GeometryNode = GeometryGraphCreator.CreateGeometryNode(gViewer.Graph, gViewer.Graph.GeometryGraph, node, ConnectionToGraph.Disconnected); var center = (rectangle.LeftBottom + rectangle.RightTop) / 2; geomNode.BoundaryCurve = CurveFactory.CreateRectangle(rectangle.Width, rectangle.Height, center); node.GeometryNode = geomNode; var dNode = gViewer.CreateIViewerNode(node); gViewer.AddNode(dNode, true); }
public static void RunTest1() { Rectangle rect1 = new Rectangle(0, 0, 2, 2); Rectangle rect2 = new Rectangle(3, 3, 4, 4); Rectangle rect3 = new Rectangle(4, 1, 5, 2); Rectangle[] moveableRectangles = {rect1, rect2, rect3}; Rectangle[] fixedRectangles = {}; SymmetricSegment[] fixedSegments = {}; OverlapRemovalFixedSegmentsMst orfs = new OverlapRemovalFixedSegmentsMst(moveableRectangles, fixedRectangles, fixedSegments); orfs.InitCdt(); double dist = orfs.GetDistance(rect1, rect2); var mstEdges = orfs.GetMstFromCdt(); }
public void RTreeQuery_RandomPoints() { var bspQueryTime = new Stopwatch(); var checkQueryTime = new Stopwatch(); const int Seeds = 5; const int Repeats = 5; for (int seed = 0; seed < Seeds; ++seed) { int n = 100000; var points = new Point[n]; var rand = new Random(seed); double scale = 1000; for (int i = 0; i < n; ++i) { points[i] = new Point(rand.NextDouble() * scale, rand.NextDouble() * scale); } var queryTree = new RTree<Point>( from p in points select new KeyValuePair<Rectangle, Point>(new Rectangle(p), p)); Assert.AreEqual(queryTree.GetAllLeaves().Count(), n); Assert.AreEqual(queryTree.GetAllIntersecting(new Rectangle(-2, -2, -1, -1)).Count(), 0); Assert.AreEqual(queryTree.GetAllIntersecting(new Rectangle(0, 0, scale, scale)).Count(), n); for (int i = 0; i < Repeats; ++i) { double s = scale / 100; var query = new Rectangle(rand.NextDouble() * s, rand.NextDouble() * s, rand.NextDouble() * s, rand.NextDouble() * s); bspQueryTime.Start(); var result = queryTree.GetAllIntersecting(query).ToList(); bspQueryTime.Stop(); checkQueryTime.Start(); var checkList = (from p in points where query.Contains(p) select p).ToList(); checkQueryTime.Stop(); var checkSet = new HashSet<Point>(checkList); Assert.AreEqual(result.Count, checkList.Count); foreach (var r in result) { Assert.IsTrue(query.Contains(r)); Assert.IsTrue(checkSet.Contains(r)); } } Assert.IsTrue(bspQueryTime.ElapsedMilliseconds < checkQueryTime.ElapsedMilliseconds); } }
static void RebuildBBHierarchyUnderObject(DObject dObj) { BBNode oldNode = dObj.BbNode; BBNode newNode = BuildBBHierarchyUnderDObject(dObj); if (newNode != null) { //now copy all fields, except the parent oldNode.left = newNode.left; oldNode.right = newNode.right; oldNode.geometry = newNode.geometry; oldNode.bBox = newNode.bBox; } else { oldNode.bBox = Rectangle.CreateAnEmptyBox(); } }
internal static void PreRunTransform(GeometryGraph geomGraph, PlaneTransformation matrix) { if (matrix.IsIdentity) return; var matrixInverse = matrix.Inverse; foreach (Node n in geomGraph.Nodes) n.Transform(matrixInverse); //calculate new label widths and heights foreach (Edge e in geomGraph.Edges) { if (e.Label != null) { e.OriginalLabelWidth = e.Label.Width; e.OriginalLabelHeight = e.Label.Height; var r = new Rectangle(matrixInverse*new Point(0, 0), matrixInverse*new Point(e.Label.Width, e.Label.Height)); e.Label.Width = r.Width; e.Label.Height = r.Height; } } geomGraph.UpdateBoundingBox(); }
internal void ExtendEdgeChain(TransientGraphUtility transUtil, VisibilityVertex targetVertex, Directions dirToExtend, Rectangle limitRect) { // Extend the edge chain to the opposite side of the limit rectangle. StaticGraphUtility.Assert(PointComparer.Equal(this.Point, targetVertex.Point) || (PointComparer.GetPureDirection(this.Point, targetVertex.Point) == dirToExtend) , "input dir does not match with to-targetVertex direction", transUtil.ObstacleTree, transUtil.VisGraph); var extendOverlapped = IsOverlapped; if (extendOverlapped) { // The initial vertex we connected to may be on the border of the enclosing obstacle, // or of another also-overlapped obstacle. If the former, we turn off overlap now. extendOverlapped = transUtil.ObstacleTree.PointIsInsideAnObstacle(targetVertex.Point, dirToExtend); } // If we're inside an obstacle's boundaries we'll never extend past the end of the obstacle // due to encountering the boundary from the inside. So start the extension at targetVertex. SegmentAndCrossings segmentAndCrossings = GetSegmentAndCrossings(this.IsOverlapped ? targetVertex : this.Vertex, dirToExtend, transUtil); transUtil.ExtendEdgeChain(targetVertex, limitRect, segmentAndCrossings.Item1, segmentAndCrossings.Item2, extendOverlapped); }
internal BundleInfo(BundleBase sourceBase, BundleBase targetBase, Set<Polyline> obstaclesToIgnore, double edgeSeparation, double[] halfWidthArray) { SourceBase = sourceBase; TargetBase = targetBase; this.obstaclesToIgnore = obstaclesToIgnore; EdgeSeparation = edgeSeparation; HalfWidthArray = halfWidthArray; TotalRequiredWidth = EdgeSeparation * HalfWidthArray.Length + HalfWidthArray.Sum() * 2; longEnoughSideLength = new Rectangle(sourceBase.Curve.BoundingBox, targetBase.Curve.BoundingBox).Diagonal; //sometimes TotalRequiredWidth is too large to fit into the circle, so we evenly scale everything double mn = Math.Max(sourceBase.Curve.BoundingBox.Diagonal, targetBase.Curve.BoundingBox.Diagonal); if (TotalRequiredWidth > mn) { double scale = TotalRequiredWidth / mn; for (int i = 0; i < HalfWidthArray.Length; i++) HalfWidthArray[i] /= scale; TotalRequiredWidth /= scale; EdgeSeparation /= scale; } }
private void button1_Click(object sender, EventArgs e) //this is abstract.dot of GraphViz { var tree = RectangleNode <object> .CreateRectangleNodeOnEnumeration(GetRectangleNodesFromGraph()); var numberOfTries = 10000; Random random = new Random(1); double rectWidth = 50; double rectHeight = 200; var delta = new Point(rectWidth / 2, rectHeight / 2); Rectangle bestRectangle = Rectangle.CreateAnEmptyBox(); Point hint = (gViewer.Graph.BoundingBox.LeftBottom + gViewer.Graph.BoundingBox.RightTop) / 2; double minDistance = double.PositiveInfinity; for (int i = 0; i < numberOfTries; i++) { Point randomCenter = GetRandomCenter(rectHeight, rectWidth, random); Rectangle r = new Rectangle(randomCenter); r.Add(randomCenter + delta); r.Add(randomCenter - delta); if (tree.GetNodeItemsIntersectingRectangle(r).Any()) { } else { var len = (randomCenter - hint).LengthSquared; if (len < minDistance) { minDistance = len; bestRectangle = r; } } } if (bestRectangle.IsEmpty == false) { InsertNodeIntoGraph(bestRectangle); } else { MessageBox.Show("cannot insert"); } }
internal bool Run() { if (metroGraphData.Edges.Count() == 0) return false; var splittingPoints = new Dictionary<PointPair, List<Point>>(); var treeOfVertices = new RTree<Point>(); foreach (var vertex in Vertices()) { var r = new Rectangle(vertex.Point); r.Pad(ApproximateComparer.IntersectionEpsilon); treeOfVertices.Add(r, vertex.Point); } var treeOfEdges = RectangleNode<PointPair>.CreateRectangleNodeOnData(Edges(), e => new Rectangle(e.First, e.Second)); RectangleNodeUtils.CrossRectangleNodes<PointPair>(treeOfEdges, treeOfEdges, (a, b) => IntersectTwoEdges(a, b, splittingPoints, treeOfVertices)); SortInsertedPoints(splittingPoints); bool pointsInserted = InsertPointsIntoPolylines(splittingPoints); bool progress = FixPaths(); bool pointsRemoved = RemoveUnimportantCrossings(); return progress || pointsInserted || pointsRemoved; }
static Rectangle Translate(Rectangle rect, Point delta) { return(new Rectangle(rect.LeftBottom + delta, rect.RightTop + delta)); }
// internal VisibilityVertex GetExistingVvCloseBy(Point p) { // var rect = new Rectangle(p); // rect.Pad(searchEps); // VisibilityVertex v=null; // // // var crossed = _visGraphVerticesTree.GetAllIntersecting(rect); // if (crossed.Length == 0) { // return null; // } // double dist = double.PositiveInfinity; // for (int i = 0; i < crossed.Length; i++) { // var vv = crossed[i]; // var vvDist = (vv.Point - p).LengthSquared; // if (vvDist < dist) { // dist = vvDist; // v = vv; // } // } // return v; // } void RegisterInTree(VisibilityVertex vv) { var rect = new Rectangle(vv.Point); VisibilityVertex treeVv; if (_visGraphVerticesTree.OneIntersecting(rect, out treeVv)) { Debug.Assert(treeVv == vv); return; } _visGraphVerticesTree.Add(rect, vv); }
// sideWithRange is either the same as sideToQueue, if that side is being loaded by an // OpenVertexEvent, or is a different side that is just closing. protected void LoadReflectionEvents(BasicObstacleSide sideToQueue, BasicObstacleSide sideWithRange) { // If this line reflects upward then it cannot receive rays from below (they would pass // through its obstacle), and of course a perpendicular lookahead line will never // intersect a perpendicular side. if ((null == sideToQueue) || SideReflectsUpward(sideToQueue) || IsPerpendicular(sideToQueue)) { return; } // If there is no overlap in the rectangles along the current axis, there is nothing // to do. This reduces (but doesn't prevent) duplicate events being loaded. var bbox1 = new Rectangle(sideToQueue.Start, sideToQueue.End); var bbox2 = new Rectangle(sideWithRange.Start, sideWithRange.End); if ((ScanDirection.IsHorizontal) ? !bbox1.IntersectsOnX(bbox2) : !bbox1.IntersectsOnY(bbox2)) { return; } // Make sure we order the endpoints from low to high along the scanline parallel, and get only // the intersection. RectilinearFileTests.Nudger_Overlap* exercise reflection lookahead subranges. Rectangle bboxIntersect = Rectangle.Intersect(bbox1, bbox2); Point low = bboxIntersect.LeftBottom; Point high = bboxIntersect.RightTop; // This is inclusive of the endpoints of sideWithRange, to be sure that we remove the item // from LookaheadScan; if it's on an extreme vertex in the perpendicular sweep then it will // stop the chain; see TestRectilinear.Reflection_Staircase_Stops_At_BoundingBox_Side*. RBNode<BasicReflectionEvent> lookaheadSiteNode = lookaheadScan.FindFirstInRange(low, high); while (null != lookaheadSiteNode) { // Calculate the lookahead intersection with this side in the perpendicular direction to // the scanline. Note: due to rounding error, this may be different from the calculation // in the parallel direction when the scanline gets up to the ScanDirection.PerpCoord(intersect); // this will be adjusted in ScanSegmentTree.MergeSegments. Point intersect = ScanLineIntersectSide(lookaheadSiteNode.Item.Site, sideToQueue , ScanDirection.PerpendicularInstance); DevTraceInfoVgGen(1, "Loading reflection from lookahead site {0} to intersect at {1}" , lookaheadSiteNode.Item.Site, intersect); DevTraceInfoVgGen(2, " side {0})", sideToQueue); // same indent as AddSegment // In some cases where the ActiveLowSide and ActiveHighSide of an obstacle lean in the same // direction such that LowSide is above HighSide, e.g. on the horizontal pass when they both // lean to the right, the delayed-lookahead in CloseVertex (obstacle close) event may find the // high side spanning the scanline-parallel coordinate range where its low side has enqueued // lookahead events. In that case the intersection will be less than the enqueueing site so // ignore it. See RectilinearTests.ReflectionsSitedByLowSideAreNotLoadedByHighSide.) // Similarly, if this is at the same perpendicular coordinate as the current scanline // position, ignore it; otherwise we could back up in the scanline's parallel coordinate. // Since we retrieved events for the endpoint of any previous side, this won't be // encountered on a bend vertex event; therefore we're on a near-flat bottom side // so we're parallel to the extreme-vertex line and it's fine to just absorb the photon. // This also handles the case of reflections into intersecting sides - at some point // they converge such that the intersection is not ahead of the lookahead site. if (ScanDirection.ComparePerpCoord(intersect, lookaheadSiteNode.Item.Site) > 0) { // Add an event to continue the chain, "shifting" the site's reflecting // obstacle back to the initialObstacle position. We must load this here // and process it in ConfirmLookaheadEvent so it will be removed from // the lookahead list; we can't remove it here if it doesn't satisfy the // staircase requirements, because this may be called from loading a "higher" // side (during the sweep) which could steal events from the lower side. AddReflectionEvent(lookaheadSiteNode.Item, sideToQueue, intersect); } else { if (lookaheadSiteNode.Item.ReflectingObstacle != sideToQueue.Obstacle) { DevTraceInfoVgGen(1, " (discarding reflection at intersect {0} as it is not ahead of the previous site)", intersect); // We need to remove the site. We're in the middle of Node enumeration so just // mark the site and on function exit we'll remove any so marked. lookaheadScan.MarkStaleSite(lookaheadSiteNode.Item); } else { DevTraceInfoVgGen(1, " (skipping reflection at intersect {0} as it is the same obstacle)", intersect); } } // Get the next item, leaving the current one in the lookahead scan until // we actually process the event; this lets us know whether an intervening // obstacle may be opened and intercepted the reflection. ConfirmLookaheadEvents // will actually do the removal when the lowest side containing the lookahead // site is loaded. See RectilinearTests.ReflectionsRemoveInterceptedSite. lookaheadSiteNode = lookaheadScan.FindNextInRange(lookaheadSiteNode, high); } // endwhile previousSiteNode lookaheadScan.RemoveStaleSites(); }
/// <summary> /// sets the bounding curve scaled to fit the targetBounds /// </summary> /// <param name="targetBounds"></param> protected void FitBoundaryCurveToTarget(Rectangle targetBounds) { if (BoundaryCurve != null) { // RoundedRect is special, rather than simply scaling the geometry we want to keep the corner radii constant RoundedRect rr = BoundaryCurve as RoundedRect; if (rr == null) { Debug.Assert(BoundaryCurve.BoundingBox.Width > 0); Debug.Assert(BoundaryCurve.BoundingBox.Height > 0); double scaleX = targetBounds.Width / BoundaryCurve.BoundingBox.Width; double scaleY = targetBounds.Height / BoundaryCurve.BoundingBox.Height; BoundaryCurve.Translate(-BoundaryCurve.BoundingBox.LeftBottom); BoundaryCurve = BoundaryCurve.ScaleFromOrigin(scaleX, scaleY); BoundaryCurve.Translate(targetBounds.LeftBottom); } else { BoundaryCurve = rr.FitTo(targetBounds); } Debug.Assert(ApproximateComparer.Close(BoundaryCurve.BoundingBox, targetBounds, ApproximateComparer.UserDefinedTolerance), "FitToBounds didn't succeed in scaling/translating to target bounds"); } }
private void SetTransformOnViewportWithoutRaisingViewChangeEvent(double scale, Point graphCenter, Rectangle vp) { var dx = vp.Width / 2 - scale * graphCenter.X; var dy = vp.Height / 2 + scale * graphCenter.Y; SetTransformWithoutRaisingViewChangeEvent(scale, dx, dy); }
/// <summary> /// Translate the labels position state by the given delta /// </summary> /// <param name="delta"></param> public void Translate(Point delta) { RaiseLayoutChangeEvent(delta); if (InnerPoints != null) { for (int i = 0; i < InnerPoints.Count; ++i) { InnerPoints[i] = InnerPoints[i] + delta; } } if (OuterPoints != null) { for (int i = 0; i < OuterPoints.Count; ++i) { OuterPoints[i] = OuterPoints[i] + delta; } } boundingBox = Rectangle.Translate(boundingBox, delta); }
internal RectangleObstacle(Rectangle r) { this.Rectangle = r; }
public void InitInsertRectSize(Rectangle box) { _insertRectSize = box.Width; _insertRectSize += NumPixelsPadding * _pixelSize; }
public OverlapRemovalFixedSegmentsBitmap(Rectangle bbox) { this._bbox = bbox; InitBitmap(); InitTransform(); }