コード例 #1
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
 public GroupPairData(float cc, EdgeGroupData e1, EdgeGroupData e2, bool dd)
 {
     c   = cc;
     ed1 = e1;
     ed2 = e2;
     d   = dd;
 }
コード例 #2
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <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)
        {
            float r = ed.length / (subdivisionPointsNum + 1);

            PointF[] sPoints = new PointF[subdivisionPointsNum];
            ed.newControlPoints = new PointF[subdivisionPointsNum];
            PointF move;

            if (ed.length == 0)
            {
                move = new PointF(0, 0);
            }
            else
            {
                move = VectorTools.Multiply(ed.v2 - new SizeF(ed.v1), 1f / ed.length);
            }
            for (int i = 0; i < subdivisionPointsNum; i++)
            {
                sPoints[i] = ed.v1 + new SizeF(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;
            }
        }
コード例 #3
0
ファイル: BundleEdgeRouting.cs プロジェクト: DaKaLKa/GraphX
        /// <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;
            }
        }
コード例 #4
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Collects data from the specified edge
        /// </summary>
        ///
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddEdgeData(IEdge e)
        {
            EdgeGroupData ed;
            KeyPair       key = new KeyPair(e.Vertices[0].ID, e.Vertices[1].ID);

            edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                PointF p1 = e.Vertices[0].Location;
                PointF p2 = e.Vertices[1].Location;
                ed    = new EdgeGroupData();
                ed.v1 = p1;
                ed.v2 = p2;
                ed.id = key;
                PointF mid = VectorTools.MidPoint(p1, p2);
                ed.middle           = mid;
                ed.length           = VectorTools.Distance(p1, p2);
                ed.compatibleGroups = new Dictionary <KeyPair, GroupPairData>();
                //ed.edges = new HashSet<int>();
                ed.edgeCount = 0;
                edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.edgeCount++;
        }
コード例 #5
0
 public GroupPairData(float cc, EdgeGroupData e1, EdgeGroupData e2, bool dd)
 {
     C   = cc;
     Ed1 = e1;
     Ed2 = e2;
     D   = dd;
 }
コード例 #6
0
ファイル: BundleEdgeRouting.cs プロジェクト: DaKaLKa/GraphX
        /// <summary>
        /// Collects data from the specified edge
        /// </summary>
        ///
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddEdgeData(TEdge e)
        {
            EdgeGroupData ed;
            var           key = new KeyPair(e.Source.ID, e.Target.ID);

            edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                var p1 = VertexPositions[e.Source]; // e.Vertices[0].Location;
                var p2 = VertexPositions[e.Target]; //e.Vertices[1].Location;
                ed    = new EdgeGroupData();
                ed.v1 = p1;
                ed.v2 = p2;
                ed.id = key;
                var mid = VectorTools.MidPoint(p1, p2);
                ed.middle           = mid;
                ed.length           = VectorTools.Distance(p1, p2);
                ed.compatibleGroups = new Dictionary <KeyPair, GroupPairData>();
                //ed.edges = new HashSet<int>();
                ed.edgeCount = 0;
                edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.edgeCount++;
        }
コード例 #7
0
ファイル: BundleEdgeRouting.cs プロジェクト: DaKaLKa/GraphX
        /// <summary>
        /// Calculates visibility coefficient of the two edges.
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float VisibilityCoefficient(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float c;
            var   p1 = ed1.v1;
            var   p2 = ed1.v2;
            var   q1 = ed2.v1;
            var   q2 = ed2.v2;

            var pn = new Point();

            pn.X = p1.Y - p2.Y;
            pn.Y = p2.X - p1.X;

            var pn1 = VectorTools.Plus(pn, p1);
            var pn2 = VectorTools.Plus(pn, p2);

            var i1 = new Point();
            var i2 = new Point();

            float r1 = 0, r2 = 0;

            if (!Intersects(q1, q2, p1, pn1, ref i1, ref r1))
            {
                return(0);
            }
            Intersects(q1, q2, p2, pn2, ref i2, ref r2);

            if ((r1 < 0 && r2 < 0) || (r1 > 1 && r2 > 1))
            {
                return(0);
            }

            var im = VectorTools.MidPoint(i1, i2);

            var qm = ed2.middle;

            var i = VectorTools.Distance(i1, i2);
            var m = VectorTools.Distance(qm, im);

            if (i == 0)
            {
                return(0);
            }

            c = 1f - 2f * m / i;

            if (c < 0)
            {
                return(0);
            }
            else
            {
                return(c);
            }
        }
