/// <summary>
        /// populate the geometry including curve and arrowhead positioning for the given edge using simple
        /// straight line routing style.  Self edges will be drawn as a loop, padding is used to control the
        /// size of the loop.
        /// </summary>
        /// <param name="edge">edge to route</param>
        /// <param name="padding">controls size of loop</param>
        public static void RouteEdge(Edge edge, double padding)
        {
            ValidateArg.IsNotNull(edge, "edge");

            var eg = edge.EdgeGeometry;

            if (eg.SourcePort == null)
            {
#if SHARPKIT // Lambdas bind differently in JS
                eg.SourcePort = ((Func <Edge, RelativeFloatingPort>)(ed => new RelativeFloatingPort(() => ed.Source.BoundaryCurve,
                                                                                                    () => ed.Source.Center)))(edge);
#else
                eg.SourcePort = new RelativeFloatingPort(() => edge.Source.BoundaryCurve, () => edge.Source.Center);
#endif
            }

            if (eg.TargetPort == null)
            {
#if SHARPKIT // Lambdas bind differently in JS
                eg.TargetPort = ((Func <Edge, RelativeFloatingPort>)(ed => new RelativeFloatingPort(() => ed.Target.BoundaryCurve,
                                                                                                    () => ed.Target.Center)))(edge);
#else
                eg.TargetPort = new RelativeFloatingPort(() => edge.Target.BoundaryCurve, () => edge.Target.Center);
#endif
            }

            if (!ContainmentLoop(eg, padding))
            {
                eg.Curve = GetEdgeLine(edge);
            }

            Arrowheads.TrimSplineAndCalculateArrowheads(eg, eg.SourcePort.Curve,
                                                        eg.TargetPort.Curve, edge.Curve, false, false);
        }
示例#2
0
 /// <summary>
 /// add an incoming edge
 /// </summary>
 /// <param name="edge"></param>
 public void AddInEdge(Edge edge)
 {
     ValidateArg.IsNotNull(edge, "edge");
     Debug.Assert(edge.Source != edge.Target);
     Debug.Assert(edge.Target == this);
     inEdges_.Insert(edge);
 }
示例#3
0
            public int CompareTo(Event other)
            {
                ValidateArg.IsNotNull(other, "other");

                int cmp = 0;

                // Use a range so that rounding inaccuracy will give consistent results.
                if (Math.Abs(this.Position - other.Position) > OverlapRemovalGlobalConfiguration.EventComparisonEpsilon)
                {
                    cmp = this.Position.CompareTo(other.Position);
                }

                if (0 == cmp)
                {
                    // Sub-order by IsRendered (false precedes true, which is what we want).
                    cmp = this.IsForOpen.CompareTo(other.IsForOpen);

                    if (0 == cmp)
                    {
                        // Sub-order by node id
                        cmp = this.Node.Id.CompareTo(other.Node.Id);
                    }
                }
                return(cmp);
            }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="cornerFitRadius"></param>
        public static void CreateSimpleEdgeCurveWithGivenFitRadius(Edge edge, double cornerFitRadius)
        {
            ValidateArg.IsNotNull(edge, "edge");
            var a = edge.Source.Center;
            var b = edge.Target.Center;

            if (edge.Source == edge.Target)
            {
                var dx = edge.Source.BoundaryCurve.BoundingBox.Width / 2;
                var dy = edge.Source.BoundingBox.Height / 4;
                edge.UnderlyingPolyline = CreateUnderlyingPolylineForSelfEdge(a, dx, dy);
                for (var site = edge.UnderlyingPolyline.HeadSite.Next; site.Next != null; site = site.Next)
                {
                    CalculateCoefficiensUnderSite(site, cornerFitRadius);
                }
                edge.Curve = edge.UnderlyingPolyline.CreateCurve();
            }
            else
            {
                edge.UnderlyingPolyline = SmoothedPolyline.FromPoints(new[] { a, b });
                edge.Curve = edge.UnderlyingPolyline.CreateCurve();
            }

            if (!Arrowheads.TrimSplineAndCalculateArrowheads(edge.EdgeGeometry, edge.Source.BoundaryCurve, edge.Target.BoundaryCurve, edge.Curve,
                                                             true))
            {
                Arrowheads.CreateBigEnoughSpline(edge);
            }
        }
