/** * Computes closest distance from a vertex to a plane * * @param vertex vertex used to compute the distance * @param face face representing the plane where it is contained * @return the closest distance from the vertex to the plane */ private double computeDistance(Vertex vertex, Face face) { Vector3d normal = face.getNormal(); double a = normal.X; double b = normal.Y; double c = normal.Z; double d = -(a * face.v1.X + b * face.v1.Y + c * face.v1.Z); return(a * vertex.X + b * vertex.Y + c * vertex.Z + d); }
/** * Computes closest distance from a vertex to a plane * * @param vertex vertex used to compute the distance * @param face face representing the plane where it is contained * @return the closest distance from the vertex to the plane */ private double computeDistance(Vertex vertex, Face face) { Vector3d normal = face.getNormal(); double a = normal.x; double b = normal.y; double c = normal.z; double d = -(a * face.v1.x + b * face.v1.y + c * face.v1.z); return(a * vertex.x + b * vertex.y + c * vertex.z + d); }
//----------------------------------CONSTRUCTORS---------------------------------// /** * Constructor for a line. The line created is the intersection between two planes * * @param face1 face representing one of the planes * @param face2 face representing one of the planes */ public Line(Face face1, Face face2) { Vector3d normalFace1 = face1.getNormal(); Vector3d normalFace2 = face2.getNormal(); //direction: cross product of the faces normals //direction = new Vector3d(); //direction.cross(normalFace1, normalFace2); direction = Vector3d.Cross(normalFace1, normalFace2); //if direction lenght is not zero (the planes aren't parallel )... if (!(direction.Length() < TOL)) { //getting a line point, zero is set to a coordinate whose direction //component isn't zero (line intersecting its origin plan) point = new Point3d(); float d1 = -(normalFace1.X * face1.v1.X + normalFace1.Y * face1.v1.Y + normalFace1.Z * face1.v1.Z); float d2 = -(normalFace2.X * face2.v1.X + normalFace2.Y * face2.v1.Y + normalFace2.Z * face2.v1.Z); if (Math.Abs(direction.X) > TOL) { point.X = 0; point.Y = (d2 * normalFace1.Z - d1 * normalFace2.Z) / direction.X; point.Z = (d1 * normalFace2.Y - d2 * normalFace1.Y) / direction.X; } else if (Math.Abs(direction.Y) > TOL) { point.X = (d1 * normalFace2.Z - d2 * normalFace1.Z) / direction.Y; point.Y = 0; point.Z = (d2 * normalFace1.X - d1 * normalFace2.X) / direction.Y; } else { point.X = (d2 * normalFace1.Y - d1 * normalFace2.Y) / direction.Z; point.Y = (d1 * normalFace2.X - d2 * normalFace1.X) / direction.Z; point.Z = 0; } } direction = Vector3d.Normalize(direction); }
//----------------------------------CONSTRUCTORS---------------------------------// /** * Constructor for a line. The line created is the intersection between two planes * * @param face1 face representing one of the planes * @param face2 face representing one of the planes */ public Line(Face face1, Face face2) { Vector3d normalFace1 = face1.getNormal(); Vector3d normalFace2 = face2.getNormal(); //direction: cross product of the faces normals direction = new Vector3d(); direction.cross(normalFace1, normalFace2); //if direction lenght is not zero (the planes aren't parallel )... if (!(direction.length() < TOL)) { //getting a line point, zero is set to a coordinate whose direction //component isn't zero (line intersecting its origin plan) point = new Point3d(); double d1 = -(normalFace1.x * face1.v1.x + normalFace1.y * face1.v1.y + normalFace1.z * face1.v1.z); double d2 = -(normalFace2.x * face2.v1.x + normalFace2.y * face2.v1.y + normalFace2.z * face2.v1.z); if (Math.Abs(direction.x) > TOL) { point.x = 0; point.y = (d2 * normalFace1.z - d1 * normalFace2.z) / direction.x; point.z = (d1 * normalFace2.y - d2 * normalFace1.y) / direction.x; } else if (Math.Abs(direction.y) > TOL) { point.x = (d1 * normalFace2.z - d2 * normalFace1.z) / direction.y; point.y = 0; point.z = (d2 * normalFace1.x - d1 * normalFace2.x) / direction.y; } else { point.x = (d2 * normalFace1.y - d1 * normalFace2.y) / direction.z; point.y = (d1 * normalFace2.x - d2 * normalFace1.x) / direction.z; point.z = 0; } } direction.normalize(); }
/** * Classifies the face based on the ray trace technique * * @param object object3d used to compute the face status */ public void rayTraceClassify(Object3D obj) { //creating a ray starting starting at the face baricenter going to the normal direction Point3d p0 = new Point3d(); p0.X = (v1.X + v2.X + v3.X) / 3.0f; p0.Y = (v1.Y + v2.Y + v3.Y) / 3.0f; p0.Z = (v1.Z + v2.Z + v3.Z) / 3.0f; Line ray = new Line(getNormal(), p0); bool success; double dotProduct, distance; Point3d?intersectionPoint; Face closestFace = null; double closestDistance; do { success = true; closestDistance = Double.MaxValue; //for each face from the other solid... for (int i = 0; i < obj.getNumFaces(); i++) { Face face = obj.getFace(i); //dotProduct = face.getNormal().dot(ray.getDirection()); dotProduct = Vector3d.Dot(face.getNormal(), ray.getDirection()); intersectionPoint = ray.computePlaneIntersection(face.getNormal(), face.v1.getPosition()); //if ray intersects the plane... if (intersectionPoint != null) { distance = ray.computePointToPointDistance(intersectionPoint.Value); //if ray lies in plane... if (Math.Abs(distance) < TOL && Math.Abs(dotProduct) < TOL) { //disturb the ray in order to not lie into another plane ray.perturbDirection(); success = false; break; } //if ray starts in plane... if (Math.Abs(distance) < TOL && Math.Abs(dotProduct) > TOL) { //if ray intersects the face... if (face.hasPoint(intersectionPoint.Value)) { //faces coincide closestFace = face; closestDistance = 0; break; } } //if ray intersects plane... else if (Math.Abs(dotProduct) > TOL && distance > TOL) { if (distance < closestDistance) { //if ray intersects the face; if (face.hasPoint(intersectionPoint.Value)) { //this face is the closest face untill now closestDistance = distance; closestFace = face; } } } } } } while (success == false); //none face found: outside face if (closestFace == null) { status = OUTSIDE; } //face found: test dot product else { //dotProduct = closestFace.getNormal().dot(ray.getDirection()); dotProduct = Vector3d.Dot(closestFace.getNormal(), ray.getDirection()); //distance = 0: coplanar faces if (Math.Abs(closestDistance) < TOL) { if (dotProduct > TOL) { status = SAME; } else if (dotProduct < -TOL) { status = OPPOSITE; } } //dot product > 0 (same direction): inside face else if (dotProduct > TOL) { status = INSIDE; } //dot product < 0 (opposite direction): outside face else if (dotProduct < -TOL) { status = OUTSIDE; } } }
/** * Computes closest distance from a vertex to a plane * * @param vertex vertex used to compute the distance * @param face face representing the plane where it is contained * @return the closest distance from the vertex to the plane */ private double computeDistance(Vertex vertex, Face face) { Vector3d normal = face.getNormal(); double a = normal.x; double b = normal.y; double c = normal.z; double d = -(a * face.v1.x + b * face.v1.y + c * face.v1.z); return a * vertex.x + b * vertex.y + c * vertex.z + d; }