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;
        }
Exemple #9
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.
        }
Exemple #13
0
        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");
            }
        }
Exemple #14
0
        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;
        }
Exemple #16
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];
        }
Exemple #20
0
        /*
         *      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);
        }
Exemple #21
0
        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);
        }
Exemple #24
0
        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.");
        }
Exemple #27
0
        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);
        }
Exemple #29
0
            /*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));
            }
Exemple #30
0
        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
        }
Exemple #32
0
        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);
     }
 }
Exemple #36
0
        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;
        }
Exemple #42
0
 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");
            }
        }
Exemple #46
0
        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;
 }
Exemple #49
0
 public void InitInsertRectSize(Rectangle box)
 {
     _insertRectSize  = box.Width;
     _insertRectSize += NumPixelsPadding * _pixelSize;
 }
Exemple #50
0
 public OverlapRemovalFixedSegmentsBitmap(Rectangle bbox)
 {
     this._bbox = bbox;
     InitBitmap();
     InitTransform();
 }