示例#5
0
 /// <summary>
 /// a constructor
 /// </summary>
 /// <param name="previousSite"></param>
 /// <param name="sitePoint"></param>
 public Site(Site previousSite, Point sitePoint)
 {
     ValidateArg.IsNotNull(previousSite, "pr");
     point             = sitePoint;
     prev              = previousSite;
     previousSite.next = this;
 }
示例#6
0
        public static void SpectralDecomposition(double[][] A,
                                                 out double[] u1, out double lambda1,
                                                 out double[] u2, out double lambda2, int maxIterations, double epsilon)
        {
            ValidateArg.IsNotNull(A, "A");
            int n = A[0].Length;

            u1 = RandomUnitLengthVector(n, 0); lambda1 = 0;
            u2 = RandomUnitLengthVector(n, 1); lambda2 = 0;
            double r     = 0;
            double limit = 1.0 - epsilon;

            // iterate until convergence but at most 30 steps
            for (int i = 0; (i < maxIterations && r < limit); i++)
            {
                double[] x1 = Multiply(A, u1);
                double[] x2 = Multiply(A, u2);

                lambda1 = Normalize(x1);
                lambda2 = Normalize(x2);
                MakeOrthogonal(x2, x1);
                Normalize(x2);

                // convergence is assumed if the inner product of
                // two consecutive (unit length) iterates is close to 1
                r  = Math.Min(DotProduct(u1, x1), DotProduct(u2, x2));
                u1 = x1;
                u2 = x2;
            }
        }
示例#7
0
 /// <summary>
 /// Adds the edge to the collection
 /// </summary>
 virtual public void Add(Edge item)
 {
     ValidateArg.IsNotNull(item, "item");
     item.GeometryParent = graph;
     edges.Add(item);
     AddEdgeToNodes(item);
 }
        /// <summary>
        /// Computes the "stress" of the current layout of the given graph:
        ///
        ///   stress = sum_{(u,v) in V} D(u,v)^(-2) (d(u,v) - D(u,v))^2
        ///
        /// where:
        ///   V is the set of nodes
        ///   d(u,v) is the euclidean distance between the centers of nodes u and v
        ///   D(u,v) is the graph-theoretic path length between u and v - scaled by average edge length.
        ///
        /// The idea of “stress” in graph layout is that nodes that are immediate neighbors should be closer
        /// together than nodes that are a few hops apart (i.e. that have path length>1).  More generally
        /// the distance between nodes in the drawing should be proportional to the path length between them.
        /// The lower the “stress” score of a particular graph layout the better it conforms to this ideal.
        ///
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public static double Stress(GeometryGraph graph)
        {
            ValidateArg.IsNotNull(graph, "graph");
            double stress = 0;

            if (graph.Edges.Count == 0)
            {
                return(stress);
            }
            var apd = new AllPairsDistances(graph);

            apd.Run();
            var    D = apd.Result;
            double l = graph.Edges.Average(e => e.Length);
            int    i = 0;

            foreach (var u in graph.Nodes)
            {
                int j = 0;
                foreach (var v in graph.Nodes)
                {
                    if (i != j)
                    {
                        double duv = (u.Center - v.Center).Length;
                        double Duv = l * D[i][j];
                        double d   = Duv - duv;
                        stress += d * d / (Duv * Duv);
                    }
                    ++j;
                }
                ++i;
            }
            return(stress);
        }
