private void TestToStringWithCulture(CultureInfo culture) { CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = culture; try { string listSeparator = culture.TextInfo.ListSeparator; string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator; var o = new BezierCurve2F( new Vec2F(1.1f, 2.2f), new Vec2F(4.4f, 5.5f), new Vec2F(7.7f, 8.8f), new Vec2F(10.10f, 11.11f)); string s = o.ToString(null, null); TestToStringResults(o, s, listSeparator, decimalSeparator); string s2 = o.ToString(); Assert.AreEqual(s, s2); s = o.ToString("G", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); s = o.ToString("R", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); } finally { Thread.CurrentThread.CurrentCulture = originalCulture; } }
/// <summary> /// Picks the specified curve</summary> /// <param name="curve">Curve</param> /// <param name="p">Picking point</param> /// <param name="tolerance">Pick tolerance</param> /// <param name="hitPoint">Hit point</param> /// <returns>True if curve found; false otherwise</returns> public static bool Pick(BezierCurve2F curve, Vec2F p, float tolerance, ref Vec2F hitPoint) { Queue <BezierCurve2F> curves = new Queue <BezierCurve2F>(); curves.Enqueue(curve); float dMin = float.MaxValue; Vec2F closestPoint = new Vec2F(); while (curves.Count > 0) { BezierCurve2F current = curves.Dequeue(); // project p onto segment connecting curve endpoints Seg2F seg = new Seg2F(current.P1, current.P4); Vec2F projection = Seg2F.Project(seg, p); float d = Vec2F.Distance(p, projection); // reject - point not near enough to segment, expanded by curve "thickness" float flatness = current.Flatness; if (d - flatness > tolerance) { continue; } // accept - point within tolerance of curve if (flatness <= tolerance) { if (d < dMin) { dMin = d; closestPoint = projection; } } else { BezierCurve2F left, right; current.Subdivide(0.5f, out left, out right); curves.Enqueue(left); curves.Enqueue(right); } } if (dMin < tolerance) { hitPoint = closestPoint; return(true); } return(false); }
/// <summary> /// Subdivides the Bezier curve into two equivalent Bezier curves</summary> /// <param name="t">Parameter of subdivision point</param> /// <param name="left">Left or "less than or equal to t" parameter side</param> /// <param name="right">Right or "greater than or equal to t" parameter side</param> public void Subdivide(float t, out BezierCurve2F left, out BezierCurve2F right) { // use de Casteljau constuction float oneMinusT = 1.0f - t; Vec2F s11 = P1 * oneMinusT + P2 * t; Vec2F s12 = P2 * oneMinusT + P3 * t; Vec2F s13 = P3 * oneMinusT + P4 * t; Vec2F s21 = s11 * oneMinusT + s12 * t; Vec2F s22 = s12 * oneMinusT + s13 * t; Vec2F s31 = s21 * oneMinusT + s22 * t; left = new BezierCurve2F(P1, s11, s21, s31); right = new BezierCurve2F(s31, s22, s13, P4); }
private void TestToStringResults(BezierCurve2F o, string s, string listSeparator, string decimalSeparator) { string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(results.Length, 8); foreach (string oneFloatString in results) Assert.True(oneFloatString.Contains(decimalSeparator)); Assert.AreEqual(float.Parse(results[0]), o.P1.X); Assert.AreEqual(float.Parse(results[1]), o.P1.Y); Assert.AreEqual(float.Parse(results[2]), o.P2.X); Assert.AreEqual(float.Parse(results[3]), o.P2.Y); Assert.AreEqual(float.Parse(results[4]), o.P3.X); Assert.AreEqual(float.Parse(results[5]), o.P3.Y); Assert.AreEqual(float.Parse(results[6]), o.P4.X); Assert.AreEqual(float.Parse(results[7]), o.P4.Y); }
/// <summary> /// Picks the specified curve</summary> /// <param name="curve">Curve</param> /// <param name="p">Picking point</param> /// <param name="tolerance">Pick tolerance</param> /// <param name="hitPoint">Hit point</param> /// <returns>True if curve found; false otherwise</returns> public static bool Pick(BezierCurve2F curve, Vec2F p, float tolerance, ref Vec2F hitPoint) { Queue<BezierCurve2F> curves = new Queue<BezierCurve2F>(); curves.Enqueue(curve); float dMin = float.MaxValue; Vec2F closestPoint = new Vec2F(); while (curves.Count > 0) { BezierCurve2F current = curves.Dequeue(); // project p onto segment connecting curve endpoints Seg2F seg = new Seg2F(current.P1, current.P4); Vec2F projection = Seg2F.Project(seg, p); float d = Vec2F.Distance(p, projection); // reject - point not near enough to segment, expanded by curve "thickness" float flatness = current.Flatness; if (d - flatness > tolerance) continue; // accept - point within tolerance of curve if (flatness <= tolerance) { if (d < dMin) { dMin = d; closestPoint = projection; } } else { BezierCurve2F left, right; current.Subdivide(0.5f, out left, out right); curves.Enqueue(left); curves.Enqueue(right); } } if (dMin < tolerance) { hitPoint = closestPoint; return true; } return false; }