#include <raytracer/object.H>
Inheritance diagram for Archon::Raytracer::Torus:
Public Member Functions | |
Torus (const Surface *surface, const CoordSystem3x3 &s, double majorRadius, double minorRadius) | |
~Torus () | |
bool | intersect (const Line3 &ray, const Object *originObject, const Object::Part *originPart, double &dist, const Object::Part **=0) const |
Equation of torus constrained to be origin centered and lie in the x-z plane:. | |
void | interiorIntersect (const Line3 &ray, const Object::Part *originPart, double &dist, const Object::Part *&) const |
void | map (const Vector3 &point, Vector3 &normal) const |
void | map (const Vector3 &point, Vector3 &normal, Vector2 &texturePoint) const |
Definition at line 205 of file object.H.
|
Equation of torus constrained to be origin centered and lie in the x-z plane:. (sqrt(x**2 + z**2)-R)**2 + y**2 = r**2 x**2 + z**2 + R**2 - 2*R*sqrt(x**2 + z**2) + y**2 = r**2 x**2 + y**2 + z**2 + R**2 - r**2 = 2*R*sqrt(x**2 + z**2) (x**2 + y**2 + z**2 + R**2 - r**2)**2 = 4 * R**2 * (x**2 + z**2) [1] Equation of ray: x = p.x + t * d.x y = p.y + t * d.y z = p.z + t * d.z x**2 = p.x**2 + t**2 * d.x**2 + 2*t*p.x*d.x y**2 = p.y**2 + t**2 * d.y**2 + 2*t*p.y*d.y z**2 = p.z**2 + t**2 * d.z**2 + 2*t*p.z*d.z x**2 + y**2 + z**2 = p.x**2 + p.y**2 + p.z**2 + t**2 * (d.x**2 + d.y**2 + d.z**2) + 2*t*(p.x*d.x + p.y*d.y + p.z*d.z) = |p|**2 + t**2 * |d|**2 + 2 * t * dot(p, d) Our mission is to obtain the distance 't' along the ray from its origin 'p' to the first intersection point with the torus measured in units of |d|. We cannot assume that the direction vector 'd' has unit length because the local coordinate system that we work in may be scaled and the length we need is the length as observed in the global coordinate system. Left side of [1]: (x**2 + y**2 + z**2 + R**2 - r**2)**2 = (|p|**2 + t**2 * |d|**2 + 2 * t * dot(p, d) + R**2 - r**2)**2 = (|d|**2 * t**2 + 2 * dot(p, d) * t + |p|**2 + R**2 - r**2)**2 = |d|**4 * t**4 + 4 * dot(p, d)**2 * t**2 + (|p|**2 + R**2 - r**2)**2 + 4 * |d|**2 * dot(p, d) * t**3 + 2 * |d|**2 * (|p|**2 + R**2 - r**2) * t**2 + 4 * dot(p, d) * (|p|**2 + R**2 - r**2) * t [2] Right side of [1]: 4 * R**2 * (x**2 + z**2) = 4 * R**2 * (x**2 + y**2 + z**2 - y**2) = 4 * R**2 * (|p|**2 + t**2 * |d|**2 + 2 * t * dot(p, d) - p.y**2 - t**2 * d.y**2 - 2*t*p.y*d.y) = 4 * R**2 * ((|d|**2 - d.y**2) * t**2 + 2 * (dot(p, d) - p.y*d.y) * t + |p|**2 - p.y**2) = 4 * R**2 * (|d|**2 - d.y**2) * t**2 + 8 * R**2 * (dot(p, d) - p.y*d.y) * t + 4 * R**2 * (|p|**2 - p.y**2) [3] Subtracting [3] from [2] we get: |d|**4 * t**4 + 4 * |d|**2 * dot(p, d) * t**3 + 2 * (2 * dot(p, d)**2 + |d|**2 * (|p|**2 - r**2) - R**2 * (|d|**2 - 2*d.y**2)) * t**2 + 4 * (dot(p, d) * (|p|**2 - r**2) - R**2 * (dot(p, d) - 2*p.y*d.y)) * t + (|p|**2 + R**2 - r**2)**2 - 4 * R**2 * (|p|**2 - p.y**2) [4] The following substitutions makes it all simpler: d = e*|d| t = u/|d| Then dot(p, d) = |d|*dot(p, e), d.z = |d|*e.z and [4] becomes: u**4 + 4 * dot(p, e) * u**3 + 2 * (2 * dot(p, e)**2 + |p|**2 - r**2 - R**2 * (1 - 2*e.y**2)) * u**2 + 4 * (dot(p, e) * (|p|**2 - r**2) - R**2 * (dot(p, e) - 2*p.y*e.y)) * u + (|p|**2 + R**2 - r**2)**2 - 4 * R**2 * (|p|**2 - p.y**2) We now have a normalized 4th order polynomial in u whos roots may be found by a standard quartic solver. Primary reference: http://www.cl.cam.ac.uk/Teaching/1999/AGraphHCI/SMAG/node2.html Implements Archon::Raytracer::Object. Definition at line 416 of file object.C. References Archon::Math::CoordSystem3x3::basis, Archon::Math::Line3::direction, Archon::Math::BasicVector< T, N >::length(), Archon::Math::Matrix3x3::map(), Archon::Math::CoordSystem3x3::map(), Archon::Math::Line3::point, and Archon::Math::quarticSolve(). Referenced by interiorIntersect(). |