Ejemplo n.º 1
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator    = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var    corner1          = new Vec2F(1.1f, 2.2f);
                var    corner2          = new Vec2F(4.4f, 5.5f);
                var    o = new Box2F(corner1, corner2);

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Ejemplo n.º 2
0
        protected virtual double GetBoundingRadius(
            Digraph <Node, Edge> .GNode node)
        {
            Box2F bbox = node.Data.LayoutBBox;

            return(Math.Sqrt(bbox.W * bbox.W + bbox.H * bbox.H) / 2.0);
        }
        private void Adjust()
        {
            Digraph <Node, Edge> .GNode closest;
            if (this.mDistances.Length < this.mNodeCount)
            {
                this.mDistances = new int[this.mNodeCount];
            }
            for (int i = 0; i < this.mNodeCount; i++)
            {
                closest = this.mGraph.InternalNodeAt(i);
                //this.mNodes[i].Index = i;
                closest.Color      = GraphColor.White;
                this.mDistances[i] = 0;
            }
            closest = null;
            Box2F bbox = this.mClusterNode == null
                ? this.BoundingBox : this.mClusterNode.LayoutBBox;

            while (closest == null || closest.TotalEdgeCount(false) == 0)
            {
                // get a random point in the container
                this.mGlobalX = (0.1 + 0.8 * this.mRnd.NextDouble())
                                * bbox.W + bbox.X;
                this.mGlobalY = (0.1 + 0.8 * this.mRnd.NextDouble())
                                * bbox.H + bbox.Y;

                // find the closest node to this random point
                closest = this.GetClosest(this.mGlobalX, this.mGlobalY);
            }

            // Adjust the nodes to the selected node

            this.AdjustNode(closest);
        }
 public ISOMLayoutAlgorithm(Digraph <Node, Edge> graph,
                            Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.mQueue     = new Digraph <Node, Edge> .GNode[0];
     this.mDistances = new int[0];
 }
Ejemplo n.º 5
0
        public bool Intersects(Box2F box)
        {
            if (!Box.Overlaps(box))
            {
                return(false);
            }

            switch (Direction)
            {
            case SegmentDirection.Vertical:
                return(box.Min.X < Start.X && Start.X < box.Max.X);

            case SegmentDirection.Horizontal:
                return(box.Min.Y < Start.Y && Start.Y < box.Max.Y);

            case SegmentDirection.PositiveSlope:
                return(DifferentSides(box.TopLeft, box.BottomRight));

            case SegmentDirection.NegativeSlope:
                return(DifferentSides(box.BottomLeft, box.TopRight));

            default:
                throw new InvalidOperationException("Invalid box intersection direction enumeration");
            }
        }
Ejemplo n.º 6
0
 public SimpleTreeLayoutForCircles(CircleNodeScene scene,
                                   Box2F boundingBox)
     : base(scene.Graph, boundingBox)
 {
     this.mScene             = scene;
     this.AdaptToSizeChanges = true;
 }
Ejemplo n.º 7
0
 public FRLayoutAlgorithm(Digraph <Node, Edge> graph,
                          Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.MaxIterations = 200;
     this.mNewXs        = sEmptyCoords;
     this.mNewYs        = sEmptyCoords;
 }
Ejemplo n.º 8
0
 public SingleCircleLayoutAlgorithm(Digraph <Node, Edge> graph,
                                    Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.mEmbedCircle = new Digraph <Node, Edge> .GNode[0];
     this.mAngles      = new double[0];
     this.mHalfSizes   = new double[0];
 }
