Exemplo n.º 1
0
            /// <summary>
            /// Ray-Triangle intersection algorithm, based on the algorithm published by Tomas Akenine-Möller, May 2000
            /// </summary>
            /// <param name="orig">Ray origin point</param>
            /// <param name="dir">Ray direction vector</param>
            /// <param name="vert0">First triangle vertex</param>
            /// <param name="vert1">Second triangle vertex</param>
            /// <param name="vert2">Third triangle vertex</param>
            /// <param name="t">t-value along ray where an intersection point has been found (if any).</param>
            /// <param name="u">u-value on triangle where an intersection point has been found (if any).</param>
            /// <param name="v">v-value on triangle where an intersection point has been found (if any).</param>
            /// <returns>True if an intersection was found, false if not.</returns>
            protected bool RayXtri(Point orig, Vector dir, Point vert0, Point vert1, Point vert2, ref double t, ref double u, ref double v)
            {
                /* find vectors for two edges sharing vert0 */
                Vector edge1 = vert1 - vert0;
                Vector edge2 = vert2 - vert0;

                /* begin calculating determinant - also used to calculate U parameter */
                Vector pvec = Hare_math.Cross(dir, edge2);

                /* if determinant is near zero, ray lies in plane of triangle */
                double det = Hare_math.Dot(edge1, pvec);

                /* calculate distance from vert0 to ray origin */
                Vector tvec   = orig - vert0;
                double invdet = 1.0 / det;

                Vector qvec = Hare_math.Cross(tvec, edge1);

                if (det > 0.000001)
                {
                    u = Hare_math.Dot(tvec, pvec);
                    if (u < 0.0 || u > det)
                    {
                        return(false);
                    }

                    /* calculate V parameter and test bounds */
                    v = Hare_math.Dot(dir, qvec);
                    if (v < 0.0 || u + v > det)
                    {
                        return(false);
                    }
                }
                else if (det < -0.000001)
                {
                    /* calculate U parameter and test bounds */
                    u = Hare_math.Dot(tvec, pvec);
                    if (u > 0.0 || u < det)
                    {
                        return(false);
                    }
                    /* calculate V parameter and test bounds */
                    v = Hare_math.Dot(dir, qvec);
                    if (v > 0.0 || u + v < det)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);  /* ray is parallell to the plane of the triangle */
                }
                t  = Hare_math.Dot(edge2, qvec) * invdet;
                u *= invdet;
                v *= invdet;

                return(true);
            }
Exemplo n.º 2
0
            public Quadrilateral(ref List <Point> Vertices, int index, int id)
                : base(ref Vertices, index, id)
            {
                if (VertexCount != 4)
                {
                    throw new ApplicationException("Faulty Quadrilateral");
                }

                area_Fraction[0] = 0.5 * Hare_math.Cross((Points[1] - Points[0]), (Points[2] - Points[0])).Length();
                area_Fraction[1] = 0.5 * Hare_math.Cross((Points[2] - Points[3]), (Points[1] - Points[3])).Length();
                double Area = area_Fraction[0] + area_Fraction[1];

                area_Fraction[0] /= Area;
                area_Fraction[1] /= Area;
            }
Exemplo n.º 3
0
            public EdgeSource(int[] attr_in, Hare.Geometry.Point PtZ0, Hare.Geometry.Point _PtZ, Vector[] _Tangents)
            {
                attr    = attr_in;
                Tangent = _Tangents;
                Z_Norm  = _PtZ - PtZ0;

                Z_Range   = Z_Norm.Length();
                Z_dot     = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm);
                Z_Norm   /= Z_Range;
                Z_Range_2 = Z_Range / 2;
                Z_mid     = (PtZ0 + _PtZ) / 2;
                Vector Bisector = (Tangent[0] + Tangent[1]) / 2;

                Bisector.Normalize();
                double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector));

                if (BisectAngle == 0)
                {
                    BisectAngle = 1E-12;
                }
                v = new double[2] {
                    Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle)
                };
                v_4pi = new double[2] {
                    v[0] / (4 * Math.PI), v[1] / (4 * Math.PI)
                };
                v_2pi = new double[2] {
                    v[0] / (2 * Math.PI), v[1] / (2 * Math.PI)
                };
                Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm);
                Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1);

                if (Hare_math.Dot(Normal[0], Bisector) > 0)
                {
                    Normal[0] *= -1;
                    Normal[1] *= -1;
                }

                ////////////////////////////
                //VisCheck//
                Rhino.Geometry.Point3d pt = new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z);
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[0].x, Normal[0].y, Normal[0].z));
                Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[1].x, Normal[1].y, Normal[1].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[0].x, Tangent[0].y, Tangent[0].z));
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[1].x, Tangent[1].y, Tangent[1].z));
                //////Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z));
            }
