Esempio n. 1
0
        /* Assumption: p lies in the plane containing T.
         *  Returns a char:
         *   'V': the query point p coincides with a Vertex of triangle T.
         *   'E': the query point p is in the relative interior of an Edge of triangle T.
         *   'F': the query point p is in the relative interior of a Face of triangle T.
         *   '0': the query point p does not intersect (misses) triangle T.
         */

        public char InTri3D(tPointi T, int m, tPointi p)
        {
            int     i;      /* Index for X,Y,Z           */
            int     j;      /* Index for X,Y             */
            int     k;      /* Index for triangle vertex */
            tPointi pp;     /* projected p */

            tPointi[] Tp;   /* projected T: three new vertices */

            pp    = new tPointi();
            Tp    = new tPointi[3];
            Tp[0] = new tPointi();
            Tp[1] = new tPointi();
            Tp[2] = new tPointi();


            /* Project out coordinate m in both p and the triangular face */
            j = 0;
            for (i = 0; i < DIM; i++)
            {
                if (i != m)
                {    /* skip largest coordinate */
                    pp.p[j] = p.p[i];
                    for (k = 0; k < 3; k++)
                    {
                        Tp[k].p[j] = Vertices[T.p[k]].p[i];
                    }
                    j++;
                }
            }

            return(InTri2D(Tp, pp));
        }
Esempio n. 2
0
        public int ComputeBox(int F, tPointi bmin, tPointi bmax)
        {
            int    i, j;
            double radius;

            for (i = 0; i < F; i++)
            {
                for (j = 0; j < DIM; j++)
                {
                    if (Vertices[i].p[j] < bmin.p[j])
                    {
                        bmin.p[j] = Vertices[i].p[j];
                    }
                    if (Vertices[i].p[j] > bmax.p[j])
                    {
                        bmax.p[j] = Vertices[i].p[j];
                    }
                }
            }

            radius = Math.Sqrt(Math.Pow((double)(bmax.p[Xindex] - bmin.p[Xindex]), 2.0) +
                               Math.Pow((double)(bmax.p[Yindex] - bmin.p[Yindex]), 2.0) +
                               Math.Pow((double)(bmax.p[Zindex] - bmin.p[Zindex]), 2.0));
            System.Diagnostics.Debug.WriteLine("radius =  " + radius);

            return((int)((radius + 1 + .5)) + 1);
        }
Esempio n. 3
0
        public char SegTriInt(tPointi T, tPointi q, tPointi r, tPointd p)
        {
            char code = '?';

            m = -1;

            code = SegPlaneInt(T, q, r, p, m);
            System.Diagnostics.Debug.WriteLine("****M is now after segplaneint: " + m);
            System.Diagnostics.Debug.WriteLine("SegPlaneInt code= " + code + " , m= " + m + "; p=()" + p.p[Xindex] + " , " + p.p[Yindex] + " , " + p.p[Zindex]);

            if (code == '0')
            {
                return('0');
            }
            else if (code == 'q')
            {
                return(InTri3D(T, m, q));
            }
            else if (code == 'r')
            {
                return(InTri3D(T, m, r));
            }
            else if (code == 'p')
            {
                return(InPlane(T, m, q, r, p));
            }
            else if (code == '1')
            {
                return(SegTriCross(T, q, r));
            }
            else /* Error */
            {
                return(code);
            }
        }
Esempio n. 4
0
        /*---------------------------------------------------------------------
        *  Computes N & D and returns index m of largest component.
        *  ---------------------------------------------------------------------*/
        public int PlaneCoeff(tPointi T, tPointd N, double D0)
        {
            int    i;
            double t;             /* Temp storage */
            double biggest = 0.0; /* Largest component of normal vector. */

            m = 0;                /* Index of largest component. */

            NormalVec(Vertices[T.p[0]], Vertices[T.p[1]], Vertices[T.p[2]], N);
            System.Diagnostics.Debug.WriteLine("PlaneCoeff: N=()" + N.p[Xindex] + " , " + N.p[Yindex] + " , " + N.p[Zindex]);
            D = Dot(Vertices[T.p[0]], N);
            System.Diagnostics.Debug.WriteLine("D should be in planecoeff" + D);

            /* Find the largest component of N. */
            for (i = 0; i < DIM; i++)
            {
                t = (float)(Math.Abs(N.p[i]));
                if (t > biggest)
                {
                    biggest = t;
                    m       = i;
                }
            }
            return(m);
        }
