00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_SUPPORT_FUNCTORS_CYLINDER_H 00002 #define OPENTISSUE_COLLISION_GJK_GJK_SUPPORT_FUNCTORS_CYLINDER_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 #include <OpenTissue/core/math/math_is_number.h> 00013 00014 #include <cmath> 00015 #include <cassert> 00016 00017 namespace OpenTissue 00018 { 00019 namespace gjk 00020 { 00024 template<typename math_types> 00025 class Cylinder 00026 { 00027 protected: 00028 00029 typedef typename math_types::real_type T; 00030 typedef typename math_types::vector3_type V; 00031 typedef typename math_types::value_traits value_traits; 00032 00033 T m_half_height; 00034 T m_radius; 00035 00036 public: 00037 00043 T const & half_height() const { return this->m_half_height; } 00044 T & half_height() { return this->m_half_height; } 00045 00051 T const & radius() const { return this->m_radius; } 00052 T & radius() { return this->m_radius; } 00053 00054 public: 00055 00056 Cylinder() 00057 : m_half_height( value_traits::one() ) 00058 , m_radius( value_traits::one() ) 00059 {} 00060 00061 public: 00062 00063 V operator()(V const & v) const 00064 { 00065 using std::sqrt; 00066 00067 assert( this->m_half_height >= value_traits::zero() || !"Cylinder::operator(): Negative half height"); 00068 assert( this->m_radius >= value_traits::zero() || !"Cylinder::operator(): Negative radius"); 00069 00070 T const norm_sigma = sqrt( v(0)*v(0) + v(1)*v(1) ); 00071 assert( is_number( norm_sigma ) || !"Cylinder::operator(): NaN encountered"); 00072 assert( norm_sigma >= value_traits::zero() || !"Cylinder::operator(): Norm can not be negative"); 00073 00074 T const h = v(2) > value_traits::zero() ? this->m_half_height : -this->m_half_height; 00075 assert( is_number( h ) || !"Cylinder::operator(): NaN encountered"); 00076 00077 // Test if search direction has any radial component 00078 if(norm_sigma > value_traits::zero() ) 00079 { 00080 V const s = V( 00081 ((this->m_radius) * v(0)) /norm_sigma 00082 , ((this->m_radius) * v(1)) /norm_sigma 00083 , h 00084 ); 00085 00086 assert( is_number( s(0) ) || !"Cylinder::operator(): NaN encountered"); 00087 assert( is_number( s(1) ) || !"Cylinder::operator(): NaN encountered"); 00088 assert( is_number( s(2) ) || !"Cylinder::operator(): NaN encountered"); 00089 00090 return s; 00091 } 00092 00093 // Search direction is parallel with z-axis 00094 // 00095 // Or search direction is zero in which case we just some point as the support point. 00096 return V( value_traits::zero(), value_traits::zero(), h ); 00097 } 00098 00099 }; 00100 00101 00102 } // namespace gjk 00103 00104 } // namespace OpenTissue 00105 00106 // OPENTISSUE_COLLISION_GJK_GJK_SUPPORT_FUNCTORS_CYLINDER_H 00107 #endif