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; }
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); }
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); }
public PointD GetCrossingPoint(LineD line) { return GetCrossingPoint(this, line); }
// 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); }
public bool IsCoLinearWith(LineD line) { return new VectorD(Point1, Point2).IsCoLinearWith(new VectorD(line.Point1, line.Point2)) && GetDistance(line.Point1) < 0.001; }
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]); } } } }