Exemplo n.º 4
0
            public Polygon(ref List <Point> Vertices, int index, int id)
            {
                top_index = index;

                for (int j = 2; j < Vertices.Count; j++)
                {
                    Normal = Hare_math.Cross(Vertices[1] - Vertices[0], Vertices[j] - Vertices[0]);
                    if (!Normal.IsZeroVector())
                    {
                        break;
                    }
                }

                Points = new Point[Vertices.Count];
                for (int p = 0; p < Vertices.Count; p++)
                {
                    Points[p] = Vertices[p];
                }

                Normal.Normalize();

                diffz = new Vector(Normal.x, Normal.y, Normal.z);
                diffx = new Vector(0, 0, 1);
                double proj = Math.Abs(Hare_math.Dot(diffz, diffx));

                if (0.99 < proj && 1.01 > proj)
                {
                    diffx = new Vector(1, 0, 0);
                }
                diffy = new Vector(diffz.x, diffz.y, diffz.z);
                diffy = Hare_math.Cross(diffy, diffx);
                diffx = Hare_math.Cross(diffy, diffz);
                diffx.Normalize();
                diffy.Normalize();
                diffz.Normalize();

                d = Hare_math.Dot(Normal, Points[0]);

                VertexCount    = Points.Length;
                Inv_Dot_Normal = 1 / (Hare_math.Dot(Normal, Normal));
                if (VertexCount < 3)
                {
                    IsDegenerate = true;
                }
                Poly_index = id;
                IsConvex   = Convexity();
            }
Exemplo n.º 5
0
 /// <summary>
 /// Determines whether or not all triangular subdivisions of a convex polygon can be considered coplanar.
 /// </summary>
 /// <param name="P"></param>
 /// <returns></returns>
 public static bool IsCoPlanar(Point[] P)
 {
     if (P.Length > 3)
     {
         Vector First_Tri_CP = Hare_math.Cross(P[1] - P[0], P[2] - P[0]);
         First_Tri_CP.Normalize();
         for (int j = 2, k = 3; k < P.Length; j++, k++)
         {
             Vector V = Hare_math.Cross(P[j] - P[0], P[k] - P[0]);
             double x = Hare_math.Dot(First_Tri_CP, V);
             if (x < 1)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Exemplo n.º 6
0
            public EdgeSource(int[] attr_in, Hare.Geometry.Point Z_mid_in, double Delta_Z, Vector[] _Tangents)
            {
                attr      = attr_in;
                Tangent   = _Tangents;
                Z_Norm    = Hare.Geometry.Hare_math.Cross(_Tangents[0], _Tangents[1]);
                Z_Range   = Delta_Z;
                Z_dot     = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm);
                Z_Range_2 = Z_Range / 2;
                Z_Norm.Normalize();
                Z_mid = Z_mid_in;
                Vector Bisector = (Tangent[0] + Tangent[1]) / 2;

                Bisector.Normalize();
                double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector));

                if (BisectAngle == 0)
                {
                    BisectAngle = 1E-12;
                }
                v = new double[2] {
                    Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle)
                };
                v_4pi = new double[2] {
                    v[0] / (4 * Math.PI), v[1] / (4 * Math.PI)
                };
                v_2pi = new double[2] {
                    v[0] / (2 * Math.PI), v[1] / (2 * Math.PI)
                };
                //BisectAngle = Math.Cos(BisectAngle);
                Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm);
                Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1);

                if (Hare_math.Dot(Normal[0], Bisector) > 0)
                {
                    Normal[0] *= -1;
                    Normal[1] *= -1;
                }
            }
Exemplo n.º 7
0
            public bool Poly_Overlap_Area(Polygon Pts, out double Area)
            {
                System.Collections.Generic.List <Point> XPts = new System.Collections.Generic.List <Point>();
                int ct = 0;

                for (int i = 0; i < Pts.VertextCT; i++)
                {
                    if (this.IsPointInBox(Pts.Points[i]))
                    {
                        ct++;
                        XPts.Add(Pts.Points[i]);
                    }
                }

                if (ct == Pts.VertextCT)
                {
                    if (ct == 3)
                    {
                        Area = Hare_math.Cross(Pts.Points[1] - Pts.Points[0], Pts.Points[2] - Pts.Points[0]).Length() / 2;
                    }
                    else
                    {
                        Area = Hare_math.Cross((Pts.Points[2] - Pts.Points[0]), (Pts.Points[3] - Pts.Points[1])).Length() / 2;
                    }
                    return(true);
                }

                for (int i = 0; i < Pts.VertextCT; i++)
                {
                    int    j    = (i + 1) % Pts.VertextCT;
                    double tmin = 0;
                    Point  X    = new Point();
                    this.Intersect(new Ray(Pts.Points[i], Pts.Points[j] - Pts.Points[i], 0, 0), ref tmin, ref X);
                    if (tmin < 1)
                    {
                        XPts.Add(X);
                    }
                }

                Point  I;
                double u; double v; double t; int id;

                for (int i = 0; i < 12; i++)
                {
                    if (Pts.Intersect(Edge(i), Pts.Points, out I, out u, out v, out t, out id))
                    {
                        XPts.Add(I);
                    }
                }

                if (XPts.Count == 0)
                {
                    Area = 0;
                    return(false);
                }

                //Sort XPts by polar angle.

                Point Center = new Point();

                foreach (Point Pt in XPts)
                {
                    Center += Pt;
                }
                Center /= XPts.Count;

                System.Collections.SortedList PtSort = new System.Collections.SortedList();
                if (Pts.Normal.x == 1)
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.y - Center.y, Pt.z - Center.z), Pt);
                    }
                }
                else if (Pts.Normal.y == 1)
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.x - Center.x, Pt.z - Center.z), Pt);
                    }
                }
                else
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.x - Center.x, Pt.y - Center.y), Pt);
                    }
                }

                Area = 0;

                for (int i = 0; i < PtSort.Count - 2; i++)
                {
                    Area += Hare_math.Cross((Point)PtSort[i + 1] - (Point)PtSort[i], (Point)PtSort[i + 2] - (Point)PtSort[i]).Length() / 2;
                }

                return(true);
            }
