예제 #1
0
        protected void IterateOne()
        {
            //create the forces (zero forces)
            var forces = new Dictionary <TVertex, VectorStd>();

            #region Repulsive forces
            var force = new VectorStd(0, 0);
            foreach (TVertex v in VisitedGraph.Vertices)
            {
                force.X = 0; force.Y = 0;
                SKPoint posV = VertexPositions[v];
                foreach (TVertex u in VisitedGraph.Vertices)
                {
                    //doesn't repulse itself
                    if (u.Equals(v))
                    {
                        continue;
                    }

                    //calculating repulsive force
                    VectorStd delta  = VectorStd.DifferenceVector(posV, VertexPositions[u]);
                    float     length = (float)Math.Max(delta.Length, double.Epsilon);
                    delta = delta / length * Parameters.ConstantOfRepulsion / length;

                    force += delta;
                }
                forces[v] = force;
            }
            #endregion

            #region Attractive forces
            foreach (TEdge e in VisitedGraph.Edges)
            {
                TVertex source = e.Source;
                TVertex target = e.Target;

                //vonzóerõ számítása a két pont közt
                VectorStd delta  = VectorStd.DifferenceVector(VertexPositions[source], VertexPositions[target]);
                float     length = (float)Math.Max(delta.Length, double.Epsilon);
                delta = delta / length * ((float)Math.Pow(length, 2)) / Parameters.ConstantOfAttraction;

                forces[source] -= delta;
                forces[target] += delta;
            }
            #endregion

            #region Limit displacement
            foreach (TVertex v in VisitedGraph.Vertices)
            {
                SKPoint pos = VertexPositions[v];

                //erõ limitálása a temperature-el
                VectorStd delta  = forces[v];
                float     length = (float)Math.Max(delta.Length, double.Epsilon);
                delta = delta / length * (float)Math.Min(delta.Length, _temperature);

                //erõhatás a pontra
                pos += delta;

                //falon ne menjünk ki
                pos.X = (float)Math.Min(_maxWidth, Math.Max(0, pos.X));
                pos.Y = (float)Math.Min(_maxHeight, Math.Max(0, pos.Y));
                VertexPositions[v] = pos;
            }
            #endregion
        }