Esempio n. 5
0
        public char InTri2D(tPointi[] Tp, tPointi pp)
        {
            int area0, area1, area2;

            /* compute three TriangleSign() values for pp w.r.t. each edge of the face in 2D */
            System.Diagnostics.Debug.WriteLine("In tri 2d pp, tp 0,1,2" + pp.p[0] + ", " + pp.p[1] + " , " + pp.p[2]);
            for (int b = 0; b < 3; b++)
            {
                for (int r = 0; r < 3; r++)
                {
                    System.Diagnostics.Debug.WriteLine(Tp[b].p[r]);
                }
            }


            area0 = TriangleSign(pp, Tp[0], Tp[1]);
            area1 = TriangleSign(pp, Tp[1], Tp[2]);
            area2 = TriangleSign(pp, Tp[2], Tp[0]);

            System.Diagnostics.Debug.WriteLine("area0= " + area0 + "  area1= " + area1 + " area2= " + area2);

            if ((area0 == 0) && (area1 > 0) && (area2 > 0) ||
                (area1 == 0) && (area0 > 0) && (area2 > 0) ||
                (area2 == 0) && (area0 > 0) && (area1 > 0))
            {
                return('E');
            }

            if ((area0 == 0) && (area1 < 0) && (area2 < 0) ||
                (area1 == 0) && (area0 < 0) && (area2 < 0) ||
                (area2 == 0) && (area0 < 0) && (area1 < 0))
            {
                return('E');
            }

            if ((area0 > 0) && (area1 > 0) && (area2 > 0) ||
                (area0 < 0) && (area1 < 0) && (area2 < 0))
            {
                return('F');
            }

            if ((area0 == 0) && (area1 == 0) && (area2 == 0))
            {
                System.Diagnostics.Debug.WriteLine("Error in InTriD");
                return(' ');
            }
            if ((area0 == 0) && (area1 == 0) ||
                (area0 == 0) && (area2 == 0) ||
                (area1 == 0) && (area2 == 0))
            {
                return('V');
            }

            else
            {
                return('0');
            }
        }
Esempio n. 6
0
 /*---------------------------------------------------------------------
 *  Compute the cross product of (b-a)x(c-a) and place into N.
 *  ---------------------------------------------------------------------*/
 public void NormalVec(tPointi a, tPointi b, tPointi c, tPointd N)
 {
     N.p[Xindex] = (c.p[Zindex] - a.p[Zindex]) * (b.p[Yindex] - a.p[Yindex]) -
                   (b.p[Zindex] - a.p[Zindex]) * (c.p[Yindex] - a.p[Yindex]);
     N.p[Yindex] = (b.p[Zindex] - a.p[Zindex]) * (c.p[Xindex] - a.p[Xindex]) -
                   (b.p[Xindex] - a.p[Xindex]) * (c.p[Zindex] - a.p[Zindex]);
     N.p[Zindex] = (b.p[Xindex] - a.p[Xindex]) * (c.p[Yindex] - a.p[Yindex]) -
                   (b.p[Yindex] - a.p[Yindex]) * (c.p[Xindex] - a.p[Xindex]);
 }
Esempio n. 7
0
        /*---------------------------------------------------------------------
        *  a - b ==> c.
        *  ---------------------------------------------------------------------*/
        public void SubVec(tPointi a, tPointi b, tPointi c)
        {
            int i;

            for (i = 0; i < DIM; i++)
            {
                c.p[i] = a.p[i] - b.p[i];
            }
        }
Esempio n. 8
0
        public void AddVec(tPointi q, tPointi ray)
        {
            int i;

            for (i = 0; i < DIM; i++)
            {
                ray.p[i] = q.p[i] + ray.p[i];
            }
        }
Esempio n. 9
0
 public bool InBox(tPointi q, tPointi bmin, tPointi bmax)
 {
     if ((bmin.p[Xindex] <= q.p[Xindex]) && (q.p[Xindex] <= bmax.p[Xindex]) &&
         (bmin.p[Yindex] <= q.p[Yindex]) && (q.p[Yindex] <= bmax.p[Yindex]) &&
         (bmin.p[Zindex] <= q.p[Zindex]) && (q.p[Zindex] <= bmax.p[Zindex]))
     {
         return(true);
     }
     return(false);
 }
Esempio n. 10
0
        /*---------------------------------------------------------------------
        *  Returns the dot product of the two input vectors.
        *  ---------------------------------------------------------------------*/
        public double Dot(tPointi a, tPointd b)
        {
            int    i;
            double sum = 0.0;

            for (i = 0; i < DIM; i++)
            {
                sum += a.p[i] * b.p[i];
            }

            return(sum);
        }
Esempio n. 11
0
        /*---------------------------------------------------------------------
        *  The signed volumes of three tetrahedra are computed, determined
        *  by the segment qr, and each edge of the triangle.
        *  Returns a char:
        *  'v': the open segment includes a vertex of T.
        *  'e': the open segment includes a point in the relative interior of an edge
        *  of T.
        *  'f': the open segment includes a point in the relative interior of a face
        *  of T.
        *  '0': the open segment does not intersect triangle T.
        *  ---------------------------------------------------------------------*/

        public char SegTriCross(tPointi T, tPointi q, tPointi r)
        {
            int vol0, vol1, vol2;

            vol0 = VolumeSign(q, Vertices[T.p[0]], Vertices[T.p[1]], r);
            vol1 = VolumeSign(q, Vertices[T.p[1]], Vertices[T.p[2]], r);
            vol2 = VolumeSign(q, Vertices[T.p[2]], Vertices[T.p[0]], r);

            System.Diagnostics.Debug.WriteLine("SegTriCross:  vol0 = " + vol0 + " vol1 = " + vol1 + " vol2 = " + vol2);

            /* Same sign: segment intersects interior of triangle. */
            if (((vol0 > 0) && (vol1 > 0) && (vol2 > 0)) ||
                ((vol0 < 0) && (vol1 < 0) && (vol2 < 0)))
            {
                return('f');
            }

            /* Opposite sign: no intersection between segment and triangle */
            if (((vol0 > 0) || (vol1 > 0) || (vol2 > 0)) &&
                ((vol0 < 0) || (vol1 < 0) || (vol2 < 0)))
            {
                return('0');
            }

            else if ((vol0 == 0) && (vol1 == 0) && (vol2 == 0))
            {
                System.Diagnostics.Debug.WriteLine("Error 1 in SegTriCross");
                return('b');
            }

            /* Two zeros: segment intersects vertex. */
            else if (((vol0 == 0) && (vol1 == 0)) ||
                     ((vol0 == 0) && (vol2 == 0)) ||
                     ((vol1 == 0) && (vol2 == 0)))
            {
                return('v');
            }

            /* One zero: segment intersects edge. */
            else if ((vol0 == 0) || (vol1 == 0) || (vol2 == 0))
            {
                return('e');
            }

            else
            {
                System.Diagnostics.Debug.WriteLine("Error 2 in SegTriCross ");
                return('b');
            }
        }
Esempio n. 12
0
        public int VolumeSign(tPointi a, tPointi b, tPointi c, tPointi d)
        {
            double vol;
            double ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz;
            double bxdx, bydy, bzdz, cxdx, cydy, czdz;

            ax = a.p[Xindex];
            ay = a.p[Yindex];
            az = a.p[Zindex];
            bx = b.p[Xindex];
            by = b.p[Yindex];
            bz = b.p[Zindex];
            cx = c.p[Xindex];
            cy = c.p[Yindex];
            cz = c.p[Zindex];
            dx = d.p[Xindex];
            dy = d.p[Yindex];
            dz = d.p[Zindex];

            bxdx = bx - dx;
            bydy = by - dy;
            bzdz = bz - dz;
            cxdx = cx - dx;
            cydy = cy - dy;
            czdz = cz - dz;
            vol  = (az - dz) * (bxdx * cydy - bydy * cxdx)
                   + (ay - dy) * (bzdz * cxdx - bxdx * czdz)
                   + (ax - dx) * (bydy * czdz - bzdz * cydy);


            /* The volume should be an integer. */
            if (vol > 0.5)
            {
                return(1);
            }
            else if (vol < -0.5)
            {
                return(-1);
            }
            else
            {
                return(0);
            }
        }
Esempio n. 13
0
        /*
         * This function returns a char:
         *  '0': the segment [ab] does not intersect (completely misses) the
         *       bounding box surrounding the n-th triangle T.  It lies
         *       strictly to one side of one of the six supporting planes.
         *  '?': status unknown: the segment may or may not intersect T.
         */

        public char BoxTest(int n, tPointi a, tPointi b)
        {
            int i; /* Coordinate index */
            int w;

            for (i = 0; i < DIM; i++)
            {
                w = Box[n][0].p[i]; /* min: lower left */
                if ((a.p[i] < w) && (b.p[i] < w))
                {
                    return('0');
                }
                w = Box[n][1].p[i]; /* max: upper right */
                if ((a.p[i] > w) && (b.p[i] > w))
                {
                    return('0');
                }
            }
            return('?');
        }
Esempio n. 14
0
        public int TriangleSign(tPointi a, tPointi b, tPointi c)
        {
            double area2;

            area2 = (b.p[0] - a.p[0]) * (double)(c.p[1] - a.p[1]) -
                    (c.p[0] - a.p[0]) * (double)(b.p[1] - a.p[1]);

            /* The area should be an integer. */
            if (area2 > 0.5)
            {
                return(1);
            }
            else if (area2 < -0.5)
            {
                return(-1);
            }
            else
            {
                return(0);
            }
        }
Esempio n. 15
0
        /* Return a random ray endpoint */

        void RandomRay(tPointi ray, int radius)
        {
            double x, y, z, w, t;

            /* Generate a random point on a sphere of radius 1. */

            /* the sphere is sliced at z, and a random point at angle t
             * generated on the circle of intersection. */
            Random r = new Random();

            z = 2.0 * (double)r.NextDouble() - 1.0;
            t = 2.0 * Math.PI * r.NextDouble();
            w = Math.Sqrt(1 - z * z);
            x = w * Math.Cos(t);
            y = w * Math.Sin(t);

            ray.p[Xindex] = (int)(radius * x + .5);
            ray.p[Yindex] = (int)(radius * y + .5);
            ray.p[Zindex] = (int)(radius * z + .5);

            System.Diagnostics.Debug.WriteLine("RandomRay returns" + ray.p[Xindex] + " , " + ray.p[Yindex] + " , " + ray.p[Zindex]);
        }
Esempio n. 16
0
        //***********************

        /*
         * This function returns a char:
         *  'V': the query point a coincides with a Vertex of polyhedron P.
         *  'E': the query point a is in the relative interior of an Edge of polyhedron P.
         *  'F': the query point a is in the relative interior of a Face of polyhedron P.
         *  'i': the query point a is strictly interior to polyhedron P.
         *  'o': the query point a is strictly exterior to( or outside of) polyhedron P.
         */

        char InPolyhedron(int F, tPointi q, tPointi bmin, tPointi bmax, int radius)
        {
            tPointi r;  /* Ray endpoint. */
            tPointd p;  /* Intersection point; not used. */
            int     f, k = 0, crossings = 0;
            char    code = '?';

            r = new tPointi();
            p = new tPointd();

            /* If query point is outside bounding box, finished. */
            if (!InBox(q, bmin, bmax))
            {
                return('o');
            }


            while (k++ < F)
            {
                crossings = 0;

                RandomRay(r, radius);
                AddVec(q, r);
                System.Diagnostics.Debug.WriteLine("Ray endpoint: (" + r.p[0] + " , " + r.p[1] + " , " + r.p[2] + " )");

                for (f = 0; f < F; f++)
                {  /* Begin check each face */
                    if (BoxTest(f, q, r) == '0')
                    {
                        code = '0';
                        System.Diagnostics.Debug.WriteLine("BoxTest = 0!");
                    }
                    else
                    {
                        code = SegTriInt(Faces[f], q, r, p);
                    }
                    System.Diagnostics.Debug.WriteLine("Face = " + f + ": BoxTest/SegTriInt returns " + code);

                    /* If ray is degenerate, then goto outer while to generate another. */
                    if (code == 'p' || code == 'v' || code == 'e')
                    {
                        System.Diagnostics.Debug.WriteLine("Degenerate ray");
                        continue;
                    }

                    /* If ray hits face at interior point, increment crossings. */

                    else if (code == 'f')
                    {
                        crossings++;
                        System.Diagnostics.Debug.WriteLine("crossings = " + crossings);
                    }

                    /* If query endpoint q sits on a V/E/F, return that code. */
                    else if (code == 'V' || code == 'E' || code == 'F')
                    {
                        return(code);
                    }

                    /* If ray misses triangle, do nothing. */
                    else if (code == '0')
                    {
                        continue;
                    }

                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Error");
                        return(' ');
                    }
                } /* End check each face */

                /* No degeneracies encountered: ray is generic, so finished. */
                break;
            } /* End while loop */

            System.Diagnostics.Debug.WriteLine("Crossings at the end = " + crossings);
            /* q strictly interior to polyhedron iff an odd number of crossings. */
            if ((crossings % 2) == 1)
            {
                return('i');
            }
            else
            {
                return('o');
            }
        }
Esempio n. 17
0
        /*---------------------------------------------------------------------
        *   'p': The segment lies wholly within the plane.
        *   'q': The q endpoint is on the plane (but not 'p').
        *   'r': The r endpoint is on the plane (but not 'p').
        *   '0': The segment lies strictly to one side or the other of the plane.
        *   '1': The segement intersects the plane, and 'p' does not hold.
        *  ---------------------------------------------------------------------*/
        public char SegPlaneInt(tPointi T, tPointi q, tPointi r, tPointd p, int m)
        {
            tPointd N;
            int     D0 = 0;
            tPointi rq;
            double  num, denom, t;
            int     i;

            N  = new tPointd();
            rq = new tPointi();

            m = PlaneCoeff(T, N, D0);

            System.Diagnostics.Debug.WriteLine("m= " + m + "; plane=( " + N.p[Xindex] + " , " + N.p[Yindex] + " , " + N.p[Zindex] + " , " + D + " )");
            num = D - Dot(q, N);
            SubVec(r, q, rq);
            denom = Dot(rq, N);

            System.Diagnostics.Debug.WriteLine("SegPlaneInt: num=" + num + " , denom= " + denom);

            if (denom == 0.0)
            {                   /* Segment is parallel to plane. */
                if (num == 0.0) /* q is on plane. */
                {
                    return('p');
                }
                else
                {
                    return('0');
                }
            }
            else
            {
                t = num / denom;
            }
            System.Diagnostics.Debug.WriteLine("SegPlaneInt: t= " + t);

            System.Diagnostics.Debug.WriteLine("p in seg plane int is: p=()");
            for (i = 0; i < DIM; i++)
            {
                p.p[i] = q.p[i] + t * (r.p[i] - q.p[i]);
                System.Diagnostics.Debug.WriteLine(p.p[i]);
            }


            if ((0.0 < t) && (t < 1.0))
            {
                return('1');
            }
            else if (num == 0.0)   /* t == 0 */
            {
                return('q');
            }
            else if (num == denom) /* t == 1 */
            {
                return('r');
            }
            else
            {
                return('0');
            }
        }
Esempio n. 18
0
 public char InPlane(tPointi T, int m, tPointi q, tPointi r, tPointd p)
 {
     /* NOT IMPLEMENTED */
     return('p');
 }
Esempio n. 19
0
        public InPolyh()
        {
            tPointi bmin, bmax;
            double  radius;

            char[] line = new char[20];
            int    i    = 0;

            Vertices = new tPointi[PMAX];
            Faces    = new tPointi[PMAX];
            Box      = new tPointi[PMAX][];

            //n = ReadVertices();
            // F = ReadFaces();
            VerifVertices();

            /* Initialize the bounding box */
            bmin = new tPointi();
            bmax = new tPointi();

            for (i = 0; i < DIM; i++)
            {
                bmin.p[i] = bmax.p[i] = Vertices[0].p[i];
            }

            radius = ComputeBox(n, bmin, bmax);

            System.Diagnostics.Debug.WriteLine("radius=" + radius);

            System.Diagnostics.Debug.WriteLine("Please input query point");
            i = 0;

            //try{
            //         System.Diagnostics.Debug.WriteLine("\n\nInput query point:\nCoord-s must be seperated by a *tab*\n"+
            //              "ENTER after each point"+"\nTo finish input type end + "+
            //              "ENTER at the end"+
            //              "\nExample:\n17      23      123\n34      5      1\nend\n"+
            //              "-----------------start entering data-------------------");
            //   //do {

            //  do {
            //c = (char) System.in.read();
            //line[i] = c;
            //i++;
            //  } while (c !='\n' );
            //  s = new String(line);
            //  s = s.Substring(0,i-1);
            //  if (s.Equals("end"))
            //break;
            //  flag = false;
            //  counter = 0;
            //  for (int j=0; j < s.Length(); j++) {
            //if (s.charAt(j) == '\t')
            //  counter++;
            //if (counter == 2) {
            //  flag = true; break;
            //}
            //  }
            //  if (flag) {
            //int t = s.IndexOf('\t');
            //int t1 = s.LastIndexOf('\t');
            //x = double.TryParse(s.Substring(0,t));
            //y = double.TryParse(s.Substring(t+1,t1));
            //z = double.TryParse(s.Substring(t1+1,s.Length()));
            //q = new tPointi(x, y, z);

            //	q.x = x;
            //	q.y = y;
            //	q.z = z;
            //    i=0;
            //      }
            //      else
            //    break;

            //      char ans = InPolyhedron(F, q, bmin, bmax, radius);
            //      System.Diagnostics.Debug.WriteLine("InPolyhedron returned:  "+ans);

            //    } while (!s.Equals("end"));
            // }
            //catch (NumberFormatException e) {System.Diagnostics.Debug.WriteLine ("Invalid input"); return;}
        }