Simbody  3.5
Contact.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATH_CONTACT_H_
00002 #define SimTK_SIMMATH_CONTACT_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) 2008-12 Stanford University and the Authors.        *
00013  * Authors: Peter Eastman, 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 
00027 #include "SimTKcommon.h"
00028 #include "simmath/internal/common.h"
00029 
00030 namespace SimTK {
00031 
00032 
00037 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactSurfaceIndex);
00038 
00048 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactId);
00049 
00056 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactTypeId);
00057 
00058 
00059 class ContactImpl;
00060 class UntrackedContactImpl;
00061 class BrokenContactImpl;
00062 class CircularPointContactImpl;
00063 class EllipticalPointContactImpl;
00064 class BrickHalfSpaceContactImpl;
00065 class TriangleMeshContactImpl;
00066 
00067 class PointContactImpl; // deprecated
00068 
00069 
00070 //==============================================================================
00071 //                                CONTACT
00072 //==============================================================================
00083 class SimTK_SIMMATH_EXPORT Contact {
00084 public:
00087     enum Condition {
00088         Unknown,    
00089         Untracked,  
00090         Anticipated,
00091         NewContact, 
00092         Ongoing,    
00093         Broken      
00094     };
00098     static const char* nameOfCondition(Condition);
00099 
00101     Contact() : impl(0) {}
00104     Contact(const Contact& source);
00107     ~Contact() {clear();}
00110     Contact& operator=(const Contact& source);
00113     void clear();
00115     bool isEmpty() const {return impl==0;}
00116 
00120     ContactId getContactId() const;
00122     Condition getCondition() const;
00125     ContactSurfaceIndex getSurface1() const;
00128     ContactSurfaceIndex getSurface2() const;
00132     const Transform& getTransform() const;
00133 
00136     Contact& setContactId(ContactId id);
00138     Contact& setCondition(Condition condition);
00140     Contact& setSurfaces(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2);
00142     Contact& setTransform(const Transform& X_S1S2);
00143 
00146     ContactTypeId getTypeId() const;
00147 
00151     static ContactId createNewContactId();
00152 
00153     const ContactImpl& getImpl() const {assert(impl); return *impl;}
00154     ContactImpl&       updImpl()       {assert(impl); return *impl;}
00155 protected:
00156     explicit Contact(ContactImpl* impl);
00157 private:
00158     ContactImpl* impl;
00159 };
00160 
00161 inline std::ostream& operator<<(std::ostream& o, const Contact& c) {
00162     o << "Contact id=" << c.getContactId() 
00163                        << " (typeId=" << c.getTypeId() << "):\n";
00164     o << "  surf1,surf2=" << c.getSurface1() << ","
00165                           << c.getSurface2() << "\n";
00166     o << "  condition=" << Contact::nameOfCondition(c.getCondition()) << "\n";
00167     return o;
00168 }
00169 
00170 
00171 
00172 //==============================================================================
00173 //                            UNTRACKED CONTACT
00174 //==============================================================================
00180 class SimTK_SIMMATH_EXPORT UntrackedContact : public Contact {
00181 public:
00183     UntrackedContact() {}
00189     UntrackedContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2); 
00190 
00192     static bool isInstance(const Contact& contact);
00194     static ContactTypeId classTypeId();
00195 
00196 private:
00197     const UntrackedContactImpl& getImpl() const 
00198     {   assert(isInstance(*this)); 
00199         return reinterpret_cast<const UntrackedContactImpl&>
00200                     (Contact::getImpl()); }
00201 };
00202 
00203 
00204 
00205 //==============================================================================
00206 //                            BROKEN CONTACT
00207 //==============================================================================
00214 class SimTK_SIMMATH_EXPORT BrokenContact : public Contact {
00215 public:
00222     BrokenContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2,
00223                   const Transform& X_S1S2, Real separation); 
00224 
00228     Real getSeparation() const;
00229 
00231     static bool isInstance(const Contact& contact);
00233     static ContactTypeId classTypeId();
00234 
00235 private:
00236     const BrokenContactImpl& getImpl() const 
00237     {   assert(isInstance(*this)); 
00238         return reinterpret_cast<const BrokenContactImpl&>(Contact::getImpl()); }
00239 };
00240 
00241 
00242 
00243 //==============================================================================
00244 //                           CIRCULAR POINT CONTACT
00245 //==============================================================================
00258 class SimTK_SIMMATH_EXPORT CircularPointContact : public Contact {
00259 public:
00274     CircularPointContact
00275        (ContactSurfaceIndex surf1, Real radius1, 
00276         ContactSurfaceIndex surf2, Real radius2, 
00277         const Transform& X_S1S2, Real radius, Real depth, 
00278         const Vec3& origin_S1, const UnitVec3& normal_S1);
00279 
00281     Real getRadius1() const;
00283     Real getRadius2() const;
00286     Real getEffectiveRadius() const;
00291     Real getDepth() const;
00293     const Vec3& getOrigin() const;
00297     const UnitVec3& getNormal() const;
00298 
00300     static bool isInstance(const Contact& contact);
00301     static const CircularPointContact& getAs(const Contact& contact)
00302     {   assert(isInstance(contact)); 
00303         return static_cast<const CircularPointContact&>(contact); }
00304     static CircularPointContact& updAs(Contact& contact)
00305     {   assert(isInstance(contact)); 
00306         return static_cast<CircularPointContact&>(contact); }
00307 
00309     static ContactTypeId classTypeId();
00310 
00311 private:
00312     const CircularPointContactImpl& getImpl() const 
00313     {   assert(isInstance(*this)); 
00314         return reinterpret_cast<const CircularPointContactImpl&>
00315                     (Contact::getImpl()); }
00316 };
00317 
00318 
00319 
00320 //==============================================================================
00321 //                           ELLIPTICAL POINT CONTACT
00322 //==============================================================================
00353 class SimTK_SIMMATH_EXPORT EllipticalPointContact : public Contact {
00354 public:
00368     EllipticalPointContact
00369        (ContactSurfaceIndex surf1, ContactSurfaceIndex surf2,
00370         const Transform& X_S1S2, 
00371         const Transform& X_S1C, const Vec2& k, Real depth); 
00372 
00375     const Vec2& getCurvatures() const;
00382     const Transform& getContactFrame() const;
00387     Real getDepth() const;
00388 
00390     static bool isInstance(const Contact& contact);
00391     static const EllipticalPointContact& getAs(const Contact& contact)
00392     {   assert(isInstance(contact)); 
00393         return static_cast<const EllipticalPointContact&>(contact); }
00394     static EllipticalPointContact& updAs(Contact& contact)
00395     {   assert(isInstance(contact)); 
00396         return static_cast<EllipticalPointContact&>(contact); }
00397 
00399     static ContactTypeId classTypeId();
00400 
00401 private:
00402     const EllipticalPointContactImpl& getImpl() const 
00403     {   assert(isInstance(*this)); 
00404         return reinterpret_cast<const EllipticalPointContactImpl&>
00405                     (Contact::getImpl()); }
00406 };
00407 
00408 
00409 
00410 //==============================================================================
00411 //                           BRICK HALFSPACE CONTACT
00412 //==============================================================================
00416 class SimTK_SIMMATH_EXPORT BrickHalfSpaceContact : public Contact {
00417 public:
00428     BrickHalfSpaceContact(ContactSurfaceIndex     halfSpace, 
00429                           ContactSurfaceIndex     brick,
00430                           const Transform&        X_HB,
00431                           int                     lowestVertex,
00432                           Real                    depth);
00433 
00436     int getLowestVertex() const;
00437 
00440     Real getDepth() const;
00441 
00443     static bool isInstance(const Contact& contact);
00444     
00447     static const BrickHalfSpaceContact& getAs(const Contact& contact)
00448     {   assert(isInstance(contact)); 
00449         return static_cast<const BrickHalfSpaceContact&>(contact); }
00450         
00453     static BrickHalfSpaceContact& updAs(Contact& contact)
00454     {   assert(isInstance(contact)); 
00455         return static_cast<BrickHalfSpaceContact&>(contact); }
00456 
00459     static ContactTypeId classTypeId();
00460 
00461 private:
00462     const BrickHalfSpaceContactImpl& getImpl() const 
00463     {   assert(isInstance(*this)); 
00464         return reinterpret_cast<const BrickHalfSpaceContactImpl&>
00465                     (Contact::getImpl()); }
00466 };
00467 
00468 
00469 
00470 //==============================================================================
00471 //                           TRIANGLE MESH CONTACT
00472 //==============================================================================
00476 class SimTK_SIMMATH_EXPORT TriangleMeshContact : public Contact {
00477 public:
00489     TriangleMeshContact(ContactSurfaceIndex     surf1, 
00490                         ContactSurfaceIndex     surf2,
00491                         const Transform&        X_S1S2,
00492                         const std::set<int>&    faces1, 
00493                         const std::set<int>&    faces2);
00494 
00498     const std::set<int>& getSurface1Faces() const;
00502     const std::set<int>& getSurface2Faces() const;
00503 
00505     static bool isInstance(const Contact& contact);
00508     static const TriangleMeshContact& getAs(const Contact& contact)
00509     {   assert(isInstance(contact)); 
00510         return static_cast<const TriangleMeshContact&>(contact); }
00513     static TriangleMeshContact& updAs(Contact& contact)
00514     {   assert(isInstance(contact)); 
00515         return static_cast<TriangleMeshContact&>(contact); }
00516 
00519     static ContactTypeId classTypeId();
00520 
00521 private:
00522     const TriangleMeshContactImpl& getImpl() const 
00523     {   assert(isInstance(*this)); 
00524         return reinterpret_cast<const TriangleMeshContactImpl&>
00525                     (Contact::getImpl()); }
00526 };
00527 
00528 
00529 
00530 
00531 //==============================================================================
00532 //                               POINT CONTACT
00533 //==============================================================================
00540 class SimTK_SIMMATH_EXPORT PointContact : public Contact {
00541 public:
00558     PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 
00559                  Vec3& location, Vec3& normal, Real radius1, Real radius2, Real depth);
00575     PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2,
00576                  Vec3& location, Vec3& normal, Real radius, Real depth);
00582     Vec3 getLocation() const;
00587     Vec3 getNormal() const;
00591     Real getRadiusOfCurvature1() const;
00595     Real getRadiusOfCurvature2() const;
00600     Real getEffectiveRadiusOfCurvature() const;
00606     Real getDepth() const;
00610     static bool isInstance(const Contact& contact);
00614     static ContactTypeId classTypeId();
00615 
00616 private:
00617     const PointContactImpl& getImpl() const 
00618     {   assert(isInstance(*this)); 
00619         return reinterpret_cast<const PointContactImpl&>(Contact::getImpl()); }
00620 };
00621 
00622 } // namespace SimTK
00623 
00624 #endif // SimTK_SIMMATH_CONTACT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines