示例#1
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();
            }
        }