예제 #1
0
        protected virtual double getlength()
        {
            double length = 0;

            for (int i = 0; i < 10000; i++)
                length += new LineD(GetCoordinate((i + 1)/10000.0), GetCoordinate(i/10000.0)).Length;

            return length;
        }
예제 #2
0
        public override Bezier GetTranslatedBezier(bool reverse, double translation)
        {
            PointD q0;
            PointD q1;
            PointD q2;

            if (reverse)
            {
                q0 = p2 + GetDirection(1).GetLeftHandNormal()*translation;
                q2 = p0 + GetDirection(0).GetLeftHandNormal()*translation;
                q1 = new LineD(q0, GetVelocity(1)).GetCrossingPoint(new LineD(q2, GetVelocity(0)));
            }
            else
            {
                q0 = p0 + GetDirection(0).GetRightHandNormal()*translation;
                q2 = p2 + GetDirection(1).GetRightHandNormal()*translation;
                q1 = new LineD(q0, GetVelocity(0)).GetCrossingPoint(new LineD(q2, GetVelocity(1)));
            }

            return new QuadraticBezier(q0, q1, q2);
        }
예제 #3
0
        public override Bezier GetTranslatedBezier(bool reverse, double translation)
        {
            var distancehashset = new HashSet<double>();

            PointD q0;
            PointD q1;
            PointD q2;
            PointD q3;

            PointD c25;
            PointD c50;
            PointD c75;

            VectorD direction0;
            VectorD direction1;

            double distance = 0;

            // Determine the controlpoints of the new Bézier curve and points of the current curve with which
            // you want to calibrate.
            if (reverse)
            {
                q0 = p3 + GetDirection(1).GetLeftHandNormal()*translation;
                q1 = p2 + GetDirection(1).GetLeftHandNormal()*translation;
                q2 = p1 + GetDirection(0).GetLeftHandNormal()*translation;
                q3 = p0 + GetDirection(0).GetLeftHandNormal()*translation;

                c25 = GetCoordinate(0.75) + translation*GetDirection(0.75).GetLeftHandNormal();
                c50 = GetCoordinate(0.50) + translation*GetDirection(0.50).GetLeftHandNormal();
                c75 = GetCoordinate(0.25) + translation*GetDirection(0.25).GetLeftHandNormal();

                direction0 = GetDirection(1);
                direction1 = GetDirection(0);
            }
            else
            {
                q0 = p0 + GetDirection(0).GetRightHandNormal()*translation;
                q1 = p1 + GetDirection(0).GetRightHandNormal()*translation;
                q2 = p2 + GetDirection(1).GetRightHandNormal()*translation;
                q3 = p3 + GetDirection(1).GetRightHandNormal()*translation;

                c25 = GetCoordinate(0.25) + translation*GetDirection(0.25).GetRightHandNormal();
                c50 = GetCoordinate(0.50) + translation*GetDirection(0.50).GetRightHandNormal();
                c75 = GetCoordinate(0.75) + translation*GetDirection(0.75).GetRightHandNormal();

                direction0 = GetDirection(0).GetInvertedVector();
                direction1 = GetDirection(1).GetInvertedVector();
            }

            // Determine the distance between the calibrationpoint for the new Bézier curve.
            distance += new LineD(getcoordinate(0.25, q0, q1, q2, q3), c25).Length;
            distance += new LineD(getcoordinate(0.50, q0, q1, q2, q3), c50).Length;
            distance += new LineD(getcoordinate(0.75, q0, q1, q2, q3), c75).Length;

            distancehashset.Add(distance);

            for (int i = 0; i < 1000; i++)
                // Try to improve the control points 1000 times as described in the Bézier curve pdf
            {
                PointD q1backup = q1;
                PointD q2backup = q2;

                var distancesnew = new List<double>(new double[4]);

                q1 = q1backup - 0.01*direction0;
                distancesnew[0] += new LineD(getcoordinate(0.25, q0, q1, q2, q3), c25).Length;
                distancesnew[0] += new LineD(getcoordinate(0.50, q0, q1, q2, q3), c50).Length;
                distancesnew[0] += new LineD(getcoordinate(0.75, q0, q1, q2, q3), c75).Length;

                q1 = q1backup + 0.01*direction0;
                distancesnew[1] += new LineD(getcoordinate(0.25, q0, q1, q2, q3), c25).Length;
                distancesnew[1] += new LineD(getcoordinate(0.50, q0, q1, q2, q3), c50).Length;
                distancesnew[1] += new LineD(getcoordinate(0.75, q0, q1, q2, q3), c75).Length;

                q2 = q2backup - 0.01*direction1;
                distancesnew[2] += new LineD(getcoordinate(0.25, q0, q1, q2, q3), c25).Length;
                distancesnew[2] += new LineD(getcoordinate(0.50, q0, q1, q2, q3), c50).Length;
                distancesnew[2] += new LineD(getcoordinate(0.75, q0, q1, q2, q3), c75).Length;

                q2 = q2backup + 0.01*direction1;
                distancesnew[3] += new LineD(getcoordinate(0.25, q0, q1, q2, q3), c25).Length;
                distancesnew[3] += new LineD(getcoordinate(0.50, q0, q1, q2, q3), c50).Length;
                distancesnew[3] += new LineD(getcoordinate(0.75, q0, q1, q2, q3), c75).Length;

                int minindex = distancesnew.IndexOf(distancesnew.Min());

                switch (minindex)
                {
                    case 0:
                        q1 = q1backup - 0.01*direction0;
                        break;
                    case 1:
                        q1 = q1backup + 0.01*direction0;
                        break;
                    case 2:
                        q2 = q2backup - 0.01*direction1;
                        break;
                    case 3:
                        q2 = q2backup + 0.01*direction1;
                        break;
                }

                distance = distancesnew[minindex];

                if (distancehashset.Contains(distance))
                    break;
                distancehashset.Add(distance);
            }

            return new CubicBezier(q0, q1, q2, q3);
        }
