/** * Computes the point resulting from the intersection with another line * * @param otherLine the other line to apply the intersection. The lines are supposed * to intersect * @return point resulting from the intersection. If the point coundn't be obtained, return null */ public Point3d computeLineIntersection(Line otherLine) { //x = x1 + a1*t = x2 + b1*s //y = y1 + a2*t = y2 + b2*s //z = z1 + a3*t = z2 + b3*s Point3d linePoint = otherLine.getPoint(); Vector3d lineDirection = otherLine.getDirection(); double t; if (Math.Abs(direction.y * lineDirection.x - direction.x * lineDirection.y) > TOL) { t = (-point.y * lineDirection.x + linePoint.y * lineDirection.x + lineDirection.y * point.x - lineDirection.y * linePoint.x) / (direction.y * lineDirection.x - direction.x * lineDirection.y); } else if (Math.Abs(-direction.x * lineDirection.z + direction.z * lineDirection.x) > TOL) { t = -(-lineDirection.z * point.x + lineDirection.z * linePoint.x + lineDirection.x * point.z - lineDirection.x * linePoint.z) / (-direction.x * lineDirection.z + direction.z * lineDirection.x); } else if (Math.Abs(-direction.z * lineDirection.y + direction.y * lineDirection.z) > TOL) { t = (point.z * lineDirection.y - linePoint.z * lineDirection.y - lineDirection.z * point.y + lineDirection.z * linePoint.y) / (-direction.z * lineDirection.y + direction.y * lineDirection.z); } else { return(null); } double x = point.x + direction.x * t; double y = point.y + direction.y * t; double z = point.z + direction.z * t; return(new Point3d(x, y, z)); }
/** * Computes the point resulting from the intersection with another line * * @param otherLine the other line to apply the intersection. The lines are supposed * to intersect * @return point resulting from the intersection. If the point coundn't be obtained, return null */ public Point3d?computeLineIntersection(Line otherLine) { //x = x1 + a1*t = x2 + b1*s //y = y1 + a2*t = y2 + b2*s //z = z1 + a3*t = z2 + b3*s Point3d linePoint = otherLine.getPoint(); Vector3d lineDirection = otherLine.getDirection(); float t; if (Math.Abs(direction.Y * lineDirection.X - direction.X * lineDirection.Y) > TOL) { t = (-point.Y * lineDirection.X + linePoint.Y * lineDirection.X + lineDirection.Y * point.X - lineDirection.Y * linePoint.X) / (direction.Y * lineDirection.X - direction.X * lineDirection.Y); } else if (Math.Abs(-direction.X * lineDirection.Z + direction.Z * lineDirection.X) > TOL) { t = -(-lineDirection.Z * point.X + lineDirection.Z * linePoint.X + lineDirection.X * point.Z - lineDirection.X * linePoint.Z) / (-direction.X * lineDirection.Z + direction.Z * lineDirection.X); } else if (Math.Abs(-direction.Z * lineDirection.Y + direction.Y * lineDirection.Z) > TOL) { t = (point.Z * lineDirection.Y - linePoint.Z * lineDirection.Y - lineDirection.Z * point.Y + lineDirection.Z * linePoint.Y) / (-direction.Z * lineDirection.Y + direction.Y * lineDirection.Z); } else { return(null); } float x = point.X + direction.X * t; float y = point.Y + direction.Y * t; float z = point.Z + direction.Z * t; return(new Point3d(x, y, z)); }
/** * 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; } } }
/** * 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) / 3d; p0.y = (v1.y + v2.y + v3.y) / 3d; p0.z = (v1.z + v2.z + v3.z) / 3d; 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()); intersectionPoint = ray.computePlaneIntersection(face.getNormal(), face.v1.getPosition()); //if ray intersects the plane... if (intersectionPoint != null) { distance = ray.computePointToPointDistance(intersectionPoint); //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)) { //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)) { //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()); //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 the point resulting from the intersection with another line * * @param otherLine the other line to apply the intersection. The lines are supposed * to intersect * @return point resulting from the intersection. If the point coundn't be obtained, return null */ public Point3d computeLineIntersection(Line otherLine) { //x = x1 + a1*t = x2 + b1*s //y = y1 + a2*t = y2 + b2*s //z = z1 + a3*t = z2 + b3*s Point3d linePoint = otherLine.getPoint(); Vector3d lineDirection = otherLine.getDirection(); double t; if (Math.Abs(direction.y * lineDirection.x - direction.x * lineDirection.y) > TOL) { t = (-point.y * lineDirection.x + linePoint.y * lineDirection.x + lineDirection.y * point.x - lineDirection.y * linePoint.x) / (direction.y * lineDirection.x - direction.x * lineDirection.y); } else if (Math.Abs(-direction.x * lineDirection.z + direction.z * lineDirection.x) > TOL) { t = -(-lineDirection.z * point.x + lineDirection.z * linePoint.x + lineDirection.x * point.z - lineDirection.x * linePoint.z) / (-direction.x * lineDirection.z + direction.z * lineDirection.x); } else if (Math.Abs(-direction.z * lineDirection.y + direction.y * lineDirection.z) > TOL) { t = (point.z * lineDirection.y - linePoint.z * lineDirection.y - lineDirection.z * point.y + lineDirection.z * linePoint.y) / (-direction.z * lineDirection.y + direction.y * lineDirection.z); } else return null; double x = point.x + direction.x * t; double y = point.y + direction.y * t; double z = point.z + direction.z * t; return new Point3d(x, y, z); }