Exemple #1
0
        /// <summary>
        /// Gets the Y values for which the equation of the circle yields the given X.
        /// </summary>
        /// <param name="x">The X value.</param>
        public         decimal[] SolveForY(ref decimal x)
        {
            // Alternative calculations. May be faster/more accurate, but need to be tested.
            //Dim absDiff = Math.Abs(x - _center.X)
            //Select Case absDiff
            //    Case Is > _radius
            //        Return New Decimal() {}
            //    Case _radius
            //        Return New Decimal() {_center.Y}
            //    Case 0
            //        Return New Decimal() {_center.Y + _radius, _center.Y - _radius}
            //    Case Else
            //        Dim height = RightTriangle.GetSideFromSideHyp(absDiff, _radius)
            //        Return New Decimal() {_center.Y + height, _center.Y - height}
            //End Select

            decimal aCoeff = 0m;
            decimal bCoeff = 0m;
            decimal cCoeff = 0m;

            // Solve for y
            //  (x - h)^2 + (y - k)^2 = r^2
            // simplifies to
            //  y^2 - 2 * k * y + k^2 + (x - h)^2 - r^2 = 0

            aCoeff = 1;
            bCoeff = -2 * _center.Y;
            cCoeff = _center.Y * _center.Y + (x - _center.X) * (x - _center.X) - _radius * _radius;

            return(DecimalEx.SolveQuadratic(aCoeff, bCoeff, cCoeff));
        }
Exemple #2
0
        /// <summary>
        /// Gets the X values for which the equation of the circle yields the given Y.
        /// </summary>
        /// <param name="y">The Y value.</param>
        public         decimal[] SolveForX(decimal y)
        {
            decimal aCoeff = 0m;
            decimal bCoeff = 0m;
            decimal cCoeff = 0m;

            // Solve for x
            //  (x - h)^2 + (y - k)^2 = r^2
            // simplifies to
            //  x^2 - 2 * h * x + h^2 + (y - k)^2 - r^2 = 0

            aCoeff = 1;
            bCoeff = -2 * _center.X;
            cCoeff = _center.X * _center.X + (y - _center.Y) * (y - _center.Y) - _radius * _radius;

            return(DecimalEx.SolveQuadratic(aCoeff, bCoeff, cCoeff));
        }
Exemple #3
0
        /// <summary>
        /// Gets the points of intersection between this circle and the line which
        /// contains the given line segment.
        /// </summary>
        /// <param name="l">Line segment used to determine line equation.</param>
        public Point2D[] GetIntersectFast(ref LineSeg2D l)
        {
            decimal[] x      = new decimal[2];
            decimal   m      = 0m;
            decimal   b      = 0m;
            decimal   aCoeff = 0m;
            decimal   bCoeff = 0m;
            decimal   cCoeff = 0m;
            decimal   lineX  = 0m;
            decimal   t      = 0m;
            decimal   p      = 0m;
            decimal   q      = 0m;

            Point2D[] pts = null;



            if (!l.IsVertical)
            {
                // Circle    (x - h) ^ 2 + (y - k) ^ 2 = r ^ 2
                //   Center: (h, k)
                //   Radius: r
                // Line      y = m * x + b

                // (x - h) ^ 2 + (m * x + b - k) ^ 2 = r ^ 2
                // (x - h) * (x - h) + (m * x + b - k) * (m * x + b - k) = r^2
                // (x^2 - 2 * h * x + h^2) + (m^2 * x^2 + 2 * (b - k) * m * x + (b - k)^2 = r^2
                // (m^2 + 1) * x^2 + (2 * (b - k) * m - 2 * h) * x + (h^2 + (b - k)^2 - r^2) = 0

                m = l.Slope;
                b = l.YIntersect;

                aCoeff = DecimalEx.Pow(m, 2) + 1;
                bCoeff = 2 * (b - _center.Y) * m - 2 * _center.X;
                cCoeff = DecimalEx.Pow(_center.X, 2) + DecimalEx.Pow(b - _center.Y, 2) - DecimalEx.Pow(_radius, 2);

                x = DecimalEx.SolveQuadratic(aCoeff, bCoeff, cCoeff);

                if (x.Length == 0)
                {
                    return new Point2D[] { }
                }
                ;

                pts = new Point2D[x.Length];

                for (var i = 0; i <= x.Length - 1; i++)
                {
                    pts[i] = new Point2D(x[i], m * x[i] + b);
                }
            }
            else
            {
                // Circle    (x - h) ^ 2 + (y - k) ^ 2 = r ^ 2
                //   Center: (h, k)
                //   Radius: r
                // Line      x = lineX

                // Got the following from
                //  http://www.sonoma.edu/users/w/wilsonst/Papers/Geometry/circles/T1--2/T1-3-2.html
                //  http://www.sonoma.edu/users/w/wilsonst/Papers/Geometry/circles/default.html

                lineX = l.Pt1.X;
                t     = _radius * _radius - (lineX - _center.X) * (lineX - _center.X);


                if (t < 0)
                {
                    return(new Point2D[] { });
                }
                else
                {
                    p = _center.Y + DecimalEx.Sqrt(t);
                    q = _center.Y - DecimalEx.Sqrt(t);

                    pts    = new Point2D[1];
                    pts[0] = new Point2D(lineX, p);

                    // NOTE that P=Q when t=0
                    if (p != q)
                    {
                        Array.Resize(ref pts, 2);
                        pts[1] = new Point2D(lineX, q);
                    }
                }
            }

            return(pts);
        }