Archon::Math Namespace Reference

Holds the Archon math library. More...


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)
Vector3operator *= (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)


Detailed Description

Holds the Archon math library.

Function Documentation

template<typename T>
T Archon::Math::angle T  x,
T  y
[inline]
 

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().

template<typename T>
T Archon::Math::clamp T  v,
T  l,
T  h
[inline]
 

Clamp a value to a certain range.

Parameters:
v The value to clamp.
l The lowest allowable value.
h The highest allowable value.
Returns:
The clamped value.

Definition at line 43 of file functions.H.

bool Archon::Math::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.

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.

Parameters:
frontToBackOnly If true then a requirement for intersection is that the ray originates from a location in front of the plane.
Returns:
True iff the ray and the plane intersect.

bool Archon::Math::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.

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.

Returns:
True iff the ray and the sphere intersect.
Todo:
One should be able to leave out the distance argument.

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().

int Archon::Math::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.

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.

int Archon::Math::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.

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.

Parameters:
height Distance from center of bottom cap to apex.
bottomRadius Radius at the base (bottom) of the cone.
dist Set to the distance described above.
side If false then intersections with the side are ignored. (See the note on Solid/non-solid cones)
bottom If false then intersections with the bottom cap are ignored. (See the note on Solid/non-solid cones)
enterOnly By default only collisions where the ray enters into the interior of the cone are considered, but if false is passed here then also points where the ray leaves the interior are considered. The default, of course, only makes sense if the cone is solid, and no parts of the cone are disabled.
Returns:
An indication of where the intersection was: 0 -> nowhere 1 -> side (x² + z² = (½ - y/height)² bottomRadius², -height/2 <= y <= height/2) 2 -> bottom cap (y = -height/2, x² + z² < bottomRadius²)
Note: It is not meaningfull to request 'enterOnly' and also specify that one or more of the cone parts should be disabled. That is, enterOnly=true, is equivalent to saying that the cone is solid, and thus cannot lack bottom or sides - of course.

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().

int Archon::Math::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.

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.

Parameters:
height Distance from bottom cap to top cap. Alternatively a negative value indicates a cylinder of infinite length.
radius Radius of cylinder.
dist Set to the distance described above.
side If false then intersections with the side are ignored. (See the note on Solid/non-solid cylinders)
top If false then intersections with the top cap are ignored. (See the note on Solid/non-solid cylinders)
bottom If false then intersections with the bottom cap are ignored. (See the note on Solid/non-solid cylinders)
enterOnly By default only collisions where the ray enters into the interior of the cylinder are considered, but if false is passed here then also points where the ray leaves the interior are considered. The default, of course, only makes sense if the cylinder is solid, and no parts of the cylinder are disabled.
Returns:
An indication of where the intersection was: 0 -> nowhere 1 -> side (x² + z² = radius², -height/2 <= y <= height/2) 2 -> bottom cap (y = -height/2, x² + z² < radius²) 3 -> top cap (y = height/2, x² + z² < radius²)
Note: It is not meaningfull to request 'enterOnly' and also specify that one or more of the cylinder parts should be disabled. That is, enterOnly=true, is equivalent to saying that the cylinder is solid, and thus cannot lack top, bottom or sides - of course.

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().

bool Archon::Math::intersectTorus const Ray3 &  ray,
double  majorTorusRadius,
double  minorTorusRadius,
double &  dist,
bool  surfaceOrigin = false,
bool  extToIntOnly = true
 

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().

template<typename T>
T Archon::Math::linInterp double  x,
double  x1,
double  x2,
T  y1,
T  y2
[inline]
 

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().

template<typename T>
T Archon::Math::modulo T  x,
T  m,
long &  n
[inline]
 

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).

Parameters:
n The index of the module in which the argument resides. '0' indicates the principal module [0,m). 1 indicates the next module [m,2m), -1 indicates the previous module [-m;0) and so on.

template<typename T>
T Archon::Math::modulo T  x,
T  m
[inline]
 

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.

Parameters:
m Must be a strictly positive value.

Referenced by modulo().

int Archon::Math::quarticSolve double  a,
double  b,
double  c,
double  d,
double  roots[4],
double  rootErrors[4] = 0
 

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().


Generated on Sun Jul 30 22:56:55 2006 for Archon by  doxygen 1.4.4