Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }