I am making an attempt to find out if a degree is inside or outdoors a (triangle) mesh.
One of the simplest ways I discovered was to solid a ray from the purpose and rely what number of triangles intersect. (Odd and even).
I used Möller–Trumbore algo to verify the ray/triangle-intersection.
However I now have a scenario the place level is outdoors the dice. However it touches the aspect. So the ray intersects the triangle, however would not go contained in the dice. So I get just one intersection with a triangle. What usually means, it’s contained in the dice. What is certainly flawed.
Interactive instance of the case (white triangles doesn’t intersect, yellow triangles intersect, intersection and begin level in purple. And in addition the ray in purple):
https://coffee-wrennie-15.tiiny.website/
Are there methods to differentiate circumstances that simply brush the mesh? Or are there extra strong algorithms?
Simply to be full, the code
non-public boolean isInsideInner2(VectorMM level) {
VectorMM route = createSafeRay(); // Create ray that is not parallel with any triangle
HashSet<VectorMM> uniques = new HashSet<>();
for(int i = 0; i!= triangles.size ; i++) {
VectorMM intersect = rayIntersectsTriangle2(level, route, triangles[i]);
if(intersect == level) {
return true;
}
if(intersect != null) {
uniques.add(intersect);
}
}
return (uniques.measurement() % 2) == 1 ? true : false;
}
non-public static VectorMM rayIntersectsTriangle2(VectorMM rayOrigin,
VectorMM rayVector,
VectorMM[] triangle) {
// supply: https://en.wikipedia.org/wiki/MpercentC3percentB6llerpercentE2percent80percent93Trumbore_intersection_algorithm
VectorMM vertex0 = triangle[0];
VectorMM vertex1 = triangle[1];
VectorMM vertex2 = triangle[2];
VectorMM edge1 = VectorMM.sub(vertex1, vertex0);
VectorMM edge2 = VectorMM.sub(vertex2, vertex0);
VectorMMLong h = VectorMM.crossproductPrecise(rayVector, edge2);
double a = VectorMMLong.dot(edge1, h);
if (a > -EPSILON && a < EPSILON) {
throw new AssertionError("Mustn't occur as we eliminated all parallell rays by creating the rayVector");
}
double f = 1.0 / a;
VectorMM s = VectorMM.sub(rayOrigin, vertex0);
double u = f * (VectorMMLong.dot(s,h));
if (u < -EPSILON || u > 1.0+EPSILON) {
return null;
}
VectorMMLong q = VectorMM.crossproductPrecise(s, edge1);
double v = f * VectorMMLong.dot(rayVector, q);
if (v < -EPSILON || u + v > 1.0+EPSILON) {
return null;
}
double t = f * VectorMMLong.dot(edge2, q);
if(t >= 0) {
if(t == 0) {
return rayOrigin;
}
return VectorMM.add(rayOrigin, VectorMM.mul(rayVector, t));
}
return null;
}