Exemplo n.º 8
0
            public bool PolyBoxOverlap(Point[] P)
            {
                Point[][] triangles = new Point[P.Length - 2][];

                for (int q = 0, j = 1, k = 2; k < P.Length; q++, j++, k++)
                {
                    triangles[q] = new Point[] { P[0], P[j], P[k] };
                }

                foreach (Point[] triverts in triangles)
                {
                    /*    use separating axis theorem to test overlap between triangle and box */
                    /*    need to test for overlap in these directions: */
                    /*    1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
                    /*       we do not even need to test these) */
                    /*    2) normal of the triangle */
                    /*    3) crossproduct(edge from tri, {x,y,z}-directin) */
                    /*       this gives 3x3=9 more tests */

                    v0 = new Vector(0, 0, 0);
                    v1 = new Vector(0, 0, 0);
                    v2 = new Vector(0, 0, 0);

                    //   float axis[3];
                    double fex, fey, fez;               // -NJMP- "d" local variable removed
                    Vector normal, e0, e1, e2;

                    /* This is the fastest branch on Sun */
                    /* move everything so that the boxcenter is in (0,0,0) */
                    v0 = triverts[0] - Center;
                    v1 = triverts[1] - Center;
                    v2 = triverts[2] - Center;

                    /* compute triangle edges */
                    e0 = v1 - v0;     /* tri edge 0 */
                    e1 = v2 - v1;     /* tri edge 1 */
                    e2 = v0 - v2;     /* tri edge 2 */

                    /* Bullet 3:  */
                    /*  test the 9 tests first (this was faster) */
                    fex = Math.Abs(e0.x);
                    fey = Math.Abs(e0.y);
                    fez = Math.Abs(e0.z);
                    if (!AXISTEST_X01(e0.z, e0.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y02(e0.z, e0.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z12(e0.y, e0.x, fey, fex))
                    {
                        continue;
                    }

                    fex = Math.Abs(e1.x);
                    fey = Math.Abs(e1.y);
                    fez = Math.Abs(e1.z);
                    if (!AXISTEST_X01(e1.z, e1.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y02(e1.z, e1.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z0(e1.y, e1.x, fey, fex))
                    {
                        continue;
                    }

                    fex = Math.Abs(e2.x);
                    fey = Math.Abs(e2.y);
                    fez = Math.Abs(e2.z);
                    if (!AXISTEST_X2(e2.z, e2.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y1(e2.z, e2.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z12(e2.y, e2.x, fey, fex))
                    {
                        continue;
                    }

                    /* Bullet 1: */
                    /*  first test overlap in the {x,y,z}-directions */
                    /*  find min, max of the triangle each direction, and test for overlap in */
                    /*  that direction -- this is equivalent to testing a minimal AABB around */
                    /*  the triangle against the AABB */

                    /* test in X-direction */
                    FINDMINMAX(v0.x, v1.x, v2.x, ref min, ref max);
                    if (min > halfwidth.x || max < -halfwidth.x)
                    {
                        continue;
                    }

                    /* test in Y-direction */
                    FINDMINMAX(v0.y, v1.y, v2.y, ref min, ref max);
                    if (min > halfwidth.y || max < -halfwidth.y)
                    {
                        continue;
                    }

                    /* test in Z-direction */
                    FINDMINMAX(v0.z, v1.z, v2.z, ref min, ref max);
                    if (min > halfwidth.z || max < -halfwidth.z)
                    {
                        continue;
                    }

                    /* Bullet 2: */
                    /*  test if the box intersects the plane of the triangle */
                    /*  compute plane equation of triangle: normal*x+d=0 */

                    normal = Hare_math.Cross(e0, e1);
                    if (!planeBoxOverlap(normal, v0, halfwidth))
                    {
                        continue;   // -NJMP-
                    }
                    return(true);   /* box and triangle overlaps */
                }
                return(false);
            }