예제 #4
0
 public PointD GetCrossingPoint(LineD line)
 {
     return GetCrossingPoint(this, line);
 }
예제 #5
0
        // http://mathworld.wolfram.com/Line-LineIntersection.html
        private static PointD GetCrossingPoint(LineD line1, LineD line2)
        {
            double x1 = line1.Point1.X;
            double x2 = line1.Point2.X;
            double x3 = line2.Point1.X;
            double x4 = line2.Point2.X;

            double y1 = line1.Point1.Y;
            double y2 = line1.Point2.Y;
            double y3 = line2.Point1.Y;
            double y4 = line2.Point2.Y;

            double x = ((x1*y2 - y1*x2)*(x3 - x4) - (x1 - x2)*(x3*y4 - y3*x4))/
                       ((x1 - x2)*(y3 - y4) - (x3 - x4)*(y1 - y2));
            double y = ((x1*y2 - y1*x2)*(y3 - y4) - (y1 - y2)*(x3*y4 - y3*x4))/
                       ((x1 - x2)*(y3 - y4) - (x3 - x4)*(y1 - y2));

            return new PointD(x, y);
        }
예제 #6
0
 public bool IsCoLinearWith(LineD line)
 {
     return new VectorD(Point1, Point2).IsCoLinearWith(new VectorD(line.Point1, line.Point2)) &&
            GetDistance(line.Point1) < 0.001;
 }
예제 #7
0
        private void MakeCrossingGraphicsPath()
        {
            int length = cornerpoints.Length;

            graphicspath = new GraphicsPath();

            for (int i = 0; i < cornerpoints.Length; i++)
            {
                if (i%2 == 0)
                    graphicspath.AddLine(cornerpoints[i], cornerpoints[i + 1]);
                else
                {
                    VectorD vector1 =
                        new VectorD(cornerpoints[(i - 1)%length], cornerpoints[(i)%length]).GetRightHandNormal();
                    VectorD vector2 =
                        new VectorD(cornerpoints[(i + 1)%length], cornerpoints[(i + 2)%length]).GetRightHandNormal();

                    if (vector1.IsCoLinearWith(vector2))
                        graphicspath.AddLine(cornerpoints[(i)%length], cornerpoints[(i + 1)%length]);
                    else
                    {
                        var line1 = new LineD(cornerpoints[(i)%length], vector1);
                        var line2 = new LineD(cornerpoints[(i + 1)%length], vector2);

                        Bezier bezier = new QuadraticBezier(cornerpoints[(i)%length], line1.GetCrossingPoint(line2),
                                                            cornerpoints[(i + 1)%length]);

                        PointF[] points = bezier.GetDrawPoints();

                        graphicspath.AddBezier(points[0], points[1], points[2], points[3]);
                    }
                }
            }
        }