//Restituisce le equazioni cartesiane della circonferenza passante per V1, V2, V3
        public static MyCircumForPath CircumPassingThrough(MyVertex V1, MyVertex V2, MyVertex V3, ref StringBuilder fileOutput, ModelDoc2 SwModel, SldWorks swApplication)
        {
            //The circumference does not exist if the 3 points lie on the same line or if 2 of them are coincident.
            if (V1.Lieonline(LinePassingThrough(V2, V3)) || V1.Equals(V2) || V1.Equals(V3) || V2.Equals(V3))
            {
                MyCircumForPath OutputCircum = new MyCircumForPath();
                return(OutputCircum);
            }
            else
            {
                MyPlane CircumPlane = PlanePassingThrough(V1, V2, V3);

                //There is a unique sphere passing through 4 points: we must arbitrarily choose a fourth point not lying on the V1-V2-V3 plane
                //So we choose the point resulting from adding the normal direction to a point lying on the V1-V2-V3 plane, for example V1

                MyVertex V4 = new MyVertex(V1.x + CircumPlane.a * 10, V1.y + CircumPlane.b * 10, V1.z + CircumPlane.c * 10);
                //Vertex V4 = new Vertex(0, 0, 0);
                //if (SwModel != null)
                //{
                //    SwModel = swApplication.ActiveDoc;
                //    SwModel.ClearSelection2(true);
                //    SwModel.Insert3DSketch();
                //    SwModel.CreatePoint2(V1.x, V1.y, V1.z);
                //    SwModel.InsertSketch();
                //    SwModel.CreatePoint2(V2.x, V2.y, V2.z);
                //    SwModel.InsertSketch();
                //    SwModel.CreatePoint2(V3.x, V3.y, V3.z);
                //    SwModel.InsertSketch();
                //    SwModel.CreatePoint2(V4.x, V4.y, V4.z);
                //    SwModel.InsertSketch();
                //}

                MySphere CircumSphere = SpherePassingThrough(V1, V2, V3, V4, ref fileOutput, SwModel);

                if (CircumSphere.centerSphere == null)
                {
                }
                else if (CircumSphere.centerSphere != null)
                {
                    MyCircumForPath OutputCircum = new MyCircumForPath(CircumPlane, CircumSphere);
                    return(OutputCircum);
                }
            }
            MyCircumForPath OutputCircumNull = new MyCircumForPath();

            return(OutputCircumNull);
        }
        //INPUT: MyVertex V1, MyVertex V2, MyVertex C
        //It returns the angle teta between the two vectors C V1 and C V2
        public static double FindAngle(MyVertex V1, MyVertex V2, MyVertex C)
        {
            //var whatToWrite = string.Format("PROVA: ");
            //KLdebug.Print(whatToWrite, "AngleComputation.txt");

            double outputAngle = 0.0;

            if (V1.Equals(V2) || V1.Equals(C) || V1.Equals(V2))
            {
                return(outputAngle);
            }
            if (C.Lieonline(LinePassingThrough(V1, V2)))
            {
                outputAngle = Math.PI;
                return(outputAngle);
            }
            //KLdebug.Print("calcolo:", "prova.txt");

            if (Math.Abs(C.x) < Math.Pow(10, -10))
            {
                C.x = 0;
            }
            if (Math.Abs(C.y) < Math.Pow(10, -10))
            {
                C.y = 0;
            }
            if (Math.Abs(C.z) < Math.Pow(10, -10))
            {
                C.z = 0;
            }
            //whatToWrite = string.Format("centro ({0},{1},{2}) ", C.x, C.y, C.z);
            //KLdebug.Print(whatToWrite, "prova.txt");

            double[] vectorV1 = { V1.x - C.x, V1.y - C.y, V1.z - C.z };
            if (Math.Abs(vectorV1[0]) < Math.Pow(10, -10))
            {
                vectorV1[0] = 0;
            }
            if (Math.Abs(vectorV1[1]) < Math.Pow(10, -10))
            {
                vectorV1[1] = 0;
            }
            if (Math.Abs(vectorV1[2]) < Math.Pow(10, -10))
            {
                vectorV1[2] = 0;
            }
            //whatToWrite = string.Format("vec1 ({0},{1},{2}) ", vectorV1[0], vectorV1[1], vectorV1[2]);
            //KLdebug.Print(whatToWrite, "prova.txt");

            double vectorV1Norm =
                Math.Sqrt(Math.Pow(vectorV1[0], 2) + Math.Pow(vectorV1[1], 2) + Math.Pow(vectorV1[2], 2));

            //KLdebug.Print("norma vec1 " + vectorV1Norm, "prova.txt");

            double[] vectorV2 = { V2.x - C.x, V2.y - C.y, V2.z - C.z };
            if (Math.Abs(vectorV2[0]) < Math.Pow(10, -10))
            {
                vectorV2[0] = 0;
            }
            if (Math.Abs(vectorV2[1]) < Math.Pow(10, -10))
            {
                vectorV2[1] = 0;
            }
            if (Math.Abs(vectorV2[2]) < Math.Pow(10, -10))
            {
                vectorV2[2] = 0;
            }
            //whatToWrite = string.Format("vec2 ({0},{1},{2}) ", vectorV2[0], vectorV2[1], vectorV2[2]);
            //KLdebug.Print(whatToWrite, "prova.txt");

            double vectorV2Norm =
                Math.Sqrt(Math.Pow(vectorV2[0], 2) + Math.Pow(vectorV2[1], 2) + Math.Pow(vectorV2[2], 2));
            //KLdebug.Print("norma vec2 " + vectorV2Norm, "prova.txt");

            double scalarProduct = vectorV1[0] * vectorV2[0] + vectorV1[1] * vectorV2[1] + vectorV1[2] * vectorV2[2];

            //KLdebug.Print("scalarProduct " + scalarProduct, "prova.txt");

            //KLdebug.Print("faccio l'arcos di: " + scalarProduct / (vectorV1Norm * vectorV2Norm), "prova.txt");

            if (vectorV1Norm * vectorV2Norm != 0)
            {
                outputAngle = Math.Acos(scalarProduct / (vectorV1Norm * vectorV2Norm));
            }
            //KLdebug.Print("outputAngle " + outputAngle, "prova.txt");

            if (!Double.IsNaN(outputAngle))
            {
                return(outputAngle);
            }
            return(-1);
        }
        public static void MyGetPointFromFaceEntity(Entity entity, ref List <MyVertex> listMyVertexFace,
                                                    ref List <MyVertex> listAddedMyVertex, SldWorks swApplication)
        {
            // In both cases, if the underlying curve is not a line, I add a new MyVertex:
            // - in case of open edge, it is in the middle of the edge
            // - in case of closed edge, it is opposite to the firstVertex

            //const string fileNameBuildRepeatedEntity = "buildRepeatedEntity.txt";
            //var whatToWrite = " ";

            var listEdgeFace    = (Array)((Face2)entity).GetEdges();
            var listEntityEdges = new List <Entity>();

            foreach (var oldEdge in listEdgeFace)
            {
                var    ent = (Entity)oldEdge;
                Entity safeEdge;

                safeEdge = ent.GetSafeEntity();

                listEntityEdges.Add(safeEdge);
            }
            //swApplication.SendMsgToUser(listEdgeFace.Length + " spigoli nella faccia");

            foreach (var ent in listEntityEdges)
            {
                if (ent != null)
                {
                    //var edge = ent as Edge;

                    var vertexS = (Vertex)((Edge)ent).GetStartVertex();
                    var vertexE = (Vertex)((Edge)ent).GetEndVertex();

                    if (vertexS != null && vertexE != null) // i.e. open edge
                    {
                        var edgeCurve = (Curve)((Edge)ent).GetCurve();
                        if (edgeCurve != null)
                        {
                            var arrayVertexStart = (Array)vertexS.GetPoint();
                            var startPoint       = new MyVertex((double)arrayVertexStart.GetValue(0),
                                                                (double)arrayVertexStart.GetValue(1), (double)arrayVertexStart.GetValue(2));

                            var arrayVertexEnd = (Array)vertexE.GetPoint();
                            var endPoint       = new MyVertex((double)arrayVertexEnd.GetValue(0),
                                                              (double)arrayVertexEnd.GetValue(1), (double)arrayVertexEnd.GetValue(2));

                            //there are situation of startPoint and endPoint not null but coinciding
                            //(these cases must be excluded and considered as closed edges)
                            if (!startPoint.Equals(endPoint))
                            {
                                listMyVertexFace.Add(startPoint);
                                //whatToWrite = string.Format("Vertice startpoint ({0},{1},{2})", startPoint.x,
                                //    startPoint.y,
                                //    startPoint.z);
                                //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);
                                listMyVertexFace.Add(endPoint);
                                //whatToWrite = string.Format("Vertice endpoint ({0},{1},{2})", endPoint.x, endPoint.y,
                                //    endPoint.z);
                                //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);

                                edgeCurve = (Curve)((Edge)ent).GetCurve();
                                if (!(edgeCurve.IsLine()))
                                {
                                    var midPoint = CreateMidMyVertex(ent);

                                    listAddedMyVertex.Add(midPoint);
                                    //whatToWrite = string.Format(
                                    //    "Vertice creato midpoint su edge curvo aperto ({0},{1},{2})", midPoint.x,
                                    //    midPoint.y,
                                    //    midPoint.z);
                                    //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);
                                }
                            }
                            //else // i.e. closed edge
                            //{
                            //    double[] arrayVertex = (double[]) curveParaData.StartPoint;
                            //        // == curveParaData.EndPoint ??
                            //    var newVertex = new MyVertex((double) arrayVertex.GetValue(0),
                            //        (double) arrayVertex.GetValue(1), (double) arrayVertex.GetValue(2));

                            //    listAddedMyVertex.Add(startPoint);
                            //    whatToWrite = string.Format("Null: vertice creato ({0},{1},{2})", newVertex.x,
                            //        newVertex.y,
                            //        newVertex.z);
                            //    KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);


                            //    if (!(edgeCurve.IsLine()))
                            //    {
                            //        var midPoint = CreateMidMyVertex(curveParaData, edgeCurve);

                            //        listAddedMyVertex.Add(midPoint);
                            //        whatToWrite = string.Format(
                            //            "Vertice creato midpoint su edge curvo chiuso ({0},{1},{2})", midPoint.x,
                            //            midPoint.y,
                            //            midPoint.z);
                            //        //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);

                            //    }
                            //}
                        }
                    }
                    else
                    // i.e. closed edge?
                    {
                        var      curveParaData = (CurveParamData)((Edge)ent).GetCurveParams3();
                        double[] arrayVertex   = (double[])curveParaData.StartPoint; // == curveParaData.EndPoint ??
                        var      newVertex     = new MyVertex((double)arrayVertex.GetValue(0), (double)arrayVertex.GetValue(1),
                                                              (double)arrayVertex.GetValue(2));

                        listAddedMyVertex.Add(newVertex);
                        //whatToWrite = string.Format("Null: vertice creato ({0},{1},{2})", newVertex.x, newVertex.y,
                        //    newVertex.z);
                        // KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);

                        var edgeCurve = (Curve)((Edge)ent).GetCurve();
                        if (!(edgeCurve.IsLine()))
                        {
                            var midPoint = CreateMidMyVertex(ent);

                            listAddedMyVertex.Add(midPoint);
                            //whatToWrite = string.Format(
                            //    "Vertice creato midpoint su edge curvo chiuso ({0},{1},{2})",
                            //    midPoint.x, midPoint.y,
                            //    midPoint.z);
                            //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);
                        }
                    }
                }
            }
        }