Beispiel #1
0
        /// <summary>
        /// Divides an edge into segments by adding subdivision points to it
        /// </summary>
        ///
        /// <param name="ed">
        /// Edge data that is used for creating new subdivision points
        /// </param>
        ///
        /// <param name="subdivisionPointsNum">
        /// Number of subdivision points that should be created
        /// </param>
        private void DivideEdge(EdgeGroupData ed, int subdivisionPointsNum)
        {
            var r       = ed.length / (subdivisionPointsNum + 1);
            var sPoints = new Point[subdivisionPointsNum];

            ed.newControlPoints = new Point[subdivisionPointsNum];
            Point move;

            if (ed.length == 0)
            {
                move = new Point(0, 0);
            }
            else
            {
                move = VectorTools.Multiply(VectorTools.Minus(ed.v2, ed.v1), 1f / ed.length);
            }
            for (var i = 0; i < subdivisionPointsNum; i++)
            {
                sPoints[i] = VectorTools.Plus(ed.v1, VectorTools.Multiply(move, r * (i + 1)));
            }
            ed.controlPoints = sPoints;
            ed.k             = springConstant * (subdivisionPointsNum + 1) / ed.length;
            if (ed.k > 0.5f)
            {
                ed.k = 0.5f;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Finds an intersection point of the two lines
        /// </summary>
        ///
        /// <param name="p1">
        /// First point of the first line
        /// </param>
        ///
        /// <param name="p2">
        /// Second point of the first line
        /// </param>
        ///
        /// <param name="q1">
        /// First point of the second line
        /// </param>
        ///
        /// <param name="q2">
        /// Second point of the second line
        /// </param>
        ///
        /// <param name="intersection">
        /// Point of intersection
        /// </param>
        ///
        /// <param name="rp">
        /// Parameter used for determining on which segment the intersection point lies
        /// </param>
        ///
        /// <returns>
        /// True if lines are not parallel, false otherwise
        /// </returns>
        private bool Intersects(Point p1, Point p2, Point q1, Point q2, ref Point intersection, ref float rp)
        {
            var q = (p1.Y - q1.Y) * (q2.X - q1.X) - (p1.X - q1.X) * (q2.Y - q1.Y);
            var d = (p2.X - p1.X) * (q2.Y - q1.Y) - (p2.Y - p1.Y) * (q2.X - q1.X);

            if (d == 0) // parallel lines
            {
                return(false);
            }

            var r = q / d;

            q = (p1.Y - q1.Y) * (p2.X - p1.X) - (p1.X - q1.X) * (p2.Y - p1.Y);
            var s = q / d;

            intersection = VectorTools.Plus(p1, VectorTools.Multiply(VectorTools.Minus(p2, p1), r));

            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Calculates new positions for the control points of an edge by applying elastic and electrostatic forces to them
        /// </summary>
        ///
        /// <param name="o">
        /// Edge data that contains subdivision points to be moved
        /// </param>
        private void CalculateNewControlPoints(Object o)
        {
            var ed = (EdgeGroupData)o;

            for (var i = 0; i < subdivisionPoints; i++)
            {
                var   p = ed.controlPoints[i];
                Point p1, p2;
                if (i == 0)
                {
                    p1 = ed.v1;
                }
                else
                {
                    p1 = ed.controlPoints[i - 1];
                }
                if (i == (subdivisionPoints - 1))
                {
                    p2 = ed.v2;
                }
                else
                {
                    p2 = ed.controlPoints[i + 1];
                }
                //SizeF sp = new SizeF(p);
                var f = VectorTools.Multiply(VectorTools.Plus(VectorTools.Minus(p1, p), VectorTools.Minus(p2, p)), ed.k);
                var r = new Point(0, 0);
                foreach (var epd in ed.compatibleGroups.Values)
                {
                    Point         q;
                    var           j = 1f;
                    EdgeGroupData ed2;
                    if ((epd.ed1.id.k1 == ed.id.k1) && (epd.ed1.id.k2 == ed.id.k2))
                    {
                        ed2 = epd.ed2;
                    }
                    else
                    {
                        ed2 = epd.ed1;
                    }

                    if (epd.d)
                    {
                        q = ed2.controlPoints[i];
                    }
                    else
                    {
                        q = ed2.controlPoints[subdivisionPoints - i - 1];
                        if (directed && repulseOpposite)
                        {
                            j = repulsionCoefficient;
                        }
                    }
                    var fs = VectorTools.Minus(q, p);
                    //PointF fs = new PointF(q.X - p.X, q.Y - p.Y);

                    var l = VectorTools.Length(fs);
                    if (l > 0)//???
                    {
                        fs = VectorTools.Multiply(fs, epd.c / (l));

                        //fs = VectorTools.Multiply(fs, VectorTools.Length(fs) * ed2.edges.Count);
                        fs = VectorTools.Multiply(fs, VectorTools.Length(fs) * ed2.edgeCount);

                        r.X += (j * fs.X);
                        r.Y += (j * fs.Y);
                    }
                }

                var rl = VectorTools.Length(r);
                if (rl > 0)
                {
                    r = VectorTools.Multiply(r, (float)(1.0 / Math.Sqrt(rl)));
                }

                var move  = new Point(f.X + r.X, f.Y + r.Y);
                var moveL = VectorTools.Length(move);

                //float len = ed.Length / (subdivisionPoints + 1);
                //if (moveL > (len)) move = VectorTools.Multiply(move, len*cooldown / moveL);
                //if (moveL != 0) move = VectorTools.Multiply(move, cooldown / moveL);
                move = VectorTools.Multiply(move, cooldown * 0.5f);
                ed.newControlPoints[i] = VectorTools.Plus(move, p);

                if (ed.newControlPoints[i].X < AreaRectangle.Left)
                {
                    ed.newControlPoints[i].X = AreaRectangle.Left;
                }
                else
                if (ed.newControlPoints[i].X > AreaRectangle.Right)
                {
                    ed.newControlPoints[i].X = AreaRectangle.Right;
                }

                if (ed.newControlPoints[i].Y < AreaRectangle.Top)
                {
                    ed.newControlPoints[i].Y = AreaRectangle.Top;
                }
                else
                if (ed.newControlPoints[i].Y > AreaRectangle.Bottom)
                {
                    ed.newControlPoints[i].Y = AreaRectangle.Bottom;
                }
            }
            if (useThreading)
            {
                sem.Release();
            }
        }
Beispiel #4
0
 /// <summary>
 /// Moves the control points of all the edges of the graph closer to their original position on the straight edge
 /// </summary>
 ///
 /// <param name="graph">
 /// Graph whose edges should be straightened
 /// </param>
 ///
 /// <param name="s">
 /// Specifies the amount of straightening, from 0 to 1
 /// </param>
 public void StraightenEdges(TGraph graph, float s)
 {
     foreach (var e in graph.Edges)
     {
         if (e.IsSelfLoop)
         {
             continue;
         }
         var controlPoints    = e.RoutingPoints;//(PointF[])e.GetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints);
         var newControlPoints = new Point[controlPoints.Length];
         for (var i = 0; i < controlPoints.Length; i++)
         {
             //STRONG CHANGE
             var p = controlPoints[i];
             p = VectorTools.Plus(VectorTools.Multiply(p, 1 - s),
                                  VectorTools.Multiply(VectorTools.Plus(VertexPositions[e.Source],
                                                                        VectorTools.Multiply(VectorTools.Minus(VertexPositions[e.Target], VertexPositions[e.Source]),
                                                                                             1.0f * (i + 1) / (controlPoints.Length + 1))), s));
             newControlPoints[i].X = p.X;
             newControlPoints[i].Y = p.Y;
         }
         //e.SetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints, newControlPoints);
         e.RoutingPoints = newControlPoints;
     }
 }
Beispiel #5
0
 /// <summary>
 /// Straightens the edges using internal data sturctures
 /// </summary>
 ///
 /// <param name="groupsToStraighten">
 /// Groups of edges that should be straightened
 /// </param>
 ///
 /// <param name="s">
 /// Specifies the amount of straightening, from 0 to 1
 /// </param>
 private void StraightenEdgesInternally(Dictionary <KeyPair, EdgeGroupData> groupsToStraighten, float s)
 {
     foreach (var ed in groupsToStraighten.Values)
     {
         for (var i = 0; i < subdivisionPoints; i++)
         {
             //STRONG CHANGE
             var p = ed.controlPoints[i];
             p = VectorTools.Plus(VectorTools.Multiply(p, 1 - s),
                                  VectorTools.Multiply(VectorTools.Plus(ed.v1,
                                                                        VectorTools.Multiply(VectorTools.Minus(ed.v2, ed.v1),
                                                                                             1.0f * (i + 1) / (subdivisionPoints + 1))), s));
             ed.controlPoints[i].X = p.X;
             ed.controlPoints[i].Y = p.Y;
         }
     }
 }