public static Point[] LineCircleIntersection(LineGeometry line, CircleGeometry circle)
        {
            if (line == null || circle == null)
            {
                return(new Point[0]);
            }

            if (!line.Bounds.IntersectsWith(circle.Bounds))
            {
                return(new Point[0]);
            }

            Vector d = line.EndPoint - line.StartPoint;
            Vector f = line.StartPoint - circle.Center;

            double a = d * d;
            double b = 2 * f * d;
            double c = (f * f) - (circle.Radius * circle.Radius);

            double discriminant = (b * b) - (4 * a * c);

            if (discriminant < 0)
            {
                return(new Point[0]);
            }

            discriminant = Math.Sqrt(discriminant);

            double t1 = (-b - discriminant) / (2 * a);
            double t2 = (-b + discriminant) / (2 * a);

            Point p1 = line.StartPoint + Vector.Multiply(d, t1);
            Point p2 = line.StartPoint + Vector.Multiply(d, t2);

            if (IsPointOnLineSegment(p1, line) && IsPointOnLineSegment(p2, line))
            {
                return new[] { p1, p2 }
            }
            ;

            if (IsPointOnLineSegment(p1, line))
            {
                return new[] { p1 }
            }
            ;

            if (IsPointOnLineSegment(p2, line))
            {
                return new[] { p2 }
            }
            ;

            return(new Point[0]);
        }
        public static Point[] CircleCircleIntersection(CircleGeometry firstCircle, CircleGeometry secondCircle)
        {
            if (firstCircle == null || secondCircle == null)
            {
                return(new Point[0]);
            }

            double cx0 = firstCircle.Center.X;
            double cx1 = secondCircle.Center.X;
            double cy0 = firstCircle.Center.Y;
            double cy1 = secondCircle.Center.Y;

            double radius0 = firstCircle.Radius;
            double radius1 = secondCircle.Radius;

            double dx   = cx0 - cx1;
            double dy   = cy0 - cy1;
            double dist = Math.Sqrt((dx * dx) + (dy * dy));

            if (dist > radius0 + radius1)
            {
                return(new Point[0]);
            }

            if (dist < Math.Abs(radius0 - radius1))
            {
                return(new Point[0]);
            }
            if ((dist.AlmostEquals(0d)) && (radius0.AlmostEquals(radius1)))
            {
                return(new Point[0]);
            }

            double a = ((radius0 * radius0) - (radius1 * radius1) + (dist * dist)) / (2 * dist);
            double h = Math.Sqrt((radius0 * radius0) - (a * a));

            double cx2 = cx0 + (a * (cx1 - cx0) / dist);
            double cy2 = cy0 + (a * (cy1 - cy0) / dist);

            return(new []
            {
                new Point(
                    cx2 + (h * (cy1 - cy0) / dist),
                    cy2 - (h * (cx1 - cx0) / dist)),
                new Point(
                    cx2 - (h * (cy1 - cy0) / dist),
                    cy2 + (h * (cx1 - cx0) / dist))
            });
        }