Ejemplo n.º 9
0
        /*/// <summary>
         * /// Tries to get the internal node in this layout algorithm's
         * /// <see cref="Graph"/> that corresponds to the root node set with
         * /// the <see cref="M:ARootedAlgorithm`1{Node}.SetRoot(Node)"/>
         * /// function.
         * /// </summary>
         * /// <returns>The internal node in this algorithm's graph that
         * /// corresponds to this algorithm's root value, or the first node in
         * /// the graph if there is corresponding node, or null if this
         * /// algorithm's graph is currently empty.</returns>
         * public Digraph<Node, Edge>.GNode TryGetGraphRoot()
         * {
         *  if (this.mGraph.NodeCount == 0)
         *  {
         *      return null;
         *  }
         *  int index = this.HasRoot
         *      ? this.mGraph.IndexOfNode(this.TryGetRoot()) : 0;
         *  if (index < 0)
         *      index = 0;
         *  Digraph<Node, Edge>.GNode root
         *      = this.mGraph.InternalNodeAt(index);
         *  //root.Index = index;
         *  return root;
         * }/* */

        /// <summary>
        /// Shuffles all layout nodes (but not port nodes) in this layout
        /// algorithm's <see cref="Graph"/> to random positions with
        /// minimal intersections of their bounding boxes.
        /// </summary>
        /// <param name="immediate">Whether the positions of the layout nodes
        /// are set after all their new positions have been randomly set.
        /// </param><remarks>
        /// The random positions of the nodes are restricted to within the
        /// bounding box of this algorithm's <see cref="ClusterNode"/>, or
        /// within this algorithm's <see cref="BoundingBox"/> if the cluster
        /// node is null.
        /// </remarks>
        public void ShuffleNodes(bool immediate)
        {
            Box2F bbox = this.mClusterNode == null
                ? this.mBBox : this.mClusterNode.LayoutBBox;

            this.ShuffleNodesInternal(bbox.X, bbox.Y,
                                      bbox.W, bbox.H, immediate);
        }
Ejemplo n.º 10
0
 public SCircleLayoutForCircles(CircleNodeScene scene,
                                Box2F boundingBox)
     : base(scene.Graph, boundingBox)
 {
     this.mScene             = scene;
     this.CenterX            = boundingBox.X + boundingBox.W / 2;
     this.CenterY            = boundingBox.Y + boundingBox.H / 2;
     this.AdaptToSizeChanges = true;
 }
Ejemplo n.º 11
0
 public SimpleTreeLayoutAlgorithm(Digraph <Node, Edge> graph,
                                  Box2F boundingBox)
     : base(graph, boundingBox)
 {
     //this.Spring = new LayoutLinearSpring();
     this.mDatas = new NodeData[0];
     //this.mSizeWs = new float[0];
     //this.mSizeHs = new float[0];
 }
Ejemplo n.º 12
0
            public void LearnNodePos(float x, float y, Box2F boundingBox)
            {
                double rad = Math.Sqrt(x * x + y * y);

                if (rad > this.mRadius)
                {
                    this.mRadius = rad;
                }
            }
Ejemplo n.º 13
0
        private void CalcParameters()
        {
            Box2F bbox = this.mClusterNode == null
                ? this.BoundingBox : this.mClusterNode.LayoutBBox;

            this.mK = (float)Math.Sqrt(bbox.W * bbox.H
                                       / this.mGraph.NodeCount);
            this.mInitTemp = Math.Min(bbox.W, bbox.H) / 10;
            this.UpdateParameters();
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets the position on the border of the given bounding box based
        /// on its intersection with a ray starting at its center point with
        /// the given rotational <paramref name="angle"/>.
        /// </summary>
        /// <param name="bbox">The bounding box to intersect with
        /// a positioning ray.</param>
        /// <param name="angle">The angle of a positioning ray starting at
        /// the center of <paramref name="bbox"/>.</param>
        /// <returns>The intersection point of the given bounding box and
        /// a ray with the given <paramref name="angle"/> starting at the
        /// bounding box's center point.</returns>
        public static Vec2F GetBoundaryPosition(Box2F bbox, double angle)
        {
            double cx = bbox.X + bbox.W / 2.0;
            double cy = bbox.Y + bbox.H / 2.0;
            double dx = Math.Cos(angle);
            double dy = Math.Sin(angle);
            double t  = Math.Min(Math.Abs(cx / dx), Math.Abs(cy / dy));

            return(new Vec2F((float)(dx * t + cx), (float)(dy * t + cy)));
        }
Ejemplo n.º 15
0
        public SCircleLayoutForCircles(CircleNodeScene scene,
                                       IClusterNode clusterNode)
            : base(scene.Graph, clusterNode)
        {
            this.mScene = scene;
            Box2F bbox = clusterNode.LayoutBBox;

            this.CenterX            = bbox.X + bbox.W / 2;
            this.CenterY            = bbox.Y + bbox.H / 2;
            this.AdaptToSizeChanges = true;
        }
Ejemplo n.º 16
0
 private void TestToStringResults(Box2F o, string s, string listSeparator, string decimalSeparator)
 {
     string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries);
     Assert.AreEqual(results.Length, 4);
     foreach (string oneFloatString in results)
     {
         Assert.True(oneFloatString.Contains(decimalSeparator));
     }
     Assert.AreEqual(float.Parse(results[0]), o.Min.X);
     Assert.AreEqual(float.Parse(results[1]), o.Min.Y);
     Assert.AreEqual(float.Parse(results[2]), o.Max.X);
     Assert.AreEqual(float.Parse(results[3]), o.Max.Y);
 }
