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); }
public QueryTuple2d(Vector2dTuple3 tuple) { mVertices = tuple; }
public QueryTuple2d(Vector2d v0, Vector2d v1, Vector2d v2) { mVertices = new Vector2dTuple3(v0, v1, v2); }
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); }