示例#9
0
        }                            //suppressing the creation of the public constructor

        /// <summary>
        /// Double-centers a matrix in such a way that the center of gravity is zero.
        /// After double-centering, each row and each column sums up to zero.
        /// </summary>
        /// <param name="matrix"></param>
        public static void DoubleCenter(double[][] matrix)
        {
            ValidateArg.IsNotNull(matrix, "matrix");
            double[] rowMean = new double[matrix.Length];
            double[] colMean = new double[matrix[0].Length];
            double   mean    = 0;

            for (int i = 0; i < matrix.Length; i++)
            {
                for (int j = 0; j < matrix[0].Length; j++)
                {
                    rowMean[i] += matrix[i][j];
                    colMean[j] += matrix[i][j];
                    mean       += matrix[i][j];
                }
            }
            for (int i = 0; i < matrix.Length; i++)
            {
                rowMean[i] /= matrix.Length;
            }
            for (int j = 0; j < matrix[0].Length; j++)
            {
                colMean[j] /= matrix[0].Length;
            }
            mean /= matrix.Length;
            mean /= matrix[0].Length;
            for (int i = 0; i < matrix.Length; i++)
            {
                for (int j = 0; j < matrix[0].Length; j++)
                {
                    matrix[i][j] -= rowMean[i] + colMean[j] - mean;
                }
            }
        }
        public int Compare(OverlapRemovalNode lhs, OverlapRemovalNode rhs)
        {
            ValidateArg.IsNotNull(lhs, "lhs");
            ValidateArg.IsNotNull(rhs, "rhs");

            return(lhs.CompareTo(rhs));
        }
示例#11
0
 /// <summary>
 /// Shallow copy the settings
 /// </summary>
 /// <param name="previousSettings"></param>
 public FastIncrementalLayoutSettings(FastIncrementalLayoutSettings previousSettings)
 {
     ValidateArg.IsNotNull(previousSettings, "previousSettings");
     maxIterations         = previousSettings.maxIterations;
     minorIterations       = previousSettings.minorIterations;
     projectionIterations  = previousSettings.projectionIterations;
     approximateRepulsion  = previousSettings.approximateRepulsion;
     initialStepSize       = previousSettings.initialStepSize;
     RungeKuttaIntegration = previousSettings.RungeKuttaIntegration;
     decay    = previousSettings.decay;
     friction = previousSettings.friction;
     repulsiveForceConstant  = previousSettings.repulsiveForceConstant;
     attractiveForceConstant = previousSettings.attractiveForceConstant;
     gravity = previousSettings.gravity;
     interComponentForces  = previousSettings.interComponentForces;
     applyForces           = previousSettings.applyForces;
     IdealEdgeLength       = previousSettings.IdealEdgeLength;
     AvoidOverlaps         = previousSettings.AvoidOverlaps;
     RespectEdgePorts      = previousSettings.RespectEdgePorts;
     RouteEdges            = previousSettings.RouteEdges;
     approximateRouting    = previousSettings.approximateRouting;
     logScaleEdgeForces    = previousSettings.logScaleEdgeForces;
     displacementThreshold = previousSettings.displacementThreshold;
     minConstraintLevel    = previousSettings.minConstraintLevel;
     maxConstraintLevel    = previousSettings.maxConstraintLevel;
     attractiveInterClusterForceConstant = previousSettings.attractiveInterClusterForceConstant;
     clusterGravity     = previousSettings.clusterGravity;
     PackingAspectRatio = previousSettings.PackingAspectRatio;
     NodeSeparation     = previousSettings.NodeSeparation;
     ClusterMargin      = previousSettings.ClusterMargin;
 }
示例#12
0
 /// <summary>
 /// constructor
 /// </summary>
 /// <param name="enumerableCollection"></param>
 public Set(IEnumerable <T> enumerableCollection)
 {
     ValidateArg.IsNotNull(enumerableCollection, "enumerableCollection");
     foreach (T j in enumerableCollection)
     {
         this.Insert(j);
     }
 }
示例#13
0
 public void PinNodesToMinLayer(params Node[] nodes)
 {
     ValidateArg.IsNotNull(nodes, "nodes");
     for (int i = 0; i < nodes.Length; i++)
     {
         VerticalConstraints.PinNodeToMinLayer(nodes[i]);
     }
 }
