/// <returns>Null (no intercepts), or array of length 1 or 2.</returns>
        public WPoint[] GetIntersectionPoints(WLine line)
        {
            //line does not intersect if perpendicular line from circle-center to line is longer than circle-radius
            WPoint perpendicularToCenter = line.GetPerpendicularIntersect(Center);

            if (perpendicularToCenter.Distance(Center) > Radius)
            {
                return(null);
            }

            //equation of circle with radius r and center (h, k)
            //is (x - h)^2 + (y - k)^2 = r^2

            //line: y = mx + b
            //circle: (x - h)^2 + (y - k)^2 = r^2
            //substitute y: (x - h)^2 + (mx + b - k)^2 = r^2
            //expand: x^2 - 2hx + h^2 + m^2x^2 + 2(b - k)mx + (b - k)^2 - r^2 = 0
            //group: (1 + m^2)x^2 + (-2h + 2(b - k)m)x + (h^2 + (b - k)^2 - r^2) = 0
            //quadratic equation: if 0 = Ax^2 + Bx + C, then x = (-B +- sqrt(B^2 - 4AC)) / 2A
            double A = 1 + Math.Pow(line.Slope, 2);
            double B = (-2 * Center.X) + (2 * (line.YIntercept - Center.Y) * line.Slope);
            double C = Math.Pow(Center.X, 2) + Math.Pow(line.YIntercept - Center.Y, 2) - Math.Pow(Radius, 2);

            double x1 = (-1 * B + Math.Sqrt(Math.Pow(B, 2) - (4 * A * C))) / (2 * A);
            double x2 = (-1 * B - Math.Sqrt(Math.Pow(B, 2) - (4 * A * C))) / (2 * A);
            double y1 = line.Slope * x1 + line.YIntercept;
            double y2 = line.Slope * x2 + line.YIntercept;

            if (line.IsVertical)
            {
                x1 = line.A.X;
                x2 = line.A.X;
                //must use circle equation instead of line equation to find y's
                y1 = Center.Y + Math.Sqrt(Math.Pow(Radius, 2) - Math.Pow(x1 - Center.X, 2));
                y2 = Center.Y - Math.Sqrt(Math.Pow(Radius, 2) - Math.Pow(x1 - Center.X, 2));
            }
            if (line.IsHorizontal)
            {
                y1 = line.A.Y;
                y2 = line.A.Y;
            }
            WPoint        point1 = new WPoint(x1, y1);
            WPoint        point2 = new WPoint(x2, y2);
            List <WPoint> result = new List <WPoint>()
            {
                point1
            };

            if (point1 != point2)
            {
                result.Add(point2);
            }
            return(result.ToArray());
        }
        //todo: better names for PointOnLine and PointPastLine, they are misleading

        /// <summary>
        /// Calculates point along line AB, starting at A and moving towards B
        /// </summary>
        /// <exception cref='ArgumentException'>Point A and B cannot be the same.</exception>
        public static WPoint PointOnLine(WPoint a, WPoint b, double distance)
        {
            double lineLength = a.Distance(b);

            if (lineLength == 0)
            {
                throw new ArgumentException("Point A and B cannot be the same.");
            }
            double lengthRatio = distance / lineLength;
            double x           = ((1d - lengthRatio) * a.X) + (lengthRatio * b.X);
            double y           = ((1d - lengthRatio) * a.Y) + (lengthRatio * b.Y);

            return(new WPoint(x, y));
        }
        /// <summary>
        /// Calculates point along line AB, starting at B and moving away from A
        /// </summary>
        public static WPoint PointPastLine(WPoint a, WPoint b, double distance)
        {
            double lineLength = a.Distance(b);

            return(PointOnLine(a, b, lineLength + distance));
        }