Exemple #1
0
 public Edge(Edge e)
 {
     v        = e.v;
     this.p1  = e.p1;
     this.p2  = e.p2;
     this.pts = e.pts;
 }
Exemple #2
0
 /// <summary>
 /// rotate the face with the given angle, around the axis
 /// </summary>
 /// <param name="pt"></param>
 /// <param name="alpha">in degree</param>
 /// <param name="axis"></param>
 /// <returns></returns>
 public Pnt Rotate(Pnt pt, double alpha, string axis)
 {
     alpha = alpha * 2 * Math.PI / 360;
     // results in here are a bit too much approximated
     // it's even wrong as fk
     if (axis == "z")
     {
         double a = pt.x * Math.Cos(alpha) - pt.y * Math.Sin(alpha);
         double b = pt.x * Math.Sin(alpha) + pt.y * Math.Cos(alpha);
         double c = pt.z;
         return(new Pnt(a, b, c));
     }
     else if (axis == "y")
     {
         double a = pt.x * Math.Cos(alpha) + pt.z * Math.Sin(alpha);
         double b = pt.y;
         double c = -pt.x * Math.Sin(alpha) + pt.z * Math.Cos(alpha);;
         return(new Pnt(a, b, c));
     }
     else if (axis == "x")
     {
         double a = pt.x;
         double b = pt.y * Math.Cos(alpha) - pt.z * Math.Sin(alpha);
         double c = pt.y * Math.Sin(alpha) + pt.z * Math.Cos(alpha);
         return(new Pnt(a, b, c));
     }
     //Debug.Log("The Vector3 returned by Rotate() is wrong, u gave a wrong axis name: please use \"x\", \"y\" ou \"z\"");
     return(new Pnt(0, 0, 0));
 }
Exemple #3
0
        /// <summary>
        ///  returns a pnt rotated from angle degrees around the axis
        /// </summary>
        /// <param name="angle">in defree</param>
        /// <param name="axis"></param>
        /// <returns></returns>
        public Pnt Rotate(double angle, Pnt axis)
        {
            Pnt p = this;

            p.Rotated(angle, axis);
            return(p);
        }
Exemple #4
0
 // comparison
 public bool IsEqual(Pnt p2)
 {
     if (this.x == p2.x && this.y == p2.y && this.z == p2.z)
     {
         return(true);
     }
     return(false);
 }
Exemple #5
0
        // constructors
        public Edge(List <gp_Pnt> pts)
        {
            this.pts = ToPnt(pts);
            p1       = ToPnt(pts[0]);
            p2       = ToPnt(pts[1]);

            v = ToPnt(pts[1]) - ToPnt(pts[0]);
        }
Exemple #6
0
 /// <summary>
 /// doesn't verify that the point is included but verifies if the point is on the same plan
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public bool Contains(Pnt p)
 {
     if (pts.Count >= 3)
     {
         Edge e = new Edge(pts[0], p);
         return(e.v.DotProduct(this.Normale) == 0);
     }
     return(true);
 }
Exemple #7
0
 public Pnt(Pnt p)
 {
     x = p.x;
     y = p.y;
     z = p.z;
     d.Clear();
     d.Add(p.x);
     d.Add(p.y);
     d.Add(p.z);
 }
Exemple #8
0
        public Edge(Pnt p1, Pnt p2)
        {
            v = p2 - p1;


            this.pts.Clear();
            this.pts.Add(p1);
            this.pts.Add(p2);
            this.p1 = p1;
            this.p2 = p2;
        }
Exemple #9
0
        public Edge(gp_Pnt p1, gp_Pnt p2)
        {
            v = ToPnt(p2) - ToPnt(p1);


            this.pts.Clear();
            this.pts.Add(ToPnt(p1));
            this.pts.Add(ToPnt(p2));
            this.p1 = ToPnt(p1);
            this.p2 = ToPnt(p2);
        }
