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 CircleF(new Vec2F(2.2f, 3.3f), 1.1f); 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; } }
private void TestToStringResults(CircleF o, string s, string listSeparator, string decimalSeparator) { string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(results.Length, 3); foreach (string oneFloatString in results) Assert.True(oneFloatString.Contains(decimalSeparator)); Assert.AreEqual(float.Parse(results[0]), o.Center.X); Assert.AreEqual(float.Parse(results[1]), o.Center.Y); Assert.AreEqual(float.Parse(results[2]), o.Radius); }
/// <summary> /// Projects a point onto a circle</summary> /// <param name="p">Point to project</param> /// <param name="c">Circle to project onto</param> /// <param name="projection">Projected point</param> /// <returns>True iff projection is well defined</returns> public static bool Project(Vec2F p, CircleF c, ref Vec2F projection) { Vec2F d = Vec2F.Sub(p, c.Center); float length = d.Length; bool wellDefined = false; if (length > 0.000001f * c.Radius) { wellDefined = true; float scale = c.Radius / length; projection = Vec2F.Add(c.Center, Vec2F.Mul(d, scale)); } return wellDefined; }
/// <summary> /// Extends box to contain circle</summary> /// <param name="circle">Input circle</param> /// <returns>Extended box</returns> public Box2F Extend(CircleF circle) { float r = circle.Radius; Extend(circle.Center + new Vec2F(r, r)); Extend(circle.Center - new Vec2F(r, r)); return this; }
/// <summary> /// Calculates the points of intersection between 2 CircleF objects</summary> /// <param name="c1">First CircleF</param> /// <param name="c2">Second CircleF</param> /// <param name="p1">First intersection point</param> /// <param name="p2">Second intersection point</param> /// <returns>True iff there are 1 or 2 intersection points; false if there are none or an infinite number</returns> public static bool Intersect(CircleF c1, CircleF c2, ref Vec2F p1, ref Vec2F p2) { Vec2F v1 = c2.Center - c1.Center; double d = v1.Length; const double EPS = 1.0e-6; if (d < EPS || d > c1.Radius + c2.Radius) return false; v1 *= (float)(1 / d); Vec2F v2 = v1.Perp; double cos = (d * d + c1.Radius * c1.Radius - c2.Radius * c2.Radius) / (2 * c1.Radius * d); double sin = Math.Sqrt(1 - cos * cos); Vec2F t1 = Vec2F.Mul(v1, (float)(c1.Radius * cos)); Vec2F t2 = Vec2F.Mul(v2, (float)(c1.Radius * sin)); p1 = c1.Center + t1 + t2; p2 = c1.Center + t1 - t2; return true; // From http://mathforum.org/library/drmath/view/51710.html // First, let C1 and C2 be the centers of the Circlefs with radii r1 and // r2, and let d be the distance between C1 and C2. // // Now let V1 be the unit vector from C1 to C2, and let V2 be the unit // vector perpendicular to V1. // // Also let V3 be the vector from C1 to one of the intersection points. // // Finally, let A be the angle between V1 and V3. // // From the law of cosines we know that // // r2^2 = r1^2 + d^2 - 2*r1*d*cos(A) // // With this equation we can solve for 'A'. // // The intersection points will be // // C1 + [r1*cos(A)]*V1 + [r1*sin(A)]*V2 // // C1 + [r1*cos(A)]*V1 - [r1*sin(A)]*V2 // a simple unit test // CircleF test1 = new CircleF(new Vec2F(-0.5f, 0), 1); // CircleF test2 = new CircleF(new Vec2F(0.5f, 0), 1); // Vec2F result1 = new Vec2F(); // Vec2F result2 = new Vec2F(); // CircleF.Intersect(test1, test2, ref result1, ref result2); }