コード例 #8
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates visibility coefficient of the two edges.
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float VisibilityCoefficient(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float  c;
            PointF p1 = ed1.v1;
            PointF p2 = ed1.v2;
            PointF q1 = ed2.v1;
            PointF q2 = ed2.v2;

            PointF pn = new PointF();

            pn.X = p1.Y - p2.Y;
            pn.Y = p2.X - p1.X;

            PointF pn1 = pn + new SizeF(p1);
            PointF pn2 = pn + new SizeF(p2);

            PointF i1 = new PointF();
            PointF i2 = new PointF();

            float r1 = 0, r2 = 0;

            if (!Intersects(q1, q2, p1, pn1, ref i1, ref r1))
            {
                return(0);
            }
            Intersects(q1, q2, p2, pn2, ref i2, ref r2);

            if ((r1 < 0 && r2 < 0) || (r1 > 1 && r2 > 1))
            {
                return(0);
            }

            PointF im = VectorTools.MidPoint(i1, i2);

            PointF qm = ed2.middle;

            float i = VectorTools.Distance(i1, i2);
            float m = VectorTools.Distance(qm, im);

            if (i == 0)
            {
                return(0);
            }

            c = 1f - 2f * m / i;

            if (c < 0)
            {
                return(0);
            }
            else
            {
                return(c);
            }
        }
コード例 #9
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates position compatibility of the two edges
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Position compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float PositionCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float avg = (ed1.length + ed2.length) / 2;
            float dis = VectorTools.Distance(ed1.middle, ed2.middle);

            if ((avg + dis) == 0)
            {
                return(0);
            }
            return(avg / (avg + dis));
        }
コード例 #10
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
 /// <summary>
 /// Calculates directedness of the two edges.
 /// </summary>
 ///
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 ///
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 ///
 /// <returns>
 /// True if edges have roughly the same direction, false otherwise
 /// </returns>
 private bool CalculateDirectedness(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     if ((VectorTools.Distance(ed1.v1, ed2.v1) + VectorTools.Distance(ed1.v2, ed2.v2)) <
         (VectorTools.Distance(ed1.v1, ed2.v2) + VectorTools.Distance(ed1.v2, ed2.v1)))
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
コード例 #11
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates visibility compatibility of the two edges.
        /// Uses lower of the two calculated visibility coefficients.
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Visibility compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float VisibilityCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float c1, c2;

            c1 = VisibilityCoefficient(ed1, ed2);
            if (c1 == 0)
            {
                return(0);
            }
            c2 = VisibilityCoefficient(ed2, ed1);

            return(Math.Min(c1, c2));
        }
コード例 #12
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates scale compatibility of the two edges
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Scale compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float ScaleCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float l1 = ed1.length;
            float l2 = ed2.length;
            float l  = l1 + l2;

            if (l == 0)
            {
                return(0);
            }
            else
            {
                float ret = 4 * l1 * l2 / (l * l);
                return(ret * ret);
            }
        }
コード例 #13
0
        /// <summary>
        /// Calculates scale compatibility of the two edges
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Scale compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float ScaleCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            var l1 = ed1.Length;
            var l2 = ed2.Length;
            var l  = l1 + l2;

            if (l == 0)
            {
                return(0);
            }
            else
            {
                var ret = 4 * l1 * l2 / (l * l);
                return(ret * ret);
            }
        }