示例#14
0
 /// <summary>
 /// adds vertical up down constraints udDownIds[0]->upDownIds[1]-> ... -> upDownsIds[upDownIds.Length-1]
 /// </summary>
 /// <param name="upDownNodes"></param>
 public void AddUpDownVerticalConstraints(params Node[] upDownNodes)
 {
     ValidateArg.IsNotNull(upDownNodes, "upDownNodes");
     for (int i = 1; i < upDownNodes.Length; i++)
     {
         AddUpDownVerticalConstraint(upDownNodes[i - 1], upDownNodes[i]);
     }
 }
示例#15
0
 /// <summary>
 /// adds a same layer constraint
 /// </summary>
 public void PinNodesToSameLayer(params Node[] nodes)
 {
     ValidateArg.IsNotNull(nodes, "nodes");
     for (int i = 1; i < nodes.Length; i++)
     {
         VerticalConstraints.SameLayerConstraints.Insert(new Tuple <Node, Node>(nodes[0], nodes[i]));
     }
 }
示例#16
0
 /// <summary>
 /// inserts a range of elements into the set
 /// </summary>
 /// <param name="elements">elements to insert</param>
 public void InsertRange(IEnumerable <T> elements)
 {
     ValidateArg.IsNotNull(elements, "elements");
     foreach (var element in elements)
     {
         Insert(element);
     }
 }
示例#17
0
        /// <summary>
        /// Create a Shape with a single relative port at its center.
        /// </summary>
        /// <param name="node">The node from which the shape is derived</param>
        /// <returns></returns>
        public static Shape CreateShapeWithRelativeNodeAtCenter(Node node)
        {
            ValidateArg.IsNotNull(node, "node");
            var shape = new RelativeShape(() => node.BoundaryCurve);

            shape.Ports.Insert(new RelativeFloatingPort(() => node.BoundaryCurve, () => node.Center));
            return(shape);
        }
示例#18
0
        /// <summary>
        /// Add the parent cluster to this node's list of parents
        /// </summary>
        /// <param name="parent"></param>
        public void AddClusterParent(Cluster parent)
        {
            ValidateArg.IsNotNull(parent, "parent");
            Debug.Assert(this.clusterParent == null);

            Debug.Assert(parent != this);
            clusterParent = parent;
        }
示例#19
0
        void RemoveObstacleWithoutRebuild(Shape shape)
        {
            ValidateArg.IsNotNull(shape, "shape");
            Obstacle obstacle = ShapeToObstacleMap[shape];

            ShapeToObstacleMap.Remove(shape);
            PortManager.RemoveObstaclePorts(obstacle);
        }
示例#20
0
 /// <summary>
 /// creates a polyline from a point enumeration
 /// </summary>
 /// <param name="points"></param>
 public Polyline(IEnumerable <Point> points)
 {
     ValidateArg.IsNotNull(points, "points");
     foreach (var p in points)
     {
         AddPoint(p);
     }
 }
示例#21
0
 /// <summary>
 ///     Construct a cluster with the specified nodes and clusters as child members
 /// </summary>
 /// <param name="nodes"></param>
 /// <param name="clusters"></param>
 public Cluster(IEnumerable <Node> nodes, IEnumerable <Cluster> clusters)
     : this(nodes) {
     ValidateArg.IsNotNull(clusters, "clusters");
     foreach (Cluster c in clusters)
     {
         AddCluster(c);
     }
 }
示例#22
0
        /// <summary>
        /// imagine that direction points up,
        /// lower events have higher priorities,
        /// for events at the same level events to the left have higher priority
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public int Compare(SweepEvent a, SweepEvent b)
        {
            ValidateArg.IsNotNull(a, "a");
            ValidateArg.IsNotNull(b, "b");
            Point aSite = a.Site;
            Point bSite = b.Site;

            return(ComparePoints(ref aSite, ref bSite));
        }
