Classes | |
struct | CoordSystem3x3 |
Description of a 3-D rectilinear coordinate system in some other reference coordinate system. More... | |
struct | Line3 |
struct | Plane3 |
Oriented plane. More... | |
struct | Ray3 |
struct | Box3 |
Axis aligned box. More... | |
struct | Sphere3 |
struct | Matrix3x3 |
A 3x3 matrix. More... | |
struct | Quaternion |
struct | Rotation3 |
Description of a rotatation in 3-D space around an arbitrary origin based axis or a 1-D sub space if you like. More... | |
struct | BasicVector |
struct | BasicVector< T, 2 > |
struct | BasicVector< T, 3 > |
Typedefs | |
typedef BasicVector< double, 2 > | Vector2 |
typedef BasicVector< double, 3 > | Vector3 |
typedef BasicVector< double, 4 > | Vector4 |
Functions | |
std::ostream & | operator<< (std::ostream &out, const CoordSystem3x3 &s) |
template<typename T> | |
T | clamp (T v, T l, T h) |
Clamp a value to a certain range. | |
template<typename T> | |
T | modulo (T x, T m) |
Calculate y = x mod m such that x = y (mod m). | |
template<typename T> | |
T | modulo (T x, T m, long &n) |
Like modulo(T, T) except that this function also tells you the index of the module in which the argument resides. | |
template<typename T> | |
T | sq (T v) |
Square. | |
template<typename T> | |
T | inv (T v) |
The reciprocal or multiplicative inverse. | |
template<typename T> | |
T | length (T x, T y) |
Length of 2-D vector. | |
template<typename T> | |
T | angle (T x, T y) |
Angle of 2-D vector in range [0;2pi). | |
template<typename T> | |
T | linInterp (double x, double x1, double x2, T y1, T y2) |
Linear interpolation (and extrapolation). | |
template<typename T> | |
void | sort3 (T x0, T x1, T x2, int &i0, int &i1, int &i2) |
template<> | |
short | modulo (short x, short m) |
template<> | |
int | modulo (int x, int m) |
template<> | |
long | modulo (long x, long m) |
template<> | |
float | modulo (float x, float m) |
template<> | |
double | modulo (double x, double m) |
template<> | |
long double | modulo (long double x, long double m) |
template<> | |
short | modulo (short x, short m, long &n) |
template<> | |
int | modulo (int x, int m, long &n) |
template<> | |
long | modulo (long x, long m, long &n) |
template<> | |
float | modulo (float x, float m, long &n) |
template<> | |
double | modulo (double x, double m, long &n) |
template<> | |
long double | modulo (long double x, long double m, long &n) |
bool | intersect (const Ray3 &ray, const Plane3 &plane, bool frontToBackOnly, double *dist) |
int | intersect (const Ray3 &, const Box3 &, double &dist) |
Test for collision between ray and axis aligned box and determine the distance along the ray from the ray origin to the box surface. | |
bool | intersect (const Ray3 &, const Sphere3 &, double &dist) |
Test for collision between ray and sphere and determine the distance along the ray from the ray origin to the sphere surface. | |
int | intersectCylinder (const Ray3 &, double height, double radius, double &dist, bool side=true, bool top=true, bool bottom=true, bool enterOnly=true) |
Test for collision between ray and cylinder and determine the distance along the ray from the ray origin to the surface of the cylinder. | |
int | intersectCone (const Ray3 &, double height, double bottomRadius, double &dist, bool side=true, bool bottom=true, bool enterOnly=true) |
Test for collision between ray and cone and determine the distance along the ray from the ray origin to the surface of the cone. | |
bool | intersectTorus (const Ray3 &ray, double majorRadius, double minorRadius, double &dist, bool surfaceOrigin, bool extToIntOnly) |
Test for collision between ray and torus and determine the distance along the ray from the ray origin to the torus surface. | |
Vector3 | intersect (const Plane3 &p1, const Plane3 &p2, const Plane3 &p3) |
bool | intersect (const Ray3 &, const Plane3 &, bool frontToBackOnly, double &dist) |
Test for collision bewteen ray and plane and determine the distance along the ray from the ray origin to the intersection point. | |
std::ostream & | operator<< (std::ostream &out, const Matrix3x3 &m) |
Matrix3x3 | transpose (const Matrix3x3 &m) |
Matrix3x3 | operator * (double f, const Matrix3x3 &m) |
Matrix3x3 | operator/ (double f, const Matrix3x3 &m) |
Vector3 & | operator *= (Vector3 &v, const Matrix3x3 &m) |
v = (v^T * m)^T | |
Vector3 | operator * (const Vector3 &v, const Matrix3x3 &m) |
(v^T * m)^T | |
int | quarticSolve (double a, double b, double c, double d, double rts[4], double rterr[4]) |
Solve the general 4th order equation:. | |
std::ostream & | operator<< (std::ostream &out, const Quaternion &q) |
Quaternion | operator * (double f, const Quaternion &q) |
Quaternion | operator/ (double f, const Quaternion &q) |
Quaternion | normalize (const Quaternion &q) |
Quaternion | conjugate (const Quaternion &q) |
Quaternion | inverse (const Quaternion &q) |
template<typename T, int N> | |
BasicVector< T, N > | operator * (T f, const BasicVector< T, N > &v) |
template<typename T, int N> | |
BasicVector< T, N > | normalize (const BasicVector< T, N > &v) |
template<typename T, int N> | |
T | squareDist (BasicVector< T, N > v, const BasicVector< T, N > &w) |
template<typename T, int N> | |
T | dist (BasicVector< T, N > v, const BasicVector< T, N > &w) |
template<typename T, int N> | |
T | dot (const BasicVector< T, N > &v, const BasicVector< T, N > &w) |
Dot product. | |
template<typename T, int N> | |
std::ostream & | operator<< (std::ostream &o, const BasicVector< T, N > &v) |
template<typename T> | |
BasicVector< T, 2 > | operator * (T f, const BasicVector< T, 2 > &v) |
template<typename T> | |
BasicVector< T, 2 > | normalize (const BasicVector< T, 2 > &v) |
template<typename T> | |
T | squareDist (BasicVector< T, 2 > v, const BasicVector< T, 2 > &w) |
template<typename T> | |
T | dist (BasicVector< T, 2 > v, const BasicVector< T, 2 > &w) |
template<typename T> | |
T | dot (const BasicVector< T, 2 > &v, const BasicVector< T, 2 > &w) |
Dot product. | |
template<typename T> | |
std::ostream & | operator<< (std::ostream &o, const BasicVector< T, 2 > &v) |
template<typename T> | |
BasicVector< T, 3 > | operator * (T f, const BasicVector< T, 3 > &v) |
template<typename T> | |
BasicVector< T, 3 > | normalize (const BasicVector< T, 3 > &v) |
template<typename T> | |
T | squareDist (BasicVector< T, 3 > v, const BasicVector< T, 3 > &w) |
template<typename T> | |
T | dist (BasicVector< T, 3 > v, const BasicVector< T, 3 > &w) |
template<typename T> | |
T | dot (const BasicVector< T, 3 > &v, const BasicVector< T, 3 > &w) |
Dot product. | |
template<typename T> | |
std::ostream & | operator<< (std::ostream &o, const BasicVector< T, 3 > &v) |
|
Angle of 2-D vector in range [0;2pi).
length(1, 0) = 0 length(1, 1) = pi/4 length(0, 1) = pi/2 length(-1, 0) = pi length(-1, -1) = 3/2 pi
A zero vector gives an angle of zero. Definition at line 126 of file functions.H. Referenced by Archon::Math::BasicVector< T, 2 >::angle(), Archon::Math::CoordSystem3x3::minimalTurn(), Archon::X3D::Viewer::renderFrame(), and Archon::rotate_cylinder(). |
|
Clamp a value to a certain range.
Definition at line 43 of file functions.H. |
|
Test for collision bewteen ray and plane and determine the distance along the ray from the ray origin to the intersection point. The distance is mesured in units of the ray direction vector length and is always strictly positive. When there is no collision reported the 'dist' parameter is left unchanged.
|
|
Test for collision between ray and sphere and determine the distance along the ray from the ray origin to the sphere surface. The distance is mesured in units of the ray direction vector length and is always strictly positive. A requirement for collision is that the ray originates from outside the sphere. The distance is always mesured to the point where the ray enters into the interior of the sphere. When there is no collision reported the 'dist' parameter is left unchanged.
Definition at line 121 of file geometry.C. References Archon::Math::Sphere3::center, Archon::Math::Ray3::direction, dot(), Archon::Math::Ray3::origin, Archon::Math::Sphere3::radius, and Archon::Math::BasicVector< T, N >::squareSum(). |
|
Test for collision between ray and axis aligned box and determine the distance along the ray from the ray origin to the box surface. The distance is mesured in units of the ray direction vector length and is always strictly positive. A requirement for collision is that the ray originates from outside the box. The distance is always mesured to the point where the ray enters into the interior of the box. When there is no collision reported the 'dist' parameter is left unchanged. Returns an indication of where the intersection was: 0 -> nowhere 1 -> left face (-boxSize.x) 2 -> right face (boxSize.x) 3 -> bottom face (-boxSize.y) 4 -> top face (boxSize.y) 5 -> back face (-boxSize.z) 6 -> front face (boxSize.z) Definition at line 47 of file geometry.C. References Archon::Math::Ray3::direction, Archon::Math::Box3::lowerCorner, Archon::Math::Ray3::origin, std::swap(), and Archon::Math::Box3::upperCorner. |
|
Test for collision between ray and cone and determine the distance along the ray from the ray origin to the surface of the cone. The distance is mesured in units of the ray direction vector length and is always positive. The cone is origin centred with the axis of revolution coincident with the Y-axis. The apex of the code always points upward (in the direction of the Y-axis) and the code is positioned such that the origin is at the midpoint between the apex and the center of the base (bottom cap). By default only collision points where the ray enters into the interior of the cone are considered, but if false is passed as the enterOnly parameter then also points where the ray leaves the interior are considered. When there is no collision reported the 'dist' parameter is left unchanged. Solid/non-solid cones: To support X3D cones it is possible to disable the various parts of the cone (side and bottom). Naturally, removing parts of a cone is equivalent to considerering it as a non-solid object. One should always pass false as the 'enterOnly' parameter if any part of the cone is disabled.
Theory: Equation of infinite double cone whos axis of revolution is coincident with the Y-axis and whos apex is at y = h/2 and whos radius in the plane y = -h/2 is r: x² + z² = (½ - y/h)² r² (1) Equation of ray: v = P + t D where P is the origin and D is the direction of the ray. or x = px + t dx y = py + t dy z = pz + t dz To ease the computation we use the following 3 substitutions: y' = (½ - y/h) r py' = (½ - py/h) r dy' = - dy/h r This gives us the equation of the standard infinite double cone: x² + z² = y'² (1) and because py' + t dy' = (½ - py/h) r - t dy/h r = (½ - (py + t dy)/h) r = (½ - y/h) r = y' we have: x = px + t dx y' = py' + t dy' (2) z = pz + t dz Inserting (2) into (1) we get: (px + t dx)² + (pz + t dz)² = (py' + t dy')² <=> px² + t²dx² + 2 px t dx + pz² + t²dz² + 2 pz t dz = py'² + t²dy'² + 2 py' t dy' <=> (dx² + dz² - dy'²) t² + 2 (px dx + pz dz - py' dy') t + (px² + pz² - py'²) = 0 (3) Alas, we need to solve a quadratic equation in t: a = dx² + dz² - dy'² b = 2 (px dx + pz dz - py' dy') c = px² + pz² - py'² d = b² - 4 a c t = (-b ± sqrt(d)) / 2a; Which is equivalent to this computationally more efficient form: a' = 2 (dx² + dz² - dy'²) b' = -2 (px dx + pz dz - py' dy') c = px² + pz² - py'² d = b'² - 2 a' c t = (b' ± sqrt(d)) / a' if d >= 0 Note that if a' = 0 then equation (3) is in fact not a quadratic equation. If b' != 0 We get: 2 (px dx + pz dz - py' dy') t + (px² + pz² - py'²) = 0 -(px² + pz² - py'²) c t = --------------------------- = --- 2 (px dx + pz dz - py' dy') b' If both a' = 0 and b' = 0 then if c = 0 we have an infinity of solutions and if c != 0 we have no solutions. The discriminating plane: I will now define the discriminating plane for the intersection between a line and an infinite double cone to be the plane that contains both the line and the apex of the double cone. In the special case where the apex of the cone is coincident with the line, the discriminating plane is not defined. The important feature of the discriminating plane is that it help us understand when the line intersects the cone and it gives us a geometrical interpretation of the discriminant d as defined above. Say that the angle between the central axis of the cone and its sides is A. In this case, if the discriminating plane is defined and if the smallest angle between the discriminating plane and the central axis of the cone is strictly less than A, then the line intersects the cone. If the discriminating plane is defined and the smallest angle between the discriminating plane and the central axis of the cone is strictly greater than A, then the line does not intersect the cone. In the special case where the discriminating plane is defined and the smallest angle between the discriminating plane and the central axis of the cone is exactly equal to A, the line generally intersects the cone in a tagential fashion since in this case the discriminating plane is a tangential plane to the cone. The only exception is when the line is parallel to the line arising as the tangential intersection between the plane and the cone. In every case where the discriminating plane is not defined the line intersects with the apex of the cone by definition. If we say that B is the smallest angle between the line and the central axis of the cone, we have the following relationship: A <= B Now, as announced earlier, there is a simple correspondance between the discriminating plane and the descriminant d of the quadratic equation above. In the case of this method, the apex of the cone is at the origin of the coordinate system, the angle between its central axis and its sides is 45°, and its central axis is coincident with the Y-axis. This means that the normal N of the descriminating plane can be expessed as follows: N = P × D By expanding the expression of the discriminant and then reducing we get: d/4 = (py*dz - pz*dy)² + (px*dy - py*dx)² - (pz*dx - px*dz)² From this we get the following: d/4 = |Nxz|² - |Ny|² where Ny is the projection of N onto the Y-axis and Nxz is the projection of N onto the X-Z-plane. Ergo, we have the following relationship between the discriminating plane and the discriminant d: d > 0 The smallest angle between the discriminating plane and the central axis of the cone is strictly less than A. d < 0 The smallest angle between the discriminating plane and the central axis of the cone is strictly greater than A. d = 0 The smallest angle between the discriminating plane and the central axis of the cone is exactly equal to A. a' = 0 iff the smallest angle between the ray and the upwards direction is exactly 45 degrees. Alternatively we could say that a' = 0 iff a plane, that contains both the ray and the apex of the cone, intersects the cone surface along a straight line that is paralell with the ray. a > 0 iff the smallest angle between the ray and the upwards direction is greater than 45 degrees. then either the ray passes by the infinite double cone without intersecting it, or it intersects the upper nappe twice or it intersects the lower nappe twice. If a < 0 then the ray has exactly one intersection with the upper nappe of the infinite double cone. It also has exactly one intersection with the lower nappe. b' = 0 iff the ray is tangential to the hyperboloid that contains the ray origin and is asymptotically equal to the cone surface. c = 0 restricts the ray to originate from the surface of the standard infinite double cone with apex at the origin of the coordinate system. If c > 0 then the ray originates outside the infinite double cone. If c < 0 then the ray originates inside the infinite double cone. a < 0 => d > 0 Whenever a' > 0 and d > 0 the ray intersects the infinite double cone twice and either both intersections are with the upper nappe or they are both with the lower one. In this case it holds that: (b' - sqrt(d)) / a' <= (b' + sqrt(d)) / a' Whenever a' < 0 and d > 0 the ray intersects the infinite double cone twice. Once with the upper nappe and once with the lower one. In this case it holds that: (b' - sqrt(d)) / a' >= (b' + sqrt(d)) / a' Note that 'on geometry surface' is considdered to be 'inside geometry interiour'. Definition at line 266 of file geometry.C. References Archon::Math::Ray3::direction, and Archon::Math::Ray3::origin. Referenced by Archon::X3D::Cone::intersect(). |
|
Test for collision between ray and cylinder and determine the distance along the ray from the ray origin to the surface of the cylinder. The distance is mesured in units of the ray direction vector length and is always strictly positive. The cylinder is origin centred with the axis of revolution coincident with the Y-axis. By default only collision points where the ray enters into the interior of the cylinder are considered, but if false is passed as the enterOnly parameter then also points where the ray leaves the interior are considered. When there is no collision reported the 'dist' parameter is left unchanged. Solid/non-solid cylinders: To support X3D cylinders it is possible to disable the various parts of the cylinder (side, top and bottom). Naturally, removing parts of a cylinder is equivalent to considerering it as a non-solid object. One should always pass false as the 'enterOnly' parameter if any part of the cylinder is disabled.
Theory: Equation of infinite cylinder whos axis of revolution is coincident with the Y-axis: x² + z² = r² (1) Equation of ray: v = p + t d or x = px + t dx y = py + t dy (2) z = pz + t dz Inserting (2) into (1) we get: (px + t dx)² + (pz + t dz)² = r² <=> px² + t²dx² + 2 px t dx + pz² + t²dz² + 2 pz t dz = r² <=> (dx² + dz²) t² + 2 (px dx + pz dz) t + (px² + pz² - r²) = 0 (3) If p' is the projection of p onto the X-Z-plane and d' is the projection of d then (3) corresponds to |d'|² t² + 2 p'·d' t + |p'|²-r² = 0 Anyway we need to solve a quadratic equation in t: a = dx² + dz² b = 2 (px dx + pz dz) c = px² + pz² - r² d = b² - 4 a c t = (-b ± sqrt(d)) / 2a; Which is equivalent to this computationally more efficient form: a' = 2 (dx² + dz²) b' = -2 (px dx + pz dz) c = px² + pz² - r² d = b'² - 2 a' c t = (b' ± sqrt(d)) / a' if d >= 0 Where it always holds that: (b' - sqrt(d)) / a' <= (b' + sqrt(d)) / a' if d >= 0 Note that a' = 0 implies b' = 0. This means that the ray is strictly vertical. In this case (3) degenerates to: px² + pz² = r² Which means that if the ray originates on the surface of the cylinder then there is an infinity of solutions for t. Otherwise there are no sollutions. Note that 'on geometry surface' is considdered to be 'inside geometry interiour'. Definition at line 136 of file geometry.C. References Archon::Math::Ray3::direction, and Archon::Math::Ray3::origin. Referenced by Archon::X3D::Cylinder::intersect(), and Archon::X3D::Viewer::renderFrame(). |
|
Test for collision between ray and torus and determine the distance along the ray from the ray origin to the torus surface. Equation of torus where torus is constrained to be origin centered and lie in the x-z plane: (sqrt(x² + z²)-R)² + y² = r² x² + z² + R² - 2*R*sqrt(x² + z²) + y² = r² x² + y² + z² + R² - r² = 2*R*sqrt(x² + z²) (x² + y² + z² + R² - r²)² = 4 * R² * (x² + z²) [1] Equation of ray: x = p[0] + t * d[0] y = p[1] + t * d[1] z = p[2] + t * d[2] x² = p[0]² + t² * d[0]² + 2*t*p[0]*d[0] y² = p[1]² + t² * d[1]² + 2*t*p[1]*d[1] z² = p[2]² + t² * d[2]² + 2*t*p[2]*d[2] x² + y² + z² = p[0]² + p[1]² + p[2]² + t² * (d[0]² + d[1]² + d[2]²) + 2*t*(p[0]*d[0] + p[1]*d[1] + p[2]*d[2]) = |p|² + t² * |d|² + 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² + y² + z² + R² - r²)² = (|p|² + t² * |d|² + 2 * t * dot(p, d) + R² - r²)² = (|d|² * t² + 2 * dot(p, d) * t + |p|² + R² - r²)² = |d|^4 * t^4 + 4 * dot(p, d)² * t² + (|p|² + R² - r²)² + 4 * |d|² * dot(p, d) * t³ + 2 * |d|² * (|p|² + R² - r²) * t² + 4 * dot(p, d) * (|p|² + R² - r²) * t [2] Right side of [1]: 4 * R² * (x² + z²) = 4 * R² * (x² + y² + z² - y²) = 4 * R² * (|p|² + t² * |d|² + 2 * t * dot(p, d) - p[1]² - t² * d[1]² - 2*t*p[1]*d[1]) = 4 * R² * ((|d|² - d[1]²) * t² + 2 * (dot(p, d) - p[1]*d[1]) * t + |p|² - p[1]²) = 4 * R² * (|d|² - d[1]²) * t² + 8 * R² * (dot(p, d) - p[1]*d[1]) * t + 4 * R² * (|p|² - p[1]²) [3] Subtracting [3] from [2] we get: |d|^4 * t^4 + 4 * |d|² * dot(p, d) * t³ + 2 * (2 * dot(p, d)² + |d|² * (|p|² - r²) - R² * (|d|² - 2*d[1]²)) * t² + 4 * (dot(p, d) * (|p|² - r²) - R² * (dot(p, d) - 2*p[1]*d[1])) * t + (|p|² + R² - r²)² - 4 * R² * (|p|² - p[1]²) [4] The following substitutions makes it all simpler: d = e*|d| t = u/|d| Then dot(p, d) = |d|*dot(p, e), d[2] = |d|*e[2] and [4] becomes: u^4 + 4 * dot(p, e) * u³ + 2 * (2 * dot(p, e)² + |p|² - r² - R² * (1 - 2*e[1]²)) * u² + 4 * (dot(p, e) * (|p|² - r²) - R² * (dot(p, e) - 2*p[1]*e[1])) * u + (|p|² + R² - r²)² - 4 * R² * (|p|² - p[1]²) 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 Definition at line 531 of file geometry.C. References Archon::Math::Ray3::direction, Archon::Math::BasicVector< T, N >::length(), Archon::Math::Ray3::origin, quarticSolve(), and std::swap(). Referenced by Archon::X3D::Torus::intersect(). |
|
Linear interpolation (and extrapolation). Choose and return a value y such that the point (x,y) lies on the line spanned by (x1,y1) and (x2,y2). Definition at line 140 of file functions.H. Referenced by Archon::Utilities::Color::interp(), Archon::X3D::normalInterp(), and Archon::X3D::rotInterp(). |
|
Like modulo(T, T) except that this function also tells you the index of the module in which the argument resides. That is, n is the integer value such that x = n * m + modulo(x, m).
|
|
Calculate y = x mod m such that x = y (mod m). That is, find y in the half open interval [0,m) such that the difference between x and y is an integer multiple of m. Note: For T=double and non-negative values of x this function is identical to the standard library function 'fmod', whereas for negative values they differ by m. that is modulo(x) = fmod(x) + m for x<0. Note also that this function is periodic but neither "even" nor "odd" where as the standard library function 'fmod' is an "odd" function and not periodic. A typical type of argument would be angels which are cyclic by nature and are often needed in the interval [0,360). Another example is texture coordinates for tiled texture mapping.
Referenced by modulo(). |
|
Solve the general 4th order equation:. called by calls qudrtc, ferrari, neumark. 21 Jan 1989 Don Herbison-Evans Note: The number of roots will always be a muliple of 2. Definition at line 537 of file quartic_solve.C. Referenced by Archon::Raytracer::Torus::intersect(), and intersectTorus(). |