public static double Between(IGeometricElement3D e1, IGeometricElement3D e2)
 {
     double result;
     if (e1 is Point3D)
     {
         var point3D = e1 as Point3D;
         switch (getType(e2))
         {
             case TYP3D.Point3D:
                 result = PointToPoint(point3D, e2 as Point3D);
                 return result;
             case TYP3D.Line3D:
                 result = PointToLine(e2 as Line3D, point3D);
                 return result;
             case TYP3D.Plane3D:
                 result = PointToPlane(e2 as Plane3D, point3D);
                 return result;
             case TYP3D.Circle3D:
                 result = PointToCircle(e2 as Circle3D, point3D);
                 return result;
             case TYP3D.Sphere3D:
                 result = PointToSphere(e2 as Sphere3D, point3D);
                 return result;
         }
     }
     else
     {
         if (e1 is Line3D)
         {
             var line3D = e1 as Line3D;
             switch (getType(e2))
             {
                 case TYP3D.Point3D:
                     result = PointToLine(line3D, e2 as Point3D);
                     return result;
                 case TYP3D.Line3D:
                     result = LineToLine(line3D, e2 as Line3D);
                     return result;
                 case TYP3D.Plane3D:
                 case TYP3D.Sphere3D:
                     throw new NotImplementedException();
                 case TYP3D.Circle3D:
                     result = LineToCircle(e2 as Circle3D, line3D);
                     return result;
             }
         }
         else
         {
             if (e1 is Plane3D)
             {
                 var plane = e1 as Plane3D;
                 switch (getType(e2))
                 {
                     case TYP3D.Point3D:
                         result = PointToPlane(plane, e2 as Point3D);
                         return result;
                     case TYP3D.Line3D:
                     case TYP3D.Plane3D:
                     case TYP3D.Circle3D:
                     case TYP3D.Sphere3D:
                         throw new NotImplementedException();
                 }
             }
             else
             {
                 if (e1 is Circle3D)
                 {
                     var circle = e1 as Circle3D;
                     switch (getType(e2))
                     {
                         case TYP3D.Point3D:
                             result = PointToCircle(circle, e2 as Point3D);
                             return result;
                         case TYP3D.Line3D:
                         case TYP3D.Plane3D:
                         case TYP3D.Circle3D:
                         case TYP3D.Sphere3D:
                             throw new NotImplementedException();
                     }
                 }
                 else
                 {
                     if (e1 is Sphere3D)
                     {
                         var sphere = e1 as Sphere3D;
                         switch (getType(e2))
                         {
                             case TYP3D.Point3D:
                                 result = PointToSphere(sphere, e2 as Point3D);
                                 return result;
                             case TYP3D.Line3D:
                             case TYP3D.Plane3D:
                             case TYP3D.Circle3D:
                             case TYP3D.Sphere3D:
                                 throw new NotImplementedException();
                             default:
                                 throw new NotImplementedException();
                         }
                     }
                 }
             }
         }
     }
     result = -1.0;
     return result;
 }
 private void CalculateErrors(IList<Point3D> points, IGeometricElement3D element)
 {
     Errors = new Collection<double>();
     var num = 0.0;
     var num2 = 0.0;
     MaxError = 0.0;
     PointWithLargestError = -1;
     for (var i = 0; i < points.Count; i++)
     {
         var e = points[i];
         var num3 = Distance3D.Between(element, e);
         Errors.Add(num3);
         num += num3;
         num2 += num3*num3;
         if (num3 > MaxError)
         {
             MaxError = num3;
             PointWithLargestError = i;
         }
     }
     var count = points.Count;
     AverageError = num/count;
     StandardDeviationError = Math.Sqrt(count*num2 - AverageError*AverageError)/count;
 }
 private static TYP3D getType(IGeometricElement3D geo)
 {
     TYP3D result;
     if (geo is Point3D)
     {
         result = TYP3D.Point3D;
     }
     else
     {
         if (geo is Line3D)
         {
             result = TYP3D.Line3D;
         }
         else
         {
             if (geo is Plane3D)
             {
                 result = TYP3D.Plane3D;
             }
             else
             {
                 if (geo is Circle3D)
                 {
                     result = TYP3D.Circle3D;
                 }
                 else
                 {
                     if (geo is Sphere3D)
                     {
                         result = TYP3D.Sphere3D;
                     }
                     else
                     {
                         result = TYP3D.None;
                     }
                 }
             }
         }
     }
     return result;
 }