Ejemplo n.º 17
0
 public KKLayoutAlgorithm(Digraph <Node, Edge> graph,
                          Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.mShortestPathsAlg
         = new BasicAllShortestPaths <Node, Edge>(
               new DijkstraShortestPath <Node, Edge>(
                   graph, false, false));
     this.mXs           = new double[0];
     this.mYs           = new double[0];
     this.mHidden       = new bool[0];
     this.MaxIterations = 200;
 }
Ejemplo n.º 18
0
            public Vec2F AdjustNodePosition(float x, float y, Box2F bbox)
            {
                float d;
                Vec2F v = new Vec2F(x, y);

                d   = bbox.W;
                v.X = Math.Max(x + bbox.X, this.mMinX) + d;
                v.X = Math.Min(v.X, this.mMaxX) - bbox.X - d;
                d   = bbox.H;
                v.Y = Math.Max(y + bbox.Y, this.mMinY) + d;
                v.Y = Math.Min(v.Y, this.mMaxY) - bbox.Y - d;
                return(v);
            }
Ejemplo n.º 19
0
        public RectGeom(Box2F boundingBox)
        {
            this.mX = boundingBox.X;
            this.mY = boundingBox.Y;
            this.mW = boundingBox.W;
            this.mH = boundingBox.H;

            this.mOffsetX = 0;
            this.mOffsetY = 0;

            this.bBBoxDirty = true;
            this.mBBoxX     = this.mX;
            this.mBBoxY     = this.mY;
            this.mBBoxW     = this.mW;
            this.mBBoxH     = this.mH;
        }
