/// <summary> /// Computes closest distance from a vertex to a plane /// </summary> /// <param name="vertex">vertex used to compute the distance</param> /// <param name="face">face representing the plane where it is contained</param> /// <returns>the closest distance from the vertex to the plane</returns> private double ComputeDistance(Vertex vertex, Face face) { Vector3 normal = face.GetNormal(); double distToV1 = Vector3.Dot(normal, face.v1.Position); double distToPositionMinusDistToV1 = Vector3.Dot(normal, vertex.Position) - distToV1; return distToPositionMinusDistToV1; }
/// <summary> /// Computes closest distance from a vertex to a plane /// </summary> /// <param name="vertex">vertex used to compute the distance</param> /// <param name="face">face representing the plane where it is contained</param> /// <returns>the closest distance from the vertex to the plane</returns> private double ComputeDistance(Vertex vertex, Face face) { Vector3d normal = face.GetNormal(); double distToV1 = Vector3d.Dot(normal, face.V1._Position); double distToPositionMinusDistToV1 = Vector3d.Dot(normal, vertex._Position) - distToV1; return(distToPositionMinusDistToV1); }
/// <summary> /// Computes closest distance from a vertex to a plane /// </summary> /// <param name="vertex">vertex used to compute the distance</param> /// <param name="face">face representing the plane where it is contained</param> /// <returns>the closest distance from the vertex to the plane</returns> private double ComputeDistance(Vertex vertex, Face face) { Vector3 normal = face.GetNormal(); double distToV1 = face.GetPlane().distanceToPlaneFromOrigin; double distToVertex = Vector3.Dot(normal, vertex.Position); double distFromFacePlane = distToVertex - distToV1; return(distFromFacePlane); }
/// <summary> /// Constructor for a line.The line created is the intersection between two planes /// </summary> /// <param name="face1">face representing one of the planes</param> /// <param name="face2">face representing one of the planes</param> public Line(Face face1, Face face2) { Vector3 normalFace1 = face1.GetNormal(); Vector3 normalFace2 = face2.GetNormal(); //direction: cross product of the faces normals Direction = Vector3.Cross(normalFace1, normalFace2); //if direction lenght is not zero (the planes aren't parallel )... if (!(Direction.Length < EqualityTolerance)) { //getting a line point, zero is set to a coordinate whose direction //component isn't zero (line intersecting its origin plan) startPoint = new Vector3(); double d1 = -(normalFace1.x * face1.v1.Position.x + normalFace1.y * face1.v1.Position.y + normalFace1.z * face1.v1.Position.z); double d2 = -(normalFace2.x * face2.v1.Position.x + normalFace2.y * face2.v1.Position.y + normalFace2.z * face2.v1.Position.z); if (Math.Abs(Direction.x) > EqualityTolerance) { startPoint.x = 0; startPoint.y = (d2 * normalFace1.z - d1 * normalFace2.z) / Direction.x; startPoint.z = (d1 * normalFace2.y - d2 * normalFace1.y) / Direction.x; } else if (Math.Abs(Direction.y) > EqualityTolerance) { startPoint.x = (d1 * normalFace2.z - d2 * normalFace1.z) / Direction.y; startPoint.y = 0; startPoint.z = (d2 * normalFace1.x - d1 * normalFace2.x) / Direction.y; } else { startPoint.x = (d2 * normalFace1.y - d1 * normalFace2.y) / Direction.z; startPoint.y = (d1 * normalFace2.x - d2 * normalFace1.x) / Direction.z; startPoint.z = 0; } } Direction.Normalize(); }
/// <summary> /// Constructor for a line.The line created is the intersection between two planes /// </summary> /// <param name="face1">face representing one of the planes</param> /// <param name="face2">face representing one of the planes</param> public Line(Face face1, Face face2) { Vector3d normalFace1 = face1.GetNormal(); Vector3d normalFace2 = face2.GetNormal(); //direction: Cross product of the faces normals Direction = Vector3d.Cross(normalFace1, normalFace2); //if direction lenght is not zero (the planes aren't parallel )... if (!(Direction.Length < EqualityTolerance)) { //getting a line point, zero is set to a coordinate whose direction //component isn't zero (line intersecting its origin plan) StartPoint = new Vector3d(); double d1 = -(normalFace1.X * face1.V1._Position.X + normalFace1.Y * face1.V1._Position.Y + normalFace1.Z * face1.V1._Position.Z); double d2 = -(normalFace2.X * face2.V1._Position.X + normalFace2.Y * face2.V1._Position.Y + normalFace2.Z * face2.V1._Position.Z); if (Math.Abs(Direction.X) > EqualityTolerance) { StartPoint.X = 0; StartPoint.Y = (d2 * normalFace1.Z - d1 * normalFace2.Z) / Direction.X; StartPoint.Z = (d1 * normalFace2.Y - d2 * normalFace1.Y) / Direction.X; } else if (Math.Abs(Direction.Y) > EqualityTolerance) { StartPoint.X = (d1 * normalFace2.Z - d2 * normalFace1.Z) / Direction.Y; StartPoint.Y = 0; StartPoint.Z = (d2 * normalFace1.X - d1 * normalFace2.X) / Direction.Y; } else { StartPoint.X = (d2 * normalFace1.Y - d1 * normalFace2.Y) / Direction.Z; StartPoint.Y = (d1 * normalFace2.X - d2 * normalFace1.X) / Direction.Z; StartPoint.Z = 0; } } Direction.Normalize(); }
/// <summary> /// Classifies the face based on the ray trace technique /// </summary> /// <param name="obj">object3d used to compute the face status</param> public void RayTraceClassify(Object3D obj) { //creating a ray starting at the face baricenter going to the normal direction Line ray = new Line(GetNormal(), center); bool success; double distance; Vector3 intersectionPoint; Face closestFace = null; double closestDistance; do { success = true; closestDistance = Double.MaxValue; //for each face from the other solid... for (int faceIndex = 0; faceIndex < obj.GetNumFaces(); faceIndex++) { Face face = obj.GetFace(faceIndex); intersectionPoint = ray.ComputePlaneIntersection(face.GetPlane()); //if ray intersects the plane... if (intersectionPoint.x != double.PositiveInfinity) { double dotProduct = Vector3.Dot(face.GetNormal(), ray.Direction); distance = ray.ComputePointToPointDistance(intersectionPoint); //if ray lies in plane... if (Math.Abs(distance) < EqualityTolerance && Math.Abs(dotProduct) < EqualityTolerance) { //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) < EqualityTolerance && Math.Abs(dotProduct) > EqualityTolerance) { //if ray intersects the face... if (face.ContainsPoint(intersectionPoint)) { //faces coincide closestFace = face; closestDistance = 0; break; } } //if ray intersects plane... else if (Math.Abs(dotProduct) > EqualityTolerance && distance > EqualityTolerance) { if (distance < closestDistance) { //if ray intersects the face; if (face.ContainsPoint(intersectionPoint)) { //this face is the closest face until now closestDistance = distance; closestFace = face; } } } } } } while (success == false); if (closestFace == null) { //none face found: outside face status = Status.OUTSIDE; } else //face found: test dot product { double dotProduct = Vector3.Dot(closestFace.GetNormal(), ray.Direction); //distance = 0: coplanar faces if (Math.Abs(closestDistance) < EqualityTolerance) { if (dotProduct > EqualityTolerance) { status = Status.SAME; } else if (dotProduct < -EqualityTolerance) { status = Status.OPPOSITE; } } else if (dotProduct > EqualityTolerance) { //dot product > 0 (same direction): inside face status = Status.INSIDE; } else if (dotProduct < -EqualityTolerance) { //dot product < 0 (opposite direction): outside face status = Status.OUTSIDE; } } }