Exemple #10
0
        /// <summary>
        /// signed angle between two vectors defined by p1 and p2
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="axis">normale of the plane defined by the two vectors</param>
        /// <returns></returns>
        public static double SignedAngle(Pnt p1, Pnt p2, Pnt axis)
        {
            double angle = Math.Acos(DotProduct(Normalize(p1), Normalize(p2)));
            Pnt    cross = Cross(p1, p2);

            if (DotProduct(axis, cross) < 0)
            { // Or > 0
                angle = -angle;
            }
            return(angle * 360 / (2 * Math.PI)); // in degree
        }
Exemple #11
0
 /// <summary>
 /// checks if pts includes the Pnt pt, returns true in that case, false otherwise
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public bool Includes(Pnt pt)
 {
     foreach (Pnt p in this.pts)
     {
         if (pt.Equals(p))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #12
0
        /// <summary>
        /// modifies the edge
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        public void Replace(gp_Pnt p1, gp_Pnt p2)
        {
            v = ToPnt(p2) - ToPnt(p1);


            this.pts.Clear();
            this.pts.Add(ToPnt(p1));
            this.pts.Add(ToPnt(p2));
            this.p1 = ToPnt(p1);
            this.p2 = ToPnt(p2);
        }
Exemple #13
0
 /// <summary>
 /// get the index of the vertex
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public int Index(Pnt pt)
 {
     for (int i = 0; i < this.pts.Count; i++)
     {
         if (pts[i].Equals(pt))
         {
             return(i);
         }
     }
     return(-1);
 }
Exemple #14
0
 /// <summary>
 /// translate the face with the vector p
 /// </summary>
 /// <param name="p"></param>
 public void Translate(Pnt p)
 {
     for (int i = 0; i < pts.Count; i++)
     {
         pts[i] = new Pnt(pts[i] + p);
     }
     foreach (Face f in subFaces)
     {
         f.Translate(p);
     }
 }
Exemple #15
0
        /// <summary>
        /// modifies the edge
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        public void Replace(Pnt p1, Pnt p2)
        {
            v = p2 - p1;


            this.pts.Clear();
            this.pts.Add(p1);
            this.pts.Add(p2);
            this.p1 = p1;
            this.p2 = p2;
        }
Exemple #16
0
 /// <summary>
 /// retrieves the index of the vertex
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public int RetrievesIndex(Pnt pt)
 {
     // make sure u applied Graham before
     if (Index(pt) == -1)
     {
         this.Add(pt);
         return(pts.Count - 1);
     }
     else
     {
         return(Index(pt));
     }
 }
Exemple #17
0
        /// <summary>
        /// rotate this from the angle "angle" around the axis "axis"
        /// </summary>
        /// <param name="angle">in degree</param>
        /// <param name="axis"></param>
        public void Rotated(double angle, Pnt axis)
        {
            angle = angle * Math.PI / 180; // converting to radians


            double rx = x * (Math.Cos(angle) + axis.x * axis.x * (1 - Math.Cos(angle))) + y * (axis.x * axis.y * (1 - Math.Cos(angle)) - axis.z * Math.Sin(angle)) + z * (axis.x * axis.z * (1 - Math.Cos(angle)) + axis.y * Math.Sin(angle));
            double ry = x * (axis.y * axis.x * (1 - Math.Cos(angle)) + axis.z * Math.Sin(angle)) + y * (Math.Cos(angle) + axis.y * axis.y * (1 - Math.Cos(angle))) + z * (axis.y * axis.z * (1 - Math.Cos(angle)) - axis.x * Math.Sin(angle));
            double rz = x * (axis.z * axis.x * (1 - Math.Cos(angle) - axis.y * Math.Sin(angle))) + y * (axis.z * axis.y * (1 - Math.Cos(angle)) + axis.x * Math.Sin(angle)) + z * (Math.Cos(angle) + axis.z * axis.z * (1 - Math.Cos(angle)));

            x = rx;
            y = ry;
            z = rz;
            d.Clear();
            d.Add(rx);
            d.Add(ry);
            d.Add(rz);
        }
Exemple #18
0
        /// <summary>
        /// transforms to the new coordinate system with the 3 angles given
        /// </summary>
        /// <param name="face"></param>
        /// <param name="alpha">in degree</param>
        /// <param name="beta">in degree</param>
        /// <param name="gamma">in degree</param>
        /// <returns></returns>
        private Face TransformToNewCoordinateSystem(Face face, double alpha, double beta, double gamma)
        {
            Face f = new Face();

            foreach (Pnt pt in face.pts)
            {
                // first rotation
                Pnt temp = Rotate(pt, alpha, "x");

                // second rotation
                temp = Rotate(temp, beta, "y");

                // third rotation
                temp = Rotate(temp, gamma, "z");

                // add it to the new face
                f.Add(temp);
            }


            return(f);
        }
Exemple #19
0
 /// <summary>
 /// dot product between this and the vector e2
 /// </summary>
 /// <param name="e2"></param>
 /// <returns></returns>
 public double DotProduct(Pnt e2)
 {
     return(x * e2.x + y * e2.y + z * e2.z);
 }
Exemple #20
0
 /// <summary>
 /// cross product between the two vectors
 /// </summary>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 /// <returns></returns>
 public static Pnt Cross(Pnt p1, Pnt p2)
 {
     return(new Pnt(p1.y * p2.z - p1.z * p2.y, p1.z * p2.x - p1.x * p2.z, p1.x * p2.y - p1.y * p2.x));
 }
Exemple #21
0
        /// <summary>
        /// appplies graham on points
        /// </summary>
        /// <returns></returns>
        public Face Graham()
        {
            // nothing verifies that points are really in the same face, be careful


            // calculation of the new orthogonal coordinate system
            Face       f = new Face(this);
            List <Pnt> c = f.CoordinateSystem; // coordinate system of our face

            // calculation of the transformations into this coordinate system
            double alpha = Pnt.Angle(new Pnt(c[0].x, c[0].y, 0), new Pnt(1, 0, 0)); // rotation around z axis on the plan X,Y between x' and x

            // new Vector3(c[0].x, c[0].y,0) is the x vector with its z coordinates put to 0
            f = TransformToNewCoordinateSystem(f, 0, 0, -alpha);
            c = f.CoordinateSystem;

            double beta = Pnt.Angle(new Pnt(0, c[2].y, c[2].z), new Pnt(0, 0, 1)); // rotation around the new x axis on the plan Y',Z'=Z  between z'' and z'=z

            // new Vector3(0, c[2].y, c[2].z) is the z vector with its x coordinate put to 0
            f = TransformToNewCoordinateSystem(f, -beta, 0, 0);
            c = f.CoordinateSystem;


            double gamma = Pnt.Angle(new Pnt(c[0].x, 0, c[0].z), new Pnt(1, 0, 0)); // rotation around new y axis on the plan x,z between x'' and x'

            f = TransformToNewCoordinateSystem(f, 0, -gamma, 0);
            // http://ads.harvard.edu/books/1989fcm..book/Chapter2.pdf page 27 definitions of Goldstein

            //new Face(new List<Pnt>() { f.pts[0], f.pts[1], f.pts[2] }).Normale.Log();
            //new Face(new List<Pnt>() { f.pts[3], f.pts[1], f.pts[2] }).Normale.Log();
            // we get the same results, which implies that they are on the same plan, which is kind of rassurant

            // calculation of the superior hull (at this point it's like if points were in 2D )
            List <int> ordonnedIndices = new List <int> {
                0
            };                                               // we decide that the first point will be also the first indice
            bool gotMyFirstEdge = false;

            //while (ordonnedIndices.Count < pts.Count) // as long as our indices are not all added... NONONO it must stop when we get back to our first point
            while (ordonnedIndices[0] != ordonnedIndices[ordonnedIndices.Count - 1] || ordonnedIndices.Count == 1)
            {
                // we must get the first segment ( i mean the second point )
                if (!gotMyFirstEdge)
                {
                    int  i  = 1;
                    Edge e1 = new Edge(f.pts[0], f.pts[i]);
                    while (e1.Length <= 0)
                    {
                        if (i == f.pts.Count - 1) // we could not find any valid edge (Length>0)
                        {
                            return(null);
                        }
                        i++;
                        e1.Replace(f.pts[0], f.pts[i]);
                    }
                    int indice = i;
                    //we got our edge that has a valid length

                    // we got the first edge, but is this one good ? i mean: is it a border or is it crossing our face ?
                    Edge e2 = new Edge();
                    for (int j = i + 1; j < f.pts.Count; j++)
                    {
                        e2.Replace(f.pts[0], f.pts[j]);
                        if (e2.Length > 0)
                        {
                            double d = e1.Angle(e2, f.Normale);
                            // we got a valid edge, let's see if the angle is a good one to keep
                            if (e1.Angle(e2, f.Normale) > 0)
                            {                          // if it turns right (or maybe left, but let's imagine it is right)
                                e1     = new Edge(e2); // we update e1, we found a better edge
                                indice = j;
                            }
                        }
                    }

                    // we got our edge, did we ?
                    if (e1.Length > 0)
                    {
                        // yes we did !! it's the most on the right (in regards of pts[0])
                        gotMyFirstEdge = true;
                        ordonnedIndices.Add(indice);
                    }
                }
                else // now that we got our first edge we must add all others
                {
                    // we update our latest edge
                    Edge   e1     = new Edge(f.pts[ordonnedIndices[ordonnedIndices.Count - 1]], f.pts[ordonnedIndices[ordonnedIndices.Count - 2]]);
                    double angle  = 0;
                    int    indice = 0;
                    // we find the new best match
                    for (int j = 0; j < f.pts.Count; j++)
                    {
                        Edge e2 = new Edge(f.pts[ordonnedIndices[ordonnedIndices.Count - 1]], f.pts[j]);
                        //Edge e2= new Edge(f.pts[1], f.pts[j]);
                        if (e2.Length > 0)
                        {
                            // we got a valid edge, let's see if the angle is a good one to keep
                            if (e1.Angle(e2, f.Normale) > angle && !e1.SameDirectionAndPoints(e2))
                            {               // if it turns right (or maybe left, but let's imagine it is right)
                                indice = j; // we update indice, we found a better edge
                                angle  = e1.Angle(e2, f.Normale);
                            } // TODO maybe we need to modify the condition on the angle depending on the orientation of the face ?
                        }
                    }

                    // i hope u checked it was really a face otherwise u may get a weird result
                    ordonnedIndices.Add(indice);
                }
            }

            List <Pnt> ordonnedPoints = new List <Pnt>();

            foreach (int indice in ordonnedIndices)
            {
                ordonnedPoints.Add(pts[indice]);                                     // we add all our points in the right order
            }
            Face g = new Face(ordonnedPoints.GetRange(0, ordonnedPoints.Count - 1)); // last point is the first point, we dont need it

            if (!this.SameOrder(ordonnedPoints))
            {// not same order
                if (this.orientation == TopAbs_Orientation.TopAbs_FORWARD)
                {
                    g.orientation = TopAbs_Orientation.TopAbs_REVERSED;
                }
                else
                {
                    g.orientation = TopAbs_Orientation.TopAbs_FORWARD;
                }
            }

            return(g);
        }
Exemple #22
0
 public Face(Pnt v1, Pnt v2)
 {
     pts.Add(v1);
     pts.Add(v2);
 }
Exemple #23
0
 /// <summary>
 /// dot product of the two vectors
 /// </summary>
 /// <param name="e1"></param>
 /// <param name="e2"></param>
 /// <returns></returns>
 public static double DotProduct(Pnt e1, Pnt e2)
 {
     return(e1.x * e2.x + e1.y * e2.y + e1.z * e2.z);
 }
Exemple #24
0
        /// <summary>
        /// performs graham on the points of your face and returns triangles
        /// </summary>
        /// <param name="computeCompletely">true-> returns triangles / false -> only applies graham</param>
        /// <returns>returns triangles</returns>
        public Face ToTrianglesGraham(bool computeCompletely)
        {
            UniqueVertices();
            Face f = Graham();

            if (computeCompletely)
            {
                if (f.pts.Count == 4)
                {
                    // __________________________________________________________
                    List <int> tempList1 = new List <int>();
                    Face       tempFace1 = new Face();

                    tempList1.Add(f.RetrievesIndex(f.pts[0]));
                    tempFace1.Add(f.pts[0]);

                    tempList1.Add(f.RetrievesIndex(f.pts[1]));
                    tempFace1.Add(f.pts[1]);

                    tempList1.Add(f.RetrievesIndex(f.pts[3]));
                    tempFace1.Add(f.pts[3]);

                    tempFace1.orientation = f.orientation;

                    f.subFaces.Add(tempFace1);
                    f.triangles.AddRange(tempList1);
                    // __________________________________________________________
                    List <int> tempList2 = new List <int>();
                    Face       tempFace2 = new Face();

                    tempList2.Add(f.RetrievesIndex(f.pts[1]));
                    tempFace2.Add(f.pts[1]);

                    tempList2.Add(f.RetrievesIndex(f.pts[2]));
                    tempFace2.Add(f.pts[2]);

                    tempList2.Add(f.RetrievesIndex(f.pts[3]));
                    tempFace2.Add(f.pts[3]);

                    tempFace2.orientation = f.orientation;

                    f.subFaces.Add(tempFace2);
                    f.triangles.AddRange(tempList2);
                    // __________________________________________________________
                }
                else
                {
                    Pnt centroid = f.Centroid;
                    for (int i = 0; i < f.pts.Count - 1; i++) // the -1 may sound weird but it is because we are adding the centroid to the points ;)
                    {
                        List <int> tempList = new List <int>();
                        Face       tempFace = new Face();

                        //
                        tempList.Add(f.RetrievesIndex(f.pts[i]));
                        tempFace.Add(f.pts[i]);
                        //
                        if (i == f.pts.Count - 1 - 1) // same reason here
                        {
                            tempList.Add(f.RetrievesIndex(f.pts[0]));
                            tempFace.Add(f.pts[0]);
                        }
                        else
                        {
                            tempList.Add(f.RetrievesIndex(f.pts[i + 1]));
                            tempFace.Add(f.pts[i + 1]);
                        }
                        //
                        tempList.Add(f.RetrievesIndex(centroid));
                        tempFace.Add(centroid);
                        //
                        tempFace.orientation = f.orientation;
                        f.subFaces.Add(tempFace);
                        f.triangles.AddRange(tempList);
                    }
                } // looks like it never occurs

                return(f); // ordonned points with triangles set
            }

            //*/
            return(f); // only ordonned pts
        }
Exemple #25
0
 /// <summary>
 /// angle between two edges
 /// </summary>
 /// <param name="e"></param>
 /// <param name="axis"></param>
 /// <returns></returns>
 public double Angle(Edge e, Pnt axis)
 {
     return(this.v.IsEqual(e.v) ? 0 : Pnt.SignedAngle(v, e.v, axis));
 }
Exemple #26
0
 /// <summary>
 /// returns the distance between this and pt
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public double Distance(Pnt pt)
 {
     return(Math.Sqrt((x - pt.x) * (x - pt.x) + (y - pt.y) * (y - pt.y) + (z - pt.z) * (z - pt.z)));
 }
Exemple #27
0
        /// <summary>
        /// angle between the two vectors
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public static double Angle(Pnt p1, Pnt p2)
        {
            double angle = Math.Acos(DotProduct(Normalize(p1), Normalize(p2)));

            return(angle * 360 / (2 * Math.PI)); // in degree;
        }
Exemple #28
0
        /// <summary>
        /// normalization of the vector
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Pnt Normalize(Pnt p)
        {
            double L = Math.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z);

            return(L == 0 ? p : p / L);
        }
Exemple #29
0
 /// <summary>
 /// add a point to the face
 /// </summary>
 /// <param name="v"></param>
 public void Add(Pnt v)
 {
     pts.Add(v);
 }