Ejemplo n.º 20
0
        private BoxCollider CreateCollider(GameObject gameObject, List <Seg2F> edges)
        {
            Box2F box = Box2F.Combine(edges.Select(edge => edge.Box));

            (float x, float z) = box.Center;
            float y = subsectorPlane.SectorPlane.Height;

            // Because we don't want some thin value being made even thinner,
            // we scale it up by the map unit size. This way we don't risk any
            // objects passing through it.
            float colliderThickness = PhysicsSystem.ColliderThickness * Constants.MapUnitInverse;

            BoxCollider collider = gameObject.AddComponent <BoxCollider>();

            collider.center = new Vector3(x, y, z).MapUnit();
            collider.size   = new Vector3(box.Width, colliderThickness, box.Height).MapUnit();

            return(collider);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Creates a new layout algorithm instance to operate on the given
        /// <paramref name="graph"/> using the given
        /// <see cref="IClusterNode"/> instance to affect the positions
        /// of the graph's nodes.</summary>
        /// <param name="graph">The graph that this layout algorithm will
        /// operate on by setting the positions of its nodes.</param>
        /// <param name="clusterNode">The <see cref="IClusterNode"/>
        /// instance that affects the positions of the nodes in the
        /// <paramref name="graph"/>.</param>
        /// <seealso cref="Graph"/><seealso cref="ClusterNode"/>
        public LayoutAlgorithm(Digraph <Node, Edge> graph,
                               IClusterNode clusterNode)
            : base(graph)
        {
            if (clusterNode == null)
            {
                throw new ArgumentNullException("clusterNode");
            }
            this.mClusterNode = clusterNode;
            this.mBBox        = new Box2F(0, 0, 0, 0);

            uint vers = graph.NodeVersion;

            this.mLastNVers = vers == 0 ? uint.MaxValue : vers - 1;
            vers            = graph.EdgeVersion;
            this.mLastEVers = vers == 0 ? uint.MaxValue : vers - 1;

            this.mLastXs = new float[0];
            this.mLastYs = new float[0];
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Creates a new layout algorithm instance to operate on the given
        /// <paramref name="graph"/> using the given <see cref="RectangleF"/>
        /// instance to constrain the positions of the graph's nodes to
        /// within its boundaries.
        /// </summary>
        /// <param name="graph">The graph that this layout algorithm will
        /// operate on by setting the positions of its nodes.</param>
        /// <param name="boundingBox">The <see cref="RectangleF"/> instance
        /// that constrains the positions of the nodes in the
        /// <paramref name="graph"/> to within its boundaries.</param>
        public LayoutAlgorithm(Digraph <Node, Edge> graph,
                               Box2F boundingBox)
            : base(graph)
        {
            if (boundingBox == null)
            {
                throw new ArgumentNullException("boundingBox");
            }
            this.mClusterNode = null;
            this.mBBox        = boundingBox;

            uint vers = graph.NodeVersion;

            this.mLastNVers = vers == 0 ? uint.MaxValue : vers - 1;
            vers            = graph.EdgeVersion;
            this.mLastEVers = vers == 0 ? uint.MaxValue : vers - 1;

            this.mLastXs = new float[0];
            this.mLastYs = new float[0];
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Shuffles all layout nodes (but not port nodes) in this layout
 /// algorithm's <see cref="Graph"/> to random positions with
 /// minimal intersections of their bounding boxes.
 /// </summary>
 /// <param name="bbox">A rectangle used to restrict the randomly set
 /// positions of the layout nodes to within its boundaries.</param>
 /// <param name="immediate">Whether the positions of the layout nodes
 /// are set after all their new positions have been randomly set.
 /// </param><remarks>
 /// The random positions of the nodes are restricted to within the
 /// bounding box of this algorithm's <see cref="ClusterNode"/>, or
 /// within this algorithm's <see cref="BoundingBox"/> if the cluster
 /// node is null.
 /// </remarks>
 public void ShuffleNodes(Box2F bbox, bool immediate)
 {
     if (this.mClusterNode == null)
     {
         bbox = Box2F.Intersect(bbox, this.mBBox);
         if (bbox.W == 0 || bbox.H == 0)
         {
             bbox = this.mBBox;
         }
     }
     else
     {
         bbox = Box2F.Intersect(bbox,
                                this.mClusterNode.LayoutBBox);
         if (bbox.W == 0 || bbox.H == 0)
         {
             bbox = this.mClusterNode.LayoutBBox;
         }
     }
     this.ShuffleNodesInternal(bbox.X, bbox.Y,
                               bbox.W, bbox.H, immediate);
 }
Ejemplo n.º 24
0
 public void LearnNodePos(float x, float y, Box2F boundingBox)
 {
 }
Ejemplo n.º 25
0
 private CircularLayoutAlgorithm(Digraph <Node, Edge> graph,
                                 Box2F boundingBox)
     : base(graph, boundingBox)
 {
 }
Ejemplo n.º 26
0
        // TODO: Can the position copying from mXPositions and mYPositions
        // be reduced to the barycenter node that changes position and any nodes
        // which have been swapped on each iteration?
        protected override void PerformIteration(uint iteration)
        {
            int  i, j;
            Node node;

            // copy positions into array
            // necessary each time because node positions can change outside
            // this algorithm, by constraining to bbox and by user code.
            for (i = 0; i < this.mNodeCount; i++)
            {
                if (!this.mHidden[i])
                {
                    node = this.mGraph.NodeAt(i);
                    if (node.PositionFixed)
                    {
                        this.mXs[i] = node.X;
                        this.mYs[i] = node.Y;
                    }
                }
            }

            double nx, ny, deltaM, maxDeltaM = double.NegativeInfinity;
            int    pm = -1;

            // get the 'p' with max delta_m
            for (i = 0; i < this.mNodeCount; i++)
            {
                if (!this.mHidden[i])
                {
                    node = this.mGraph.NodeAt(i);
                    if (!node.PositionFixed)
                    {
                        deltaM = this.CalculateEnergyGradient(i);
                        if (maxDeltaM < deltaM)
                        {
                            maxDeltaM = deltaM;
                            pm        = i;
                        }
                    }
                }
            }
            // TODO: is this needed?
            if (pm == -1)
            {
                this.Abort();
                return;
            }

            // Calculate the delta_x & delta_y with the Newton-Raphson method
            // Upper-bound for the while (deltaM > epsilon) {...} cycle (100)
            for (i = 0; i < 100; i++)
            {
                this.CalcDeltaXY(pm);

                deltaM = this.CalculateEnergyGradient(pm);
                // real stop condition
                if (deltaM < double.Epsilon)
                {
                    break;
                }
            }

            // Perform the bounding constraints normally done by base layout
            // algorithm. It needs to be done here so cached positions don't
            // need to be copied over on every single iteration, but still
            // allow the energy calculations to compensate for it.
            node = this.mGraph.NodeAt(pm);
            Box2F nbox = node.LayoutBBox;

            if (this.mClusterNode == null)
            {
                double d;
                Box2F  bbox = this.BoundingBox;
                d            = nbox.W;
                this.mXs[pm] = Math.Min(Math.Max(this.mXs[pm] + nbox.X, bbox.X) + d, bbox.Right) - nbox.X - d;
                d            = nbox.H;
                this.mYs[pm] = Math.Min(Math.Max(this.mYs[pm] + nbox.Y, bbox.Y) + d, bbox.Bottom) - nbox.Y - d;
            }
            else
            {
                this.mClusterNode.LearnNodePos(
                    (float)this.mXs[pm], (float)this.mYs[pm], nbox);
                Vec2F pos = this.mClusterNode.AugmentNodePos(
                    (float)this.mXs[pm], (float)this.mYs[pm]);
                this.mXs[pm] = pos.X;
                this.mYs[pm] = pos.Y;
            }

            // What if two of the nodes were exchanged?
            if (this.bExchangeVertices && maxDeltaM < double.Epsilon)
            {
                double xenergy, energy = CalcEnergy();
                bool   noSwaps = true;
                for (i = 0; i < this.mNodeCount && noSwaps; i++)
                {
                    if (!this.mHidden[i])
                    {
                        for (j = 0; j < this.mNodeCount && noSwaps; j++)
                        {
                            if (i == j || this.mHidden[i])
                            {
                                continue;
                            }
                            xenergy = CalcEnergyIfExchanged(i, j);
                            if (energy > xenergy)
                            {
                                deltaM      = this.mXs[i];
                                this.mXs[i] = this.mXs[j];
                                this.mXs[j] = deltaM;
                                deltaM      = this.mYs[i];
                                this.mYs[i] = this.mYs[j];
                                this.mYs[j] = deltaM;
                                noSwaps     = false;
                            }
                        }
                    }
                }
            }
            // Use a linear transition to make the animation smooth
            // pos = pos + 0.1 * (newPos - pos) = 0.9 * pos + 0.1 * newPos
            for (i = 0; i < this.mNodeCount; i++)
            {
                if (!this.mHidden[i])
                {
                    node = this.mGraph.NodeAt(i);
                    if (!node.PositionFixed)
                    {
                        //node.SetPosition((float)this.mXPositions[i],
                        //                 (float)this.mYPositions[i]);
                        nx = 0.9 * node.X + 0.1 * this.mXs[i];
                        ny = 0.9 * node.Y + 0.1 * this.mYs[i];
                        node.SetPosition((float)nx, (float)ny);
                    }
                }
            }
        }
Ejemplo n.º 27
0
        protected override void PerformPrecalculations(
            uint lastNodeVersion, uint lastEdgeVersion)
        {
            bool isDirty = lastNodeVersion != this.mGraph.NodeVersion;

            if (isDirty)
            {
                Digraph <Node, Edge> .GNode gNode;
                this.mNodeCount = this.mGraph.NodeCount;
                // Cache the nodes for speed-up and in case the graph
                // is modified during the iteration.
                if (this.mHidden.Length < this.mNodeCount)
                {
                    this.mXs     = new double[this.mNodeCount];
                    this.mYs     = new double[this.mNodeCount];
                    this.mHidden = new bool[this.mNodeCount];
                }
                for (int k = 0; k < this.mNodeCount; k++)
                {
                    gNode           = this.mGraph.InternalNodeAt(k);
                    this.mXs[k]     = gNode.Data.X;
                    this.mYs[k]     = gNode.Data.Y;
                    this.mHidden[k] = gNode.Hidden;
                }
                this.bDirty = true;
            }

            isDirty = isDirty || lastEdgeVersion != this.mGraph.EdgeVersion;
            if (isDirty)
            {
                // Calculate the distances and diameter of the graph.
                this.mShortestPathsAlg.Reset();
                this.mShortestPathsAlg.Compute();
                this.mDistances = this.mShortestPathsAlg.Distances;
                this.mDiameter  = this.mShortestPathsAlg.GetDiameter();
                this.bDirty     = true;
            }

            if (this.bDirty)
            {
                Box2F bbox = this.mClusterNode == null
                    ? this.BoundingBox : this.mClusterNode.LayoutBBox;

                // L0 is the length of a side of the display area
                float L0 = Math.Min(bbox.W, bbox.H);

                // ideal length = L0 / max distance
                this.mIdealEdgeLength
                    = L0 * this.mLengthFactor / this.mDiameter;

                this.mMaxDistance
                    = this.mDiameter * this.mDisconnectedMultiplier;

                // Calculate the ideal distances between the nodes

                /*float dist;
                 * int i, j;
                 * for (i = 0; i < this.mNodeCount; i++)
                 * {
                 *  for (j = 0; j < this.mNodeCount; j++)
                 *  {
                 *      // distance between non-adjacent nodes
                 *      dist = (float)Math.Min(this.mDistances[i][j],
                 *                             this.mMaxDistance);
                 *      // calculate the minimal distance between the vertices
                 *      this.mDistances[i][j] = dist;
                 *  }
                 * }/* */
            }
            this.bDirty = false;
        }
 public LinLogLayoutAlgorithm(Digraph <Node, Edge> graph,
                              Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.MaxIterations = 100;
 }
Ejemplo n.º 29
0
 public ATreeLayoutAlgorithm(Digraph <Node, Edge> graph,
                             Box2F boundingBox)
     : base(graph, boundingBox)
 {
     this.mCCAlg = new CCAlgorithm <Node, Edge>(graph, false, false);
 }
Ejemplo n.º 30
0
        private void ShuffleNodesInternal(float bbx, float bby,
                                          float bbw, float bbh, bool immediate)
        {
            int    i, j, iter;
            bool   intersection;
            Node   node;
            float  x, y, bbxi, bbyi;
            Vec2F  pos;
            Box2F  bboxI, bboxJ;
            Random rnd   = new Random(DateTime.Now.Millisecond);
            int    count = this.mGraph.NodeCount;

            for (i = 0; i < count; i++)
            {
                node = this.mGraph.NodeAt(i);
                if (!node.PositionFixed)
                {
                    x     = y = 0;
                    bboxI = new Box2F(node.LayoutBBox);
                    bbxi  = bboxI.X;
                    bbyi  = bboxI.Y;
                    // Set the padding of the bounding box to bboxI
                    bbx -= bbxi;
                    bby -= bbyi;
                    bbw -= bboxI.W;
                    bbh -= bboxI.H;
                    // Iterate until a random position is found that doesn't
                    // intersect with any of the other already placed nodes.
                    intersection = true;
                    for (iter = 0; iter < 50 && intersection; iter++)
                    {
                        intersection = false;
                        x            = (float)(rnd.NextDouble() * bbw + bbx);
                        y            = (float)(rnd.NextDouble() * bbh + bby);
                        if (this.mClusterNode == null)
                        {
                            bboxI.X = bbxi + x;
                            bboxI.Y = bbyi + y;
                        }
                        else
                        {
                            pos     = this.mClusterNode.AugmentNodePos(x, y);
                            bboxI.X = bbxi + pos.X;
                            bboxI.Y = bbyi + pos.Y;
                        }
                        for (j = 0; j < i && !intersection; j++)
                        {
                            node = this.mGraph.NodeAt(j);
                            //if (!(node is IPortNode))
                            {
                                bboxJ        = new Box2F(node.LayoutBBox);
                                bboxJ.X     += node.X; //node.NewX;
                                bboxJ.Y     += node.Y; //node.NewY;
                                intersection = bboxI.IntersectsWith(bboxJ);
                                //intersection =
                                //    bboxJ.X < (bboxI.X + bboxI.Width) &&
                                //    bboxI.X < (bboxJ.X + bboxJ.Width) &&
                                //    bboxJ.Y < (bboxI.Y + bboxI.Height) &&
                                //    bboxI.Y < (bboxJ.Y + bboxJ.Height);
                            }
                        }
                    }
                    // Clear the padding of the bounding box
                    bbx += bbxi;
                    bby += bbyi;
                    bbw += bboxI.W;
                    bbh += bboxI.H;
                    // Set the node's new randomized position
                    node = this.mGraph.NodeAt(i);
                    node.SetPosition(x, y);//SetNewPosition(x, y);
                }
            }
            for (i = this.mGraph.EdgeCount - 1; i >= 0; i--)
            {
                this.mGraph.EdgeAt(i).Update();
            }

            /*if (immediate)
             * {
             *  for (i = 0; i < nodes.Length; i++)
             *  {
             *      node = nodes[i].Data;
             *      if (!node.PositionFixed)
             *          node.SetPosition(node.NewX, node.NewY);
             *  }
             *  Digraph<Node, Edge>.GEdge[] edges
             *      = this.mGraph.InternalEdges;
             *  for (i = 0; i < edges.Length; i++)
             *  {
             *      edges[i].Data.Update();
             *  }
             * }/* */
        }