/// <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); }
/// <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); }
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); }
/// <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); } }
/// <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; }
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; } }
/// <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); }
} //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)); }
/// <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; }
/// <summary> /// constructor /// </summary> /// <param name="enumerableCollection"></param> public Set(IEnumerable <T> enumerableCollection) { ValidateArg.IsNotNull(enumerableCollection, "enumerableCollection"); foreach (T j in enumerableCollection) { this.Insert(j); } }
public void PinNodesToMinLayer(params Node[] nodes) { ValidateArg.IsNotNull(nodes, "nodes"); for (int i = 0; i < nodes.Length; i++) { VerticalConstraints.PinNodeToMinLayer(nodes[i]); } }
/// <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]); } }
/// <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])); } }
/// <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); } }
/// <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); }
/// <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; }
void RemoveObstacleWithoutRebuild(Shape shape) { ValidateArg.IsNotNull(shape, "shape"); Obstacle obstacle = ShapeToObstacleMap[shape]; ShapeToObstacleMap.Remove(shape); PortManager.RemoveObstaclePorts(obstacle); }
/// <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); } }
/// <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); } }
/// <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)); }
/// <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(); }
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); }
/// <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); } }
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)); }
/// <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)); }