コード例 #14
0
ファイル: BundleEdgeRouting.cs プロジェクト: DaKaLKa/GraphX
        /// <summary>
        /// Doubles subdivision points for an edge by adding one new subdivision point between each two
        /// </summary>
        ///
        /// <param name="ed">
        /// Edge data that contains subdivision points to be doubled
        /// </param>
        private void DoubleSubdivisionPoints(EdgeGroupData ed)
        {
            if (subdivisionPoints == 0) //make one subdivision point
            {
                ed.k = springConstant * 2 / ed.length;
                if (ed.k > 0.5f)
                {
                    ed.k = 0.5f;
                }
                ed.controlPoints    = new Point[1];
                ed.newControlPoints = new Point[1];
                ed.controlPoints[0] = ed.middle;

                return;
            }

            var sPoints        = ed.controlPoints;
            var sPointsDoubled = new Point[subdivisionPoints * 2 + 1];

            ed.newControlPoints = new Point[subdivisionPoints * 2 + 1];
            for (var i = 0; i < subdivisionPoints; i++)
            {
                sPointsDoubled[i * 2 + 1] = sPoints[i];
            }


            for (var i = 0; i < subdivisionPoints - 1; i++)
            {
                sPointsDoubled[i * 2 + 2] = VectorTools.MidPoint(sPoints[i], sPoints[i + 1]);
            }


            sPointsDoubled[0] = VectorTools.MidPoint(ed.v1, sPoints[0]);
            sPointsDoubled[subdivisionPoints * 2] = VectorTools.MidPoint(sPoints[subdivisionPoints - 1], ed.v2);
            //ed.K = springConstant * (subdivisionPoints * 2 + 2) / ed.Length;
            ed.k *= 2f;
            if (ed.k > 0.5f)
            {
                ed.k = 0.5f;
            }
            ed.controlPoints = sPointsDoubled;
        }
コード例 #15
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;

            move = ed.Length == 0 ? new Point(0, 0) : 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;
            }
        }
コード例 #16
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Collects data from the specified edge.
        /// Used for edges that already have control points metadata.
        /// </summary>
        ///
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddExistingData(IEdge e)
        {
            EdgeGroupData ed;
            KeyPair       key = new KeyPair(e.Vertices[0].ID, e.Vertices[1].ID);

            edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                PointF p1 = e.Vertices[0].Location;
                PointF p2 = e.Vertices[1].Location;
                ed    = new EdgeGroupData();
                ed.v1 = p1;
                ed.v2 = p2;
                ed.id = key;
                PointF mid = VectorTools.MidPoint(p1, p2);
                ed.middle = mid;
                ed.length = VectorTools.Distance(p1, p2);

                ed.controlPoints = (PointF[])e.GetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints);

                if (subdivisionPoints == 0)
                {
                    subdivisionPoints = ed.controlPoints.Length;
                }
                ed.newControlPoints = new PointF[subdivisionPoints];
                ed.k = springConstant * (subdivisionPoints + 1) / ed.length;
                if (ed.k > 0.5f)
                {
                    ed.k = 0.5f;
                }
                //ed.edges = new HashSet<int>();
                ed.edgeCount        = 0;
                ed.compatibleGroups = new Dictionary <KeyPair, GroupPairData>();
                edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.edgeCount++;
        }
コード例 #17
0
        /// <summary>
        /// Collects data from the specified edge.
        /// Used for edges that already have control points metadata.
        /// </summary>
        ///
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddExistingData(TEdge e)
        {
            EdgeGroupData ed;
            var           key = new KeyPair(e.Source.ID, e.Target.ID);

            _edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                var p1 = VertexPositions[e.Source]; // e.Vertices[0].Location;
                var p2 = VertexPositions[e.Target]; //e.Vertices[1].Location;
                ed = new EdgeGroupData {
                    V1 = p1, V2 = p2, ID = key
                };
                var mid = VectorTools.MidPoint(p1, p2);
                ed.Middle = mid;
                ed.Length = VectorTools.Distance(p1, p2);

                ed.ControlPoints = e.RoutingPoints; //e.GetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints);

                if (_subdivisionPoints == 0)
                {
                    _subdivisionPoints = ed.ControlPoints.Length;
                }
                ed.NewControlPoints = new Point[_subdivisionPoints];
                ed.K = _springConstant * (_subdivisionPoints + 1) / ed.Length;
                if (ed.K > 0.5f)
                {
                    ed.K = 0.5f;
                }
                //ed.edges = new HashSet<int>();
                ed.EdgeCount        = 0;
                ed.CompatibleGroups = new Dictionary <KeyPair, GroupPairData>();
                _edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.EdgeCount++;
        }
