Simbody
3.3
|
The Geo class collects geometric primitives intended to deal with raw, fixed-size geometric shapes occupying minimal memory and providing maximum performance through small inline methods and larger high performance algorithms. More...
#include <Geo.h>
Classes | |
class | AlignedBox_ |
A 3d box aligned with an unspecified frame F and centered at a given point measured from that frame's origin. More... | |
class | BicubicBezierPatch_ |
A primitive useful for computations involving a single bicubic Bezier patch. More... | |
class | BicubicHermitePatch_ |
A primitive useful for computations involving a single bicubic Hermite patch. More... | |
class | Box_ |
A 3d rectangular box aligned with an unspecified frame F and centered at that frame's origin. More... | |
class | Circle_ |
class | CubicBezierCurve_ |
This is a primitive useful for computations involving a single cubic Bezier curve segment. More... | |
class | CubicHermiteCurve_ |
A primitive useful for computations involving a single cubic Hermite curve segment in algebraic or geometric (Hermite) form. More... | |
class | Line_ |
class | LineSeg_ |
A 3d line segment primitive represented by its end points in an unspecified frame, and a collection of line segment-related utility methods. More... | |
class | OrientedBox_ |
TODO: A 3d box oriented and positioned with respect to an unspecified frame F. More... | |
class | Plane_ |
class | Point_ |
A 3d point primitive represented by a Vec3 from the origin of an unspecified frame, and a collection of point-related utility methods. More... | |
class | Sphere_ |
A geometric primitive representing a sphere by its radius and center point, and a collection of sphere-related utility methods. More... | |
class | Triangle_ |
A geometric primitive representing a triangle by its vertices as points in some unspecified frame, and a collection of triangle-related utility methods. More... | |
Public Types | |
typedef Point_< Real > | Point |
typedef Sphere_< Real > | Sphere |
typedef LineSeg_< Real > | LineSeg |
typedef Line_< Real > | Line |
typedef Plane_< Real > | Plane |
typedef Circle_< Real > | Circle |
typedef Box_< Real > | Box |
typedef AlignedBox_< Real > | AlignedBox |
typedef OrientedBox_< Real > | OrientedBox |
typedef Triangle_< Real > | Triangle |
typedef CubicHermiteCurve_< Real > | CubicHermiteCurve |
typedef BicubicHermitePatch_ < Real > | BicubicHermitePatch |
typedef CubicBezierCurve_< Real > | CubicBezierCurve |
typedef BicubicBezierPatch_< Real > | BicubicBezierPatch |
Static Public Member Functions | |
Differential geometry of curve segments | |
These methods calculate geometric quantities from given parametric ones, in an arbitrary parameter u, such that points on the curve segment are given by P(u), with 0<=u<=1. We consider the direction of increasing arc length to be the same as the direction of u. These are utility methods that can be used with any parametric curve. The idea is that you use the curve evaluators to determine the arguments here, using the same u value for each of them. If you don't use the same u value you'll get meaningless results. The primary reference for this material is the book "Lectures on Classical Differential Geometry, 2nd ed." (chapter 1) by Dirk Struik, 1961, republished by Dover in 1988. Notation and equation numbers are from that reference. Two exceptions: (1) we use c for the curvature vector rather than Struik's bold k, so we can use k for the scalar value of curvature, and (2) we define the curve normal n to point away (outward) from the center of curvature, while Struik defined it to point inward. Using our definition, if you have a parametric circle the normal points towards the outside, which is more conventional and analogous to surface normals. Our right-handed curve frame is thus x,y,z=n,t,b rather than Struik's "moving trihedron" frame t,n,b. For us the binormal b=n X t, while with Struik's definition it is t X n. Note that only the normal is reversed from Struik's, the tangent and binormal vectors are the same. | |
template<class RealP , int S> | |
static bool | isCusp (const Vec< 3, RealP, S > &Pu) |
Given the parametric derivative Pu(u)=dP/du, determine whether the point P(u) is at a cusp, that is, a place where the arc length s does not change when parameter u does, so ds/du=0 (within tolerance). More... | |
template<class RealP , int S> | |
static bool | isInflectionPoint (const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu) |
Given the parametric derivatives Pu(u)=dP/du, and Puu(u)=d2P/du2 determine whether point P(u) is at an inflection point on the curve, that is, a flat place where there is no curvature (within tolerance). More... | |
template<class RealP , int S> | |
static UnitVec< RealP, 1 > | calcUnitTangent (const Vec< 3, RealP, S > &Pu) |
Calculate the unit tangent vector t=dP/ds, given Pu=dP/du. More... | |
template<class RealP , int S> | |
static Vec< 3, RealP > | calcCurvatureVector (const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu) |
Return the curvature vector c=dt/ds=d2P/ds2, given Pu=dP/du and Puu=d2P/du2. More... | |
template<class RealP , int S> | |
static UnitVec< RealP, 1 > | calcUnitNormal (const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu) |
In our definition, the unit normal vector n points in the "outward" direction, that is, it points away from the center of curvature (opposite the curvature vector c so n=-c/|c|). More... | |
template<class RealP , int S> | |
static RealP | calcCurveFrame (const Vec< 3, RealP, S > &P, const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu, Transform_< RealP > &X_FP) |
Return the the curvature k (always positive), and a frame whose origin is a point along the curve, x axis is the outward unit normal n, y is the unit tangent t, and z=x X y is the binormal b, which is a normal to the osculating plane. More... | |
template<class RealP , int S> | |
static RealP | calcCurvatureSqr (const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu) |
Return k^2, the square of the scalar curvature k, given Pu=dP/du and Puu=d2P/du2. More... | |
template<class RealP , int S> | |
static RealP | calcTorsion (const Vec< 3, RealP, S > &Pu, const Vec< 3, RealP, S > &Puu, const Vec< 3, RealP, S > &Puuu) |
Return tau, the torsion or "second curvature" given Pu=dP/du, Puu=d2P/du2, Puuu=d3P/du3. More... | |
Lines | |
template<class RealP > | |
static void | findClosestPointsOfTwoLines (const Vec< 3, RealP > &p0, const UnitVec< RealP, 1 > &d0, const Vec< 3, RealP > &p1, const UnitVec< RealP, 1 > &d1, Vec< 3, RealP > &x0, Vec< 3, RealP > &x1, bool &linesAreParallel) |
Find the points of closest approach on two lines L0 and L1, each represented by an origin point and a direction. More... | |
Miscellaneous utilities | |
template<class RealP > | |
static RealP | getDefaultTol () |
Return the default tolerance to use for degeneracy tests and other tests for "too small" or "near enough" that arise in dealing with geometry primitives. More... | |
template<class RealP > | |
static RealP | getDefaultTolSqr () |
Returns the square of the default tolerance. More... | |
template<class RealP > | |
static RealP | getEps () |
Return machine precision for floating point calculations at precision RealP. More... | |
template<class RealP > | |
static RealP | getNaN () |
Return a NaN (not a number) at precision RealP. More... | |
template<class RealP > | |
static RealP | getInfinity () |
Return Infinity at precision RealP. You can negate this for -Infinity. More... | |
template<class RealP > | |
static RealP | stretchBy (RealP length, RealP tol) |
Stretch a dimension by a given tolerance amount. More... | |
template<class RealP > | |
static RealP | stretch (RealP length) |
Stretch a dimension using the default tolerance for this precision as the tolerance in stretchBy(). More... | |
The Geo class collects geometric primitives intended to deal with raw, fixed-size geometric shapes occupying minimal memory and providing maximum performance through small inline methods and larger high performance algorithms.
Subclasses collect algorithms relevant to particular shapes. There are no virtual methods or class hierarchies here; each subclass is a "POD" (plain old data) class. The general idea is to make it so that these common methods are implemented in only one place in Simbody.
The Geo class itself is dataless and provides only static methods. It is also used as a namespace for geometric primitives to allow these names to be used elsewhere for more significant objects.
typedef Point_<Real> SimTK::Geo::Point |
typedef Sphere_<Real> SimTK::Geo::Sphere |
typedef LineSeg_<Real> SimTK::Geo::LineSeg |
typedef Line_<Real> SimTK::Geo::Line |
typedef Plane_<Real> SimTK::Geo::Plane |
typedef Circle_<Real> SimTK::Geo::Circle |
typedef Box_<Real> SimTK::Geo::Box |
typedef AlignedBox_<Real> SimTK::Geo::AlignedBox |
typedef OrientedBox_<Real> SimTK::Geo::OrientedBox |
typedef Triangle_<Real> SimTK::Geo::Triangle |
typedef CubicHermiteCurve_<Real> SimTK::Geo::CubicHermiteCurve |
typedef BicubicHermitePatch_<Real> SimTK::Geo::BicubicHermitePatch |
typedef CubicBezierCurve_<Real> SimTK::Geo::CubicBezierCurve |
typedef BicubicBezierPatch_<Real> SimTK::Geo::BicubicBezierPatch |
|
inlinestatic |
Given the parametric derivative Pu(u)=dP/du, determine whether the point P(u) is at a cusp, that is, a place where the arc length s does not change when parameter u does, so ds/du=0 (within tolerance).
Note that an inflection point, where the curvature is zero, is not a cusp; see isInflectionPoint(). Cost is 6 flops.
|
inlinestatic |
Given the parametric derivatives Pu(u)=dP/du, and Puu(u)=d2P/du2 determine whether point P(u) is at an inflection point on the curve, that is, a flat place where there is no curvature (within tolerance).
We will also return true if this point is a cusp, where curvature is not defined. Cost is 15 flops.
If Puu is zero or parallel to Pu (meaning it changes the parametric tangent's length but not its direction) then we are at an inflection point. We consider a cusp to be an inflection point even though curvature is undefined there, so we define an inflection point to be any place where |Pu X Puu|==0 to within tolerance.
|
inlinestatic |
Calculate the unit tangent vector t=dP/ds, given Pu=dP/du.
This is undefined at a cusp (Pu==0). See Struik, eq. 2-2. Cost is about 40 flops.
|
inlinestatic |
Return the curvature vector c=dt/ds=d2P/ds2, given Pu=dP/du and Puu=d2P/du2.
This vector points towards the center of curvature, with length equal to the magnitude of the curvature (it's not a unit vector). Curvature is undefined at a cusp (where Pu==0). Since we define the curve unit normal n to point away from the center of curvature (see above), we have c=-k*n where k is the (scalar) curvature. Cost is about 30 flops.
See Struik, eqn. 4-3, 4-4. Let prime denote differentiation with respect to arclength:
u' = du/ds = 1/|Pu| u'' = -(~Pu Puu)/Pu^4 = -(~Pu Puu) * u'^4 t = P' = Pu u' = Pu/|Pu| c = t' = P'' = Puu u'^2 + Pu u'' = Puu/Pu^2 - Pu (~Pu Puu)/Pu^4 = -k * n, k is signed curvature, n is unit normal
Note that c can be used to determine the magnitude |k|, but you can't get the sign until the normal n has been defined. We're going to define n from c, so that n=-c/|c| so dot(c,n) is always negative meaning that k is always positive for us.
|
inlinestatic |
In our definition, the unit normal vector n points in the "outward" direction, that is, it points away from the center of curvature (opposite the curvature vector c so n=-c/|c|).
This convention is the opposite of Struik's, where he has the normal point in the same direction as the curvature vector. The normal is undefined at a cusp (Pu(u)==0), and is an arbitrary perpendicular to the tangent at an inflection point (a flat place where there is no curvature, i.e. |Pu(u) X Puu(u)|==0). If the curve is a straight line then every point is an inflection point, so the normal is arbitrary everywhere. Cost is about 80 flops.
|
inlinestatic |
Return the the curvature k (always positive), and a frame whose origin is a point along the curve, x axis is the outward unit normal n, y is the unit tangent t, and z=x X y is the binormal b, which is a normal to the osculating plane.
So the vectors n,t,b form a right-handed set; this convention is different from Struik's since he has n pointing the opposite direction. This frame is undefined at a cusp (Pu==0), and the normal is arbitrary at an inflection point (|Pu(u) X Puu(u)|==0) or if the curve is a line. Cost is about 115 flops.
|
inlinestatic |
Return k^2, the square of the scalar curvature k, given Pu=dP/du and Puu=d2P/du2.
Using our definition for the curve normal n (see above), k is always positive so the curvature is the positive square root of the value returned here. Curvature is undefined at a cusp (where Pu==0) and is zero at an inflection point (|Pu X Puu|==0). Cost is about 30 flops.
|Pu X Puu|^2 k^2 = |c|^2 = ------------ |Pu|^6
See Struik, pg. 17, eq. 5-5a.
|
inlinestatic |
Return tau, the torsion or "second curvature" given Pu=dP/du, Puu=d2P/du2, Puuu=d3P/du3.
Torsion is a signed quantity related to the rate of change of the osculating plane binormal b, with db/ds=tau*n where n is the "outward" unit normal (see above). Torsion is undefined at either a cusp (where Pu==0) or an inflection point (where |Pu X Puu|==0). Cost is about 30 flops.
~(Pu X Puu) * Puuu tau = ------------------ |Pu X Puu|^2
See Struik, pg. 17, eq. 5-5b and discussion on page 16.
|
inlinestatic |
Find the points of closest approach on two lines L0 and L1, each represented by an origin point and a direction.
Points and vectors must be in a common frame. We return point x0 on L0 and x1 on L1 such that the distance |x1-x0| is the smallest for any points on the two lines. If the lines are parallel or nearly so (all points same distance) we'll pick the point on each line closest to midway between the origins as the closest points and return and indication that the returned points weren't unique.
[in] | p0 | The origin point of line L0, that is, any point through which line L0 passes. |
[in] | d0 | A unit vector giving the direction of L0. |
[in] | p1 | The origin point of line L1. |
[in] | d1 | A unit vector giving the direction of L1. |
[out] | x0 | The point of L0 that is closest to L1. |
[out] | x1 | The point of L1 that is closest to L2. |
[out] | linesAreParallel | True if the lines were treated as effectively parallel. |
Cost is about 65 flops.
|
inlinestatic |
Return the default tolerance to use for degeneracy tests and other tests for "too small" or "near enough" that arise in dealing with geometry primitives.
The value depends on the precision being used; we use the SimTK constant SignificantReal which is eps^(7/8) where eps is the resolution of the template argument RealP (which must be float
or double
) That makes this tolerance around 2e-14 in double precision and 9e-7 in float.
|
inlinestatic |
Returns the square of the default tolerance.
|
inlinestatic |
Return machine precision for floating point calculations at precision RealP.
|
inlinestatic |
Return a NaN (not a number) at precision RealP.
|
inlinestatic |
Return Infinity at precision RealP. You can negate this for -Infinity.
|
inlinestatic |
Stretch a dimension by a given tolerance amount.
The result is the given length increased by at least an absolute amount tol, or by a relative amount length*tol if length > 1. Don't call this with tol less than machine precision or an exception will be thrown. Cost is 3 flops.
|
inlinestatic |
Stretch a dimension using the default tolerance for this precision as the tolerance in stretchBy().
Cost is 3 flops.