예제 #2
0
        private void DrawEdge(SKCanvas canvas, Kaemika.Edge <Vertex> edge, float nodeHeight, float textSize, SKColor color, Swipe swipe)
        {
            bool spline = false; bool arc = false;

            using (var paint = new SKPaint()) {
                paint.TextSize = 10.0f; paint.IsAntialias = true; paint.Color = color;

                SKPoint source     = layoutInfo.vertexPositions[edge.Source];
                SKPoint target     = layoutInfo.vertexPositions[edge.Target];
                SKSize  sourceSize = layoutInfo.vertexSizes[edge.Source];
                SKSize  targetSize = layoutInfo.vertexSizes[edge.Target];

                if (layoutInfo.edgeRoutes == null)
                {
                    layoutInfo.edgeRoutes = new Dictionary <Kaemika.Edge <Vertex>, SKPoint[]>();
                }
                SKPoint[] route = (layoutInfo.edgeRoutes.ContainsKey(edge)) ? layoutInfo.edgeRoutes[edge] : new SKPoint[] { };

                var     routePath     = new SKPath(); paint.IsStroke = true;
                SKPoint initialTarget = (route.Length == 0) ? target : route[0];
                SKPoint firstSource   = PointOnRectangle(source, initialTarget, sourceSize.Width / 2, sourceSize.Height / 2);
                routePath.MoveTo(swipe % firstSource);
                SKPoint lastSource = firstSource;
                foreach (var nextTarget in route)
                {
                    if (spline)
                    {
                        (SKPoint control, SKPoint nextControl) = SplineControls(lastSource, nextTarget, new SKSize(textSize, textSize));
                        routePath.CubicTo(swipe % control, swipe % nextControl, swipe % nextTarget);
                    }
                    else
                    {
                        routePath.LineTo(swipe % nextTarget);
                    }
                    lastSource = nextTarget;
                }
                SKPoint lastTarget  = PointOnRectangle(target, lastSource, targetSize.Width / 2, targetSize.Height / 2);
                SKPoint firstTarget = (route.Length == 0) ? lastTarget : initialTarget;
                if (spline)
                {
                    (SKPoint control, SKPoint nextControl) = SplineControls(lastSource, lastTarget, new SKSize(textSize, textSize));
                    routePath.CubicTo(swipe % control, swipe % nextControl, swipe % lastTarget);
                }
                else if (arc && route.Length == 0)
                {
                    routePath.ArcTo(swipe % lastSource, swipe % lastTarget, swipe % textSize);                                // see Postscript arct
                }
                else
                {
                    routePath.LineTo(swipe % lastTarget);
                }
                canvas.DrawPath(routePath, paint);

                SKPoint arrowHeadBase = lastTarget;

                //SKPoint nextSource = source;
                //foreach (var nextTarget in route) {
                //    if (nextSource == source) nextSource = PointOnRectangle(source, nextTarget, sourceSize.Width / 2, sourceSize.Height / 2);
                //    canvas.DrawLine(swipe % nextSource, swipe % nextTarget, paint);
                //    nextSource = nextTarget;
                //}
                //SKPoint lastSource = (nextSource != source) ? nextSource : PointOnRectangle(source, target, sourceSize.Width / 2, sourceSize.Height / 2);
                //SKPoint lastTarget = PointOnRectangle(target, lastSource, targetSize.Width / 2, targetSize.Height / 2);
                //canvas.DrawLine(swipe % lastSource, swipe % lastTarget, paint);

                //SKPoint pointOnLine = lastTarget;

                if (edge.Directed != Directed.No)   // draw arrowhead, update arrowHeadBase
                {
                    VectorStd lineVector = VectorStd.DifferenceVector(lastTarget, lastSource);
                    float     lineLength = lineVector.Length;
                    // calculate point at base of arrowhead
                    float arrowWidth   = nodeHeight / 6;
                    float tPointOnLine = (float)(arrowWidth / (2 * (Math.Tan(120) / 2) * lineLength));
                    arrowHeadBase = lastTarget + (-tPointOnLine * lineVector);
                    VectorStd normalVector = new VectorStd(-lineVector.Y, lineVector.X);
                    float     tNormal      = arrowWidth / (2 * lineLength);
                    SKPoint   leftPoint    = arrowHeadBase + tNormal * normalVector;
                    SKPoint   rightPoint   = arrowHeadBase + -tNormal * normalVector;
                    if (edge.Directed == Directed.Solid)
                    {
                        var arrowPath = new SKPath(); paint.IsStroke = false;
                        arrowPath.MoveTo(swipe % leftPoint); arrowPath.LineTo(swipe % lastTarget);
                        arrowPath.LineTo(swipe % rightPoint); arrowPath.Close();
                        canvas.DrawPath(arrowPath, paint);
                    }
                    if (edge.Directed == Directed.Pointy)
                    {
                        var arrowPath = new SKPath(); paint.IsStroke = true;
                        arrowPath.MoveTo(swipe % leftPoint); arrowPath.LineTo(swipe % lastTarget);
                        arrowPath.LineTo(swipe % rightPoint);
                        canvas.DrawPath(arrowPath, paint);
                    }
                }

                if (edge.Label != null)   // draw label
                {
                    var saveTextSize = paint.TextSize;
                    paint.TextSize = swipe % textSize / 3;
                    SKPoint labelTarget = (route.Length == 0) ? arrowHeadBase : firstTarget;
                    GraphLayout.CanvasDrawTextCentered(canvas, edge.Label, swipe % new SKPoint((firstSource.X + labelTarget.X) / 2, (firstSource.Y + labelTarget.Y) / 2), paint, true);
                    paint.TextSize = saveTextSize;
                    //var path = new SKPath(); paint.IsStroke = false;
                    //path.MoveTo(swipe % firstSource);
                    //path.LineTo(swipe % ((route.Length == 0) ? arrowHeadBase : firstTarget));
                    //path.Close(); // so the text wraps back around the closed single-line path
                    //paint.TextSize = swipe % textSize / 3;
                    //canvas.DrawTextOnPath(edge.Label, path, new SKPoint(paint.TextSize/2, -paint.TextSize/2), paint);
                }
            }
        }