コード例 #18
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates compatibility of the two edges.
        /// Combines angle, position, scale, and visibility compatibility coefficient.
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float CalculateCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float c = PositionCompatibility(ed1, ed2);

            if (c > threshold)
            {
                c *= ScaleCompatibility(ed1, ed2);
            }
            else
            {
                return(0);
            }
            if (c > threshold)
            {
                c *= AngleCompatibility(ed1, ed2);
            }
            else
            {
                return(0);
            }
            if (c > threshold)
            {
                c *= VisibilityCompatibility(ed1, ed2);
            }
            else
            {
                return(0);
            }
            if (c > threshold)
            {
                return(c);
            }
            else
            {
                return(0);
            }
        }
コード例 #19
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)
 {
     float r = ed.length / (subdivisionPointsNum + 1);
     PointF[] sPoints = new PointF[subdivisionPointsNum];
     ed.newControlPoints = new PointF[subdivisionPointsNum];
     PointF move;
     if (ed.length == 0)
         move = new PointF(0, 0);
     else
         move = VectorTools.Multiply(ed.v2 - new SizeF(ed.v1), 1f / ed.length);
     for (int i = 0; i < subdivisionPointsNum; i++)
         sPoints[i] = ed.v1 + new SizeF(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;
 }
コード例 #20
0
 /// <summary>
 /// Calculates position compatibility of the two edges
 /// </summary>
 /// 
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 /// 
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 /// 
 /// <returns>
 /// Position compatibility coefficient ranging from 0 to 1
 /// </returns>
 private float PositionCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     float avg = (ed1.length + ed2.length) / 2;
     float dis = VectorTools.Distance(ed1.middle, ed2.middle);
     if ((avg + dis) == 0) return 0;
     return (avg / (avg + dis));
 }
コード例 #21
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <summary>
        /// Calculates angle compatibility of the two edges
        /// </summary>
        ///
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        ///
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        ///
        /// <returns>
        /// Angle compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float AngleCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float a = VectorTools.Angle(ed1.v1, ed1.v2, ed2.v1, ed2.v2);

            return((float)Math.Abs(Math.Cos(a)));
        }
コード例 #22
0
 /// <summary>
 /// Calculates scale compatibility of the two edges
 /// </summary>
 /// 
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 /// 
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 /// 
 /// <returns>
 /// Scale compatibility coefficient ranging from 0 to 1
 /// </returns>
 private float ScaleCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     float l1 = ed1.length;
     float l2 = ed2.length;
     float l = l1 + l2;
     if (l == 0)
         return 0;
     else
     {
         float ret = 4 * l1 * l2 / (l * l);
         return ret * ret;
     }
 }
コード例 #23
0
 public GroupPairData(float cc, EdgeGroupData e1, EdgeGroupData e2, bool dd)
 {
     c = cc;
     ed1 = e1;
     ed2 = e2;
     d = dd;
 }
コード例 #24
0
 /// <summary>
 /// Calculates angle compatibility of the two edges
 /// </summary>
 /// 
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 /// 
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 /// 
 /// <returns>
 /// Angle compatibility coefficient ranging from 0 to 1
 /// </returns>
 private float AngleCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     float a = VectorTools.Angle(ed1.v1, ed1.v2, ed2.v1, ed2.v2);
     return (float)Math.Abs(Math.Cos(a));
 }
コード例 #25
0
        /// <summary>
        /// Calculates visibility compatibility of the two edges.
        /// Uses lower of the two calculated visibility coefficients.
        /// </summary>
        /// 
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        /// 
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        /// 
        /// <returns>
        /// Visibility compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float VisibilityCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float c1, c2;

            c1 = VisibilityCoefficient(ed1, ed2);
            if (c1 == 0)
                return 0;
            c2 = VisibilityCoefficient(ed2, ed1);

            return Math.Min(c1, c2);
        }
