Simbody  3.4 (development)
Geo_Point.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATH_GEO_POINT_H_
00002 #define SimTK_SIMMATH_GEO_POINT_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                        Simbody(tm): SimTKmath                              *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2011-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00030 #include "SimTKcommon.h"
00031 #include "simmath/internal/common.h"
00032 #include "simmath/internal/Geo.h"
00033 
00034 #include <cassert>
00035 #include <cmath>
00036 #include <algorithm>
00037 
00038 namespace SimTK {
00039 
00040 //==============================================================================
00041 //                               GEO POINT
00042 //==============================================================================
00045 template <class P>
00046 class Geo::Point_ {
00047 typedef P               RealP;
00048 typedef Vec<3,P>        Vec3P;
00049 typedef Mat<3,3,P>      Mat33P;
00050 typedef SymMat<3,P>     SymMat33P;
00051 typedef UnitVec<P,1>    UnitVec3P;
00052 typedef Rotation_<P>    RotationP;
00053 typedef Transform_<P>   TransformP;
00054 
00055 public:
00057 Point_() {}
00060 Point_(const Vec3P& location) : p(location) {} 
00061 
00063 Point_& setLocation(const Vec3P& location) {p=location; return *this;}
00064 
00066 const Vec3P& getLocation() const {return p;}
00067 
00070 RealP calcDistance(const Vec3P& p2) const 
00071 {   return calcDistance(p, p2); }
00072 
00075 RealP findDistanceSqr(const Vec3P& p2) const 
00076 {   return findDistanceSqr(p, p2); }
00077 
00087 static RealP calcDistance(const Vec3P& p1, const Vec3P& p2)
00088 {   return std::sqrt(findDistanceSqr(p1,p2)); }
00089 
00092 static RealP findDistanceSqr(const Vec3P& p1, const Vec3P& p2)
00093 {   return (p2-p1).normSqr(); }
00094 
00096 static Vec3P findMidpoint(const Vec3P& p1, const Vec3P& p2)
00097 {   return (p1+p2)/2; }
00098 
00106 static bool pointsAreNumericallyCoincident(const Vec3P& p1, const Vec3P& p2)
00107 {
00108     return pointsAreNumericallyCoincident(p1,p2,Geo::getDefaultTol<RealP>());
00109 }
00111 static bool pointsAreNumericallyCoincident
00112    (const Vec3P& p1, const Vec3P& p2, RealP tol)
00113 {
00114     const RealP maxcoord = std::max(max(p1.abs()),max(p2.abs())); // ~7 flops
00115     const RealP scale = std::max(tol, maxcoord*tol); // 2 flops
00116     return findDistanceSqr(p1,p2) < square(scale); // 10 flops
00117 }
00118 
00119 
00123 SimTK_SIMMATH_EXPORT static void
00124 findSupportPoint(const Array_<Vec3P>& points, const UnitVec3P& direction,
00125                  int& most, RealP& mostCoord);
00126 
00129 SimTK_SIMMATH_EXPORT static void
00130 findSupportPointIndirect(const Array_<const Vec3P*>& points, 
00131                          const UnitVec3P& direction,
00132                          int& most, RealP& mostCoord);
00133 
00138 SimTK_SIMMATH_EXPORT static void
00139 findExtremePoints(const Array_<Vec3P>& points, const UnitVec3P& direction,
00140                   int& least, int& most,
00141                   RealP& leastCoord, RealP& mostCoord);
00142 
00145 SimTK_SIMMATH_EXPORT static void
00146 findExtremePointsIndirect(const Array_<const Vec3P*>& points, 
00147                           const UnitVec3P& direction,
00148                           int& least, int& most,
00149                           RealP& leastCoord, RealP& mostCoord);
00150 
00153 SimTK_SIMMATH_EXPORT static Vec3P
00154 calcCentroid(const Array_<Vec3P>& points_F);
00155 
00158 SimTK_SIMMATH_EXPORT static Vec3P
00159 calcCentroidIndirect(const Array_<const Vec3P*>& points_F);
00160 
00163 SimTK_SIMMATH_EXPORT static void
00164 calcCovariance(const Array_<Vec3P>& points_F,
00165                Vec3P& centroid, SymMat33P& covariance);
00166 
00169 SimTK_SIMMATH_EXPORT static void
00170 calcCovarianceIndirect(const Array_<const Vec3P*>& points_F,
00171                        Vec3P& centroid, SymMat33P& covariance);
00172 
00178 SimTK_SIMMATH_EXPORT static void
00179 calcPrincipalComponents(const Array_<Vec3P>& points_F,
00180                         TransformP&          X_FP);
00181 
00184 SimTK_SIMMATH_EXPORT static void
00185 calcPrincipalComponentsIndirect(const Array_<const Vec3P*>& points_F,
00186                                 TransformP&                 X_FP);
00187 
00200 SimTK_SIMMATH_EXPORT static void
00201 findAxisAlignedExtremePoints(const Array_<Vec3P>& points,
00202                              int least[3], int most[3],
00203                              Vec3P& low, Vec3P& high);
00204 
00207 SimTK_SIMMATH_EXPORT static void
00208 findAxisAlignedExtremePointsIndirect(const Array_<const Vec3P*>& points,
00209                                      int least[3], int most[3],
00210                                      Vec3P& low, Vec3P& high);
00211 
00214 SimTK_SIMMATH_EXPORT static Geo::AlignedBox_<P> 
00215 calcAxisAlignedBoundingBox(const Array_<Vec3P>& points,
00216                            Array_<int>&         support);
00217 
00219 static Geo::AlignedBox_<P> 
00220 calcAxisAlignedBoundingBox(const Array_<Vec3P>& points)
00221 {   Array_<int> support; 
00222     return calcAxisAlignedBoundingBox(points,support); }
00223 
00226 SimTK_SIMMATH_EXPORT static Geo::AlignedBox_<P> 
00227 calcAxisAlignedBoundingBoxIndirect(const Array_<const Vec3P*>& points,
00228                                    Array_<int>&                support);
00229 
00231 static Geo::AlignedBox_<P> 
00232 calcAxisAlignedBoundingBoxIndirect(const Array_<const Vec3P*>& points)
00233 {   Array_<int> support; 
00234     return calcAxisAlignedBoundingBoxIndirect(points,support); }
00235 
00255 SimTK_SIMMATH_EXPORT static void
00256 findOrientedExtremePoints(const Array_<Vec3P>&  points_F, 
00257                           const RotationP&      R_FB,
00258                           int least[3], int most[3],
00259                           Vec3P& low_B, Vec3P& high_B);
00260 
00263 SimTK_SIMMATH_EXPORT static void
00264 findOrientedExtremePointsIndirect(const Array_<const Vec3P*>&  points_F, 
00265                                   const RotationP&             R_FB,
00266                                   int least[3], int most[3],
00267                                   Vec3P& low_B, Vec3P& high_B);
00268 
00272 SimTK_SIMMATH_EXPORT static Geo::OrientedBox_<P> 
00273 calcOrientedBoundingBox(const Array_<Vec3P>& points,
00274                         Array_<int>&         support,
00275                         bool                 optimize=true);
00276 
00278 static Geo::OrientedBox_<P> 
00279 calcOrientedBoundingBox(const Array_<Vec3P>& points)
00280 {   Array_<int> support; 
00281     return calcOrientedBoundingBox(points,support); }
00282 
00285 SimTK_SIMMATH_EXPORT static Geo::OrientedBox_<P> 
00286 calcOrientedBoundingBoxIndirect(const Array_<const Vec3P*>& points,
00287                                 Array_<int>&                support,
00288                                 bool                        optimize=true);
00289 
00291 static Geo::OrientedBox_<P> 
00292 calcOrientedBoundingBoxIndirect(const Array_<const Vec3P*>& points,
00293                                 bool                        optimize=true)
00294 {   Array_<int> support; 
00295     return calcOrientedBoundingBoxIndirect(points,support,optimize); }
00333 static Sphere_<P> calcBoundingSphere(const Vec3P& p)
00334 {   return Sphere_<P>(p, 0).stretchBoundary(); }
00335 
00336 
00340 static Sphere_<P> calcBoundingSphere(const Vec3P& p0, const Vec3P& p1) {
00341     Array_<int> which;
00342     return calcBoundingSphere(p0,p1,which);
00343 }
00344 
00345 
00347 static Sphere_<P> calcBoundingSphere
00348    (const Vec3P& p0, const Vec3P& p1, const Vec3P& p2) {
00349     Array_<int> which;
00350     return calcBoundingSphere(p0,p1,p2,false,which);
00351 }
00352 
00354 static Sphere_<P> calcBoundingSphere
00355    (const Vec3P& p0, const Vec3P& p1, const Vec3P& p2, const Vec3P& p3) {
00356     Array_<int> which;
00357     return calcBoundingSphere(p0,p1,p2,p3,false,which);
00358 }
00359 
00363 static Sphere_<P> calcBoundingSphere(const Array_<Vec3P>& points) {
00364     Array_<int> which; 
00365     return calcBoundingSphere(points, which);
00366 }
00367 
00370 static Sphere_<P> 
00371 calcBoundingSphere(const std::vector<Vec3P>& points) {
00372     return calcBoundingSphere // no copy done here
00373                 (ArrayViewConst_<Vec3P>(points));
00374 }
00375 
00379 static Sphere_<P> calcBoundingSphereIndirect(const Array_<const Vec3P*>& points) {
00380     Array_<int> which; 
00381     return calcBoundingSphereIndirect(points, which);
00382 }
00383 
00386 static Sphere_<P> 
00387 calcBoundingSphere(const std::vector<const Vec3P*>& points) {
00388     return calcBoundingSphereIndirect // no copy done here
00389                 (ArrayViewConst_<const Vec3P*>(points));
00390 }
00391 
00394 static Sphere_<P> calcBoundingSphere(const Vec3P& p0, Array_<int>& which) 
00395 {   which.clear(); which.push_back(0); 
00396     return Sphere_<P>(p0,0).stretchBoundary(); }
00397 
00406 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00407 calcBoundingSphere(const Vec3P& p0, const Vec3P& p1, Array_<int>& which);
00408 
00415 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00416 calcBoundingSphere(const Vec3P& p0, const Vec3P& p1, const Vec3P& p2, 
00417                    bool forceCircumsphere, Array_<int>& which);
00418 
00425 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00426 calcBoundingSphere(const Vec3P& p0, const Vec3P& p1, const Vec3P& p2, 
00427                    const Vec3P& p3, bool forceCircumsphere, Array_<int>& which);
00428 
00433 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00434 calcBoundingSphere(const Array_<Vec3P>& points, Array_<int>& which);
00435 
00437 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00438 calcBoundingSphereIndirect(const Array_<const Vec3P*>& points, 
00439                            Array_<int>& which);
00440 
00443 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00444 calcApproxBoundingSphere(const Array_<Vec3P>& points);
00445 
00448 static Sphere_<P> 
00449 calcApproxBoundingSphere(const std::vector<Vec3P>& points) {
00450     return calcApproxBoundingSphere // no copy done here
00451                 (ArrayViewConst_<Vec3P>(points));
00452 }
00453 
00455 SimTK_SIMMATH_EXPORT static Sphere_<P> 
00456 calcApproxBoundingSphereIndirect(const Array_<const Vec3P*>& points);
00457 
00460 static Sphere_<P> 
00461 calcApproxBoundingSphereIndirect(const std::vector<const Vec3P*>& points) {
00462     return calcApproxBoundingSphereIndirect // no copy done here
00463                 (ArrayViewConst_<const Vec3P*>(points));
00464 }
00468 private:
00469 Vec3P   p;
00470 };
00471 
00472 } // namespace SimTK
00473 
00474 #endif // SimTK_SIMMATH_GEO_POINT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines