bool ContainsPoint(ref Triangle3d triangle, ref Plane3d plane, Vector3d point)
        {
            // Generate a coordinate system for the plane.  The incoming triangle has
            // vertices <V0,V1,V2>.  The incoming plane has unit-length normal N.
            // The incoming point is P.  V0 is chosen as the origin for the plane. The
            // coordinate axis directions are two unit-length vectors, U0 and U1,
            // constructed so that {U0,U1,N} is an orthonormal set.  Any point Q
            // in the plane may be written as Q = V0 + x0*U0 + x1*U1.  The coordinates
            // are computed as x0 = Dot(U0,Q-V0) and x1 = Dot(U1,Q-V0).
            Vector3d U0 = Vector3d.Zero, U1 = Vector3d.Zero;

            Vector3d.GenerateComplementBasis(ref U0, ref U1, plane.Normal);

            // Compute the planar coordinates for the points P, V1, and V2.  To
            // simplify matters, the origin is subtracted from the points, in which
            // case the planar coordinates are for P-V0, V1-V0, and V2-V0.
            Vector3d PmV0  = point - triangle[0];
            Vector3d V1mV0 = triangle[1] - triangle[0];
            Vector3d V2mV0 = triangle[2] - triangle[0];

            // The planar representation of P-V0.
            Vector2d ProjP = new Vector2d(U0.Dot(PmV0), U1.Dot(PmV0));

            // The planar representation of the triangle <V0-V0,V1-V0,V2-V0>.
            Vector2dTuple3 ProjV = new Vector2dTuple3(
                Vector2d.Zero,
                new Vector2d(U0.Dot(V1mV0), U1.Dot(V1mV0)),
                new Vector2d(U0.Dot(V2mV0), U1.Dot(V2mV0)));

            // Test whether P-V0 is in the triangle <0,V1-V0,V2-V0>.
            QueryTuple2d query = new QueryTuple2d(ProjV);

            if (query.ToTriangle(ProjP, 0, 1, 2) <= 0)
            {
                Result    = IntersectionResult.Intersects;
                Type      = IntersectionType.Point;
                Quantity  = 1;
                Points[0] = point;
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
 public QueryTuple2d(Vector2dTuple3 tuple)
 {
     mVertices = tuple;
 }
Esempio n. 3
0
 public QueryTuple2d(Vector2d v0, Vector2d v1, Vector2d v2)
 {
     mVertices = new Vector2dTuple3(v0, v1, v2);
 }
Esempio n. 4
0
        Circle UpdateSupport3(int i, int[] permutation, Support support)
        {
            var point = new Vector2dTuple3(
                Points[permutation[support.Index[0]]],                  // P0
                Points[permutation[support.Index[1]]],                  // P1
                Points[permutation[support.Index[2]]]                   // P2
                );
            Vector2d P3 = Points[permutation[i]];

            // Permutations of type 2, used for calling ExactCircle2(..).
            int numType2 = 3;


            // Permutations of type 2, used for calling ExactCircle3(..).
            int numType3 = 3;

            Circle[] circle = circle_buf;
            int      indexCircle = 0;
            double   minRSqr = double.MaxValue;
            int      indexMinRSqr = -1;
            double   distDiff = 0, minDistDiff = double.MaxValue;
            int      indexMinDistDiff = -1;

            // Permutations of type 2.
            int j;

            for (j = 0; j < numType2; ++j, ++indexCircle)
            {
                circle[indexCircle] = ExactCircle2(point[type2_3[j, 0]], ref P3);
                if (circle[indexCircle].Radius < minRSqr)
                {
                    if (Contains(point[type2_3[j, 1]], ref circle[indexCircle], ref distDiff) &&
                        Contains(point[type2_3[j, 2]], ref circle[indexCircle], ref distDiff))
                    {
                        minRSqr      = circle[indexCircle].Radius;
                        indexMinRSqr = indexCircle;
                    }
                    else if (distDiff < minDistDiff)
                    {
                        minDistDiff      = distDiff;
                        indexMinDistDiff = indexCircle;
                    }
                }
            }

            // Permutations of type 3.
            for (j = 0; j < numType3; ++j, ++indexCircle)
            {
                circle[indexCircle] = ExactCircle3(point[type3_3[j, 0]], point[type3_3[j, 1]], ref P3);
                if (circle[indexCircle].Radius < minRSqr)
                {
                    if (Contains(point[type3_3[j, 2]], ref circle[indexCircle], ref distDiff))
                    {
                        minRSqr      = circle[indexCircle].Radius;
                        indexMinRSqr = indexCircle;
                    }
                    else if (distDiff < minDistDiff)
                    {
                        minDistDiff      = distDiff;
                        indexMinDistDiff = indexCircle;
                    }
                }
            }

            // Theoreticaly, indexMinRSqr >= 0, but floating-point round-off errors
            // can lead to indexMinRSqr == -1.  When this happens, the minimal circle
            // is chosen to be the one that has the minimum absolute errors between
            // the circle and points (barely) outside the circle.
            if (indexMinRSqr == -1)
            {
                indexMinRSqr = indexMinDistDiff;
            }

            Circle minimal = circle[indexMinRSqr];

            switch (indexMinRSqr)
            {
            case 0:
                support.Quantity = 2;
                support.Index[1] = i;
                break;

            case 1:
                support.Quantity = 2;
                support.Index[0] = i;
                break;

            case 2:
                support.Quantity = 2;
                support.Index[0] = support.Index[2];
                support.Index[1] = i;
                break;

            case 3:
                support.Index[2] = i;
                break;

            case 4:
                support.Index[1] = i;
                break;

            case 5:
                support.Index[0] = i;
                break;
            }

            return(minimal);
        }