コード例 #26
0
        /// <summary>
        /// Calculates visibility coefficient of the two edges.
        /// </summary>
        /// 
        /// <param name="ed1">
        /// First edge to be used in calculation
        /// </param>
        /// 
        /// <param name="ed2">
        /// Second edge to be used in calculation
        /// </param>
        /// 
        /// <returns>
        /// Compatibility coefficient ranging from 0 to 1
        /// </returns>
        private float VisibilityCoefficient(EdgeGroupData ed1, EdgeGroupData ed2)
        {
            float c;
            PointF p1 = ed1.v1;
            PointF p2 = ed1.v2;
            PointF q1 = ed2.v1;
            PointF q2 = ed2.v2;

            PointF pn = new PointF();
            pn.X = p1.Y - p2.Y;
            pn.Y = p2.X - p1.X;

            PointF pn1 = pn + new SizeF(p1);
            PointF pn2 = pn + new SizeF(p2);

            PointF i1 = new PointF();
            PointF i2 = new PointF();

            float r1 = 0, r2 = 0;

            if (!Intersects(q1, q2, p1, pn1, ref i1, ref r1)) return 0;
            Intersects(q1, q2, p2, pn2, ref i2, ref r2);

            if ((r1 < 0 && r2 < 0) || (r1 > 1 && r2 > 1)) return 0;

            PointF im = VectorTools.MidPoint(i1, i2);

            PointF qm = ed2.middle;

            float i = VectorTools.Distance(i1, i2);
            float m = VectorTools.Distance(qm, im);

            if (i == 0) return 0;

            c = 1f - 2f * m / i;

            if (c < 0)
                return 0;
            else
                return c;
        }
コード例 #27
0
        /// <summary>
        /// Collects data from the specified edge.
        /// Used for edges that already have control points metadata.
        /// </summary>
        /// 
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddExistingData(IEdge e)
        {
            EdgeGroupData ed;
            KeyPair key = new KeyPair(e.Vertices[0].ID, e.Vertices[1].ID);

            edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                PointF p1 = e.Vertices[0].Location;
                PointF p2 = e.Vertices[1].Location;
                ed = new EdgeGroupData();
                ed.v1 = p1;
                ed.v2 = p2;
                ed.id = key;
                PointF mid = VectorTools.MidPoint(p1, p2);
                ed.middle = mid;
                ed.length = VectorTools.Distance(p1, p2);

                ed.controlPoints = (PointF[])e.GetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints);

                if (subdivisionPoints == 0) subdivisionPoints = ed.controlPoints.Length;
                ed.newControlPoints = new PointF[subdivisionPoints];
                ed.k = springConstant * (subdivisionPoints + 1) / ed.length;
                if (ed.k > 0.5f) ed.k = 0.5f;
                //ed.edges = new HashSet<int>();
                ed.edgeCount = 0;
                ed.compatibleGroups = new Dictionary<KeyPair, GroupPairData>();
                edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.edgeCount++;
        }
コード例 #28
0
 /// <summary>
 /// Calculates directedness of the two edges.
 /// </summary>
 /// 
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 /// 
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 /// 
 /// <returns>
 /// True if edges have roughly the same direction, false otherwise
 /// </returns>
 private bool CalculateDirectedness(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     if ((VectorTools.Distance(ed1.v1, ed2.v1) + VectorTools.Distance(ed1.v2, ed2.v2)) <
         (VectorTools.Distance(ed1.v1, ed2.v2) + VectorTools.Distance(ed1.v2, ed2.v1)))
         return true;
     else return false;
 }
コード例 #29
0
 /// <summary>
 /// Calculates compatibility of the two edges.
 /// Combines angle, position, scale, and visibility compatibility coefficient.
 /// </summary>
 /// 
 /// <param name="ed1">
 /// First edge to be used in calculation
 /// </param>
 /// 
 /// <param name="ed2">
 /// Second edge to be used in calculation
 /// </param>
 /// 
 /// <returns>
 /// Compatibility coefficient ranging from 0 to 1
 /// </returns>
 private float CalculateCompatibility(EdgeGroupData ed1, EdgeGroupData ed2)
 {
     float c = PositionCompatibility(ed1, ed2);
     if (c > threshold) c *= ScaleCompatibility(ed1, ed2);
     else return 0;
     if (c > threshold) c *= AngleCompatibility(ed1, ed2);
     else return 0;
     if (c > threshold) c *= VisibilityCompatibility(ed1, ed2);
     else return 0;
     if (c > threshold)
         return c;
     else return 0;
 }
