using System;

using System.Drawing;

 

namespace Geometry

{

      /// <summary>

      /// Geometric solutions for circles

      /// </summary>

      public class CircleGeometry

      {

            private CircleGeometry()

            {

            }

 

            /// <summary>

            /// Find the centre and radius of a circle through 3 points

            /// </summary>

            /// <param name="pt1">First point</param>

            /// <param name="pt2">Second point</param>

            /// <param name="pt3">Third point</param>

            /// <param name="ptCentre">Centre point result</param>

            /// <param name="nRadius">Radius result</param>

            /// <returns>Status value</returns>

            public static int Circle3P(Point pt1, Point pt2, Point pt3,

                  ref Point ptCentre, ref int nRadius)

                  //*****************************************************************

                  // Find the centre and radius of a circle passing through 3 points

                  // Return 0 : success, 1 : two or more points are co-incident or co-linear,

                  //   2 : solution out of range

            {

                  double x1, y1, x2, y2, x3, y3, xc, yc, fRadius, Div;

 

                  // Check points are distinct

                  if((pt1 == pt2) || (pt1 == pt3) || (pt2 == pt3)) return 1;

 

                  // Convert points to real for accuracy

                  x1 = pt1.X;  y1 = pt1.Y;

                  x2 = pt2.X;  y2 = pt2.Y;

                  x3 = pt3.X;  y3 = pt3.Y;

 

                  // Calculate x-coordinate of centre

                  Div = 2.0 * ((x1 - x2)*(y2 - y3)-(x2 - x3)*(y1 - y2));

                  if(Div == 0.0) return 1;

                  xc = ((y2 - y3) *( x1*x1 - x2*x2 + y1*y1 - y2*y2) -

                        (y1 - y2) * (x2*x2 - x3*x3 + y2*y2 - y3*y3)) / Div;

 

                  // Calculate y-coordinate

                  if(y1 != y2) yc = ((2.0 * xc * (x2-x1)) + (x1*x1 - x2*x2 + y1*y1 - y2*y2))/

                                           (2.0 * (y1-y2));

                  else yc = ((2.0 * xc * (x3-x1)) + (x1*x1 - x3*x3 + y1*y1 - y3*y3))/

                               (2.0 * (y1-y3));

 

                  // Derive radius

                  fRadius = Math.Sqrt((xc - x1) * (xc - x1) + (yc - y1) * (yc - y1));

 

                  // Convert results to integers

                  if(Math.Abs(xc) > (double)Int32.MaxValue) return 2;

                  if(Math.Abs(yc) > (double)Int32.MaxValue) return 2;

                  if(Math.Abs(fRadius) > (double)Int32.MaxValue) return 2;

                  ptCentre.X = (int)Math.Round(xc);

                  ptCentre.Y = (int)Math.Round(yc);

                  nRadius = (int)Math.Round(fRadius);

 

                  // Return success

                  return 0;

            }

 

      }

}