示例#23
0
 /// <summary>
 /// Remove obstacles from the router.
 /// </summary>
 /// <param name="obstacles"></param>
 public void RemoveObstacles(IEnumerable <Shape> obstacles)
 {
     ValidateArg.IsNotNull(obstacles, "obstacles");
     foreach (var shape in obstacles)
     {
         RemoveObstacleWithoutRebuild(shape);
     }
     RebuildTreeAndGraph();
 }
示例#24
0
        public OptimalColumnPacking(IEnumerable <RectangleToPack <TData> > rectangles, double aspectRatio)
            : base(rectangles.ToList(), aspectRatio)
        {
            ValidateArg.IsNotNull(rectangles, "rectangles");
            Debug.Assert(rectangles.Any(), "Expected more than one rectangle in rectangles");
            Debug.Assert(aspectRatio > 0, "aspect ratio should be greater than 0");

            this.createPacking = (rs, height) => new ColumnPacking <TData>(rs, height);
        }
        public OptimalRectanglePacking(IEnumerable <RectangleToPack <TData> > rectangles, double aspectRatio)
            : base(RectanglePacking <TData> .SortRectangles(rectangles).ToList(), aspectRatio)
        {
            ValidateArg.IsNotNull(rectangles, "rectangles");
            Debug.Assert(rectangles.Any(), "Expected more than one rectangle in rectangles");
            Debug.Assert(aspectRatio > 0, "aspect ratio should be greater than 0");

            this.createPacking = (rs, width) => new RectanglePacking <TData>(rs, width, rectanglesPresorted: true);
        }
示例#26
0
 /// <summary>
 /// Create rectangle that is the bounding box of the given points
 /// </summary>
 public Rectangle(IEnumerable <Point> points)
     : this(0, 0, new Point(-1, -1))
 {
     ValidateArg.IsNotNull(points, "points");
     foreach (var p in points)
     {
         Add(p);
     }
 }
示例#27
0
 public Cluster(IEnumerable <Node> nodes)
     : this()
 {
     ValidateArg.IsNotNull(nodes, "nodes");
     foreach (Node v in nodes)
     {
         AddNode(v);
     }
 }
 /// <summary>
 /// trim the edge curve with the node boundaries
 /// </summary>
 /// <param name="edge"></param>
 /// <param name="spline"></param>
 /// <param name="narrowestInterval"></param>
 /// <param name="keepOriginalSpline">to keep the original spline</param>
 /// <returns></returns>
 public static bool TrimSplineAndCalculateArrowheads(Edge edge, ICurve spline, bool narrowestInterval, bool keepOriginalSpline)
 {
     ValidateArg.IsNotNull(edge, "edge");
     return(TrimSplineAndCalculateArrowheads(edge.EdgeGeometry,
                                             edge.Source.BoundaryCurve,
                                             edge.Target.BoundaryCurve,
                                             spline,
                                             narrowestInterval, keepOriginalSpline));
 }
示例#29
0
 /// <summary>
 /// Create rectangle that is the bounding box of the given Rectangles
 /// </summary>
 public Rectangle(IEnumerable <Rectangle> rectangles)
     : this(0, 0, new Point(-1, -1))
 {
     ValidateArg.IsNotNull(rectangles, "rectangles");
     foreach (var r in rectangles)
     {
         Add(r);
     }
 }
        /// <summary>
        /// Rotate a curve around a given point using radians
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="center"></param>
        /// <param name="angle"></param>
        /// <returns></returns>
        public static ICurve RotateCurveAroundCenterByRadian(ICurve curve, Point center, double angle)
        {
            ValidateArg.IsNotNull(curve, "curve");
            var c         = Math.Cos(angle);
            var s         = Math.Sin(angle);
            var transform = new PlaneTransformation(1, 0, center.X, 0, 1, center.Y) * new PlaneTransformation(c, -s, 0, s, c, 0) * new PlaneTransformation(1, 0, -center.X, 0, 1, -center.Y);

            return(curve.Transform(transform));
        }