コード例 #30
0
        /// <summary>
        /// Doubles subdivision points for an edge by adding one new subdivision point between each two
        /// </summary>
        /// 
        /// <param name="ed">
        /// Edge data that contains subdivision points to be doubled
        /// </param>
        private void DoubleSubdivisionPoints(EdgeGroupData ed)
        {
            if (subdivisionPoints == 0) //make one subdivision point
            {
                ed.k = springConstant * 2 / ed.length;
                if (ed.k > 0.5f) ed.k = 0.5f;
                ed.controlPoints = new PointF[1];
                ed.newControlPoints = new PointF[1];
                ed.controlPoints[0] = ed.middle;

                return;
            }

            PointF[] sPoints = ed.controlPoints;
            PointF[] sPointsDoubled = new PointF[subdivisionPoints * 2 + 1];
            ed.newControlPoints = new PointF[subdivisionPoints * 2 + 1];
            for (int i = 0; i < subdivisionPoints; i++)
                sPointsDoubled[i * 2 + 1] = sPoints[i];


            for (int i = 0; i < subdivisionPoints - 1; i++)
                sPointsDoubled[i * 2 + 2] = VectorTools.MidPoint(sPoints[i], sPoints[i + 1]);


            sPointsDoubled[0] = VectorTools.MidPoint(ed.v1, sPoints[0]);
            sPointsDoubled[subdivisionPoints * 2] = VectorTools.MidPoint(sPoints[subdivisionPoints - 1], ed.v2);
            //ed.K = springConstant * (subdivisionPoints * 2 + 2) / ed.Length;
            ed.k *= 2f;
            if (ed.k > 0.5f) ed.k = 0.5f;
            ed.controlPoints = sPointsDoubled;
        }
コード例 #31
0
ファイル: EdgeBundler.cs プロジェクト: yesbb12/ParallelBFS
        /// <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)
        {
            EdgeGroupData ed = (EdgeGroupData)o;

            for (int i = 0; i < subdivisionPoints; i++)
            {
                PointF p = ed.controlPoints[i];
                PointF 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);
                PointF f  = VectorTools.Multiply((p1 - sp) + new SizeF((p2 - sp)), ed.k);
                PointF r  = new PointF(0, 0);
                foreach (GroupPairData epd in ed.compatibleGroups.Values)
                {
                    PointF        q;
                    float         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;
                        }
                    }
                    PointF fs = q - sp;
                    //PointF fs = new PointF(q.X - p.X, q.Y - p.Y);

                    float 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);
                    }
                }

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

                PointF move  = new PointF(f.X + r.X, f.Y + r.Y);
                float  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] = move + sp;

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

                if (ed.newControlPoints[i].Y < rectangle.Top)
                {
                    ed.newControlPoints[i].Y = rectangle.Top;
                }
                else
                if (ed.newControlPoints[i].Y > rectangle.Bottom)
                {
                    ed.newControlPoints[i].Y = rectangle.Bottom;
                }
            }
            if (useThreading)
            {
                sem.Release();
            }
        }
コード例 #32
0
        /// <summary>
        /// Collects data from the specified edge
        /// </summary>
        /// 
        /// <param name="e">
        /// Edge to collect data from
        /// </param>
        private void AddEdgeData(IEdge e)
        {
            EdgeGroupData ed;
            KeyPair key = new KeyPair(e.Vertices[0].ID, e.Vertices[1].ID);

            edgeGroupData.TryGetValue(key, out ed);

            if (ed == null)
            {
                PointF p1 = e.Vertices[0].Location;
                PointF p2 = e.Vertices[1].Location;
                ed = new EdgeGroupData();
                ed.v1 = p1;
                ed.v2 = p2;
                ed.id = key;
                PointF mid = VectorTools.MidPoint(p1, p2);
                ed.middle = mid;
                ed.length = VectorTools.Distance(p1, p2);
                ed.compatibleGroups = new Dictionary<KeyPair, GroupPairData>();
                //ed.edges = new HashSet<int>();
                ed.edgeCount = 0;
                edgeGroupData.Add(key, ed);
            }
            //ed.edges.Add(e.ID);
            ed.edgeCount++;
        }