예제 #3
0
        private void DrawSplineEdge(SKCanvas canvas, Kaemika.Edge <Vertex> edge, float nodeHeight, float textSize, SKColor color, Swipe swipe)
        {
            if (edge.Source is Vertex_Routing)
            {
                return;                                // this edge it will be drawn as part of another edge
            }
            List <SKPoint> edgePath = new List <SKPoint>();

            Kaemika.Edge <Vertex> routedEdge = edge;
            (SKPoint firstSource, SKPoint firstTarget) = AddEdgePath(edgePath, routedEdge);
            while (routedEdge.Target is Vertex_Routing)
            {
                routedEdge = (routedEdge.Target as Vertex_Routing).toEdge;
                AddEdgePath(edgePath, routedEdge);
            }
            edgePath.Insert(0, edgePath[0]); // duplicate first point for spline
            SKPoint ultimate    = edgePath[edgePath.Count - 1];
            SKPoint penultimate = edgePath[edgePath.Count - 2];

            edgePath.Insert(edgePath.Count, ultimate); // duplicate last point for spline
            List <SKPoint> controlPoints = ControlPoints(edgePath);
            SKPath         path          = AddBeziers(new SKPath(), controlPoints.ToArray(), swipe);

            using (var paint = new SKPaint()) {
                paint.TextSize = 10.0f; paint.IsAntialias = true; paint.Color = color; paint.IsStroke = true;
                canvas.DrawPath(path, paint);

                SKPoint arrowHeadBase = ultimate;
                if (routedEdge.Directed != Directed.No)   // draw arrowhead on last routedEdge segment, update arrowHeadBase
                {
                    VectorStd lineVector = VectorStd.DifferenceVector(ultimate, penultimate);
                    float     lineLength = lineVector.Length;
                    // calculate point at base of arrowhead
                    float     arrowWidth         = nodeHeight / 6;
                    float     tPointOnLine       = (float)(arrowWidth / (2 * (Math.Tan(120) / 2) * lineLength));
                    VectorStd arrowReverseVector = -tPointOnLine * lineVector;
                    arrowHeadBase = ultimate + arrowReverseVector;
                    SKPoint   arrowHeadMid = ultimate + (0.5F * arrowReverseVector);
                    VectorStd normalVector = new VectorStd(-lineVector.Y, lineVector.X);
                    float     tNormal      = arrowWidth / (2 * lineLength);
                    SKPoint   leftPoint    = arrowHeadBase + tNormal * normalVector;
                    SKPoint   rightPoint   = arrowHeadBase + -tNormal * normalVector;
                    if (routedEdge.Directed == Directed.Solid)
                    {
                        var arrowPath = new SKPath(); paint.IsStroke = false;
                        arrowPath.MoveTo(swipe % leftPoint); arrowPath.LineTo(swipe % ultimate);
                        arrowPath.LineTo(swipe % rightPoint); arrowPath.Close();
                        canvas.DrawPath(arrowPath, paint);
                    }
                    if (routedEdge.Directed == Directed.Pointy)
                    {
                        var arrowPath = new SKPath(); paint.IsStroke = true;
                        arrowPath.MoveTo(swipe % leftPoint); arrowPath.LineTo(swipe % ultimate);
                        arrowPath.LineTo(swipe % rightPoint);
                        canvas.DrawPath(arrowPath, paint);
                    }
                    if (routedEdge.Directed == Directed.Ball)
                    {
                        var arrowPath = new SKPath(); paint.IsStroke = false;
                        canvas.DrawCircle(swipe % arrowHeadMid, swipe % (arrowReverseVector.Length / 2), paint);
                    }
                }
                // if (routedEdge.Directed == Directed.Solid) { paint.IsStroke = false; canvas.DrawCircle(path.LastPoint, 20, paint); }
                // if (routedEdge.Directed == Directed.Pointy) { paint.IsStroke = true; canvas.DrawCircle(path.LastPoint, 20, paint); }

                if (edge.Label != null)   // draw label on first routedEdge segment
                {
                    var saveTextSize = paint.TextSize;
                    paint.TextSize = swipe % textSize / 3;
                    SKPoint labelTarget = (firstTarget == ultimate) ? arrowHeadBase : firstTarget;
                    GraphLayout.CanvasDrawTextCentered(canvas, edge.Label, swipe % new SKPoint((firstSource.X + labelTarget.X) / 2, (firstSource.Y + labelTarget.Y) / 2), paint, true);
                    paint.TextSize = saveTextSize;
                }
            }
        }
        protected void CopyPositionsSilent(bool shouldTranslate)
        {
            //calculate the topLeft position
            var translation = new VectorStd(float.PositiveInfinity, float.PositiveInfinity);

            if (shouldTranslate)
            {
                foreach (var v in _graph.Vertices)
                {
                    if (double.IsNaN(v.RealPosition.X) || double.IsNaN(v.RealPosition.Y))
                    {
                        continue;
                    }

                    translation.X = Math.Min(v.RealPosition.X, translation.X);
                    translation.Y = Math.Min(v.RealPosition.Y, translation.Y);
                }
                translation   *= -1;
                translation.X += Parameters.VerticalGap / 2;
                translation.Y += Parameters.HorizontalGap / 2;

                //translate with the topLeft position
                foreach (var v in _graph.Vertices)
                {
                    v.RealPosition += translation;
                }
            }
            else
            {
                translation = new VectorStd(0, 0);
            }

            //copy the positions of the vertices
            VertexPositions.Clear();
            foreach (var v in _graph.Vertices)
            {
                if (v.IsDummyVertex)
                {
                    continue;
                }

                SKPoint pos = v.RealPosition;
                if (!shouldTranslate)
                {
                    pos.X += v.Size.Width * 0.5f + translation.X;
                    pos.Y += v.Size.Height * 0.5f + translation.Y;
                }
                VertexPositions[v.Original] = pos;
            }

            //copy the edge routes
            EdgeRoutes.Clear();
            foreach (var e in _graph.HiddenEdges)
            {
                if (!e.IsLongEdge)
                {
                    continue;
                }

                EdgeRoutes[e.Original] =
                    e.IsReverted
                        ? e.DummyVertices.Reverse().Select(dv => dv.RealPosition).ToArray()
                        : e.DummyVertices.Select(dv => dv.RealPosition).ToArray();
            }
        }