WFMath
1.0.1
|
00001 // rotbox.h (A box with arbitrary orientation) 00002 // 00003 // The WorldForge Project 00004 // Copyright (C) 2000, 2001 The WorldForge Project 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 // 00020 // For information about WorldForge and its authors, please contact 00021 // the Worldforge Web Site at http://www.worldforge.org. 00022 // 00023 00024 // Author: Ron Steinke 00025 00026 #ifndef WFMATH_ROT_BOX_H 00027 #define WFMATH_ROT_BOX_H 00028 00029 #include <wfmath/point.h> 00030 #include <wfmath/rotmatrix.h> 00031 #include <wfmath/intersect_decls.h> 00032 00033 namespace WFMath { 00034 00035 template<int dim> 00036 std::ostream& operator<<(std::ostream& os, const RotBox<dim>& r); 00037 template<int dim> 00038 std::istream& operator>>(std::istream& is, RotBox<dim>& r); 00039 00041 00045 template<int dim = 3> 00046 class RotBox 00047 { 00048 public: 00050 RotBox() : m_corner0(), m_size(), m_orient() {} 00052 00057 RotBox(const Point<dim>& p, const Vector<dim>& size, 00058 const RotMatrix<dim>& orientation) : m_corner0(p), m_size(size), 00059 m_orient(orientation) {} 00061 RotBox(const RotBox& b) : m_corner0(b.m_corner0), m_size(b.m_size), 00062 m_orient(b.m_orient) {} 00064 explicit RotBox(const AtlasInType& a); 00065 00066 ~RotBox() {} 00067 00069 AtlasOutType toAtlas() const; 00071 void fromAtlas(const AtlasInType& a); 00072 00073 friend std::ostream& operator<< <dim>(std::ostream& os, const RotBox& r); 00074 friend std::istream& operator>> <dim>(std::istream& is, RotBox& r); 00075 00076 RotBox& operator=(const RotBox& s); 00077 00078 bool isEqualTo(const RotBox& b, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const; 00079 00080 bool operator==(const RotBox& b) const {return isEqualTo(b);} 00081 bool operator!=(const RotBox& b) const {return !isEqualTo(b);} 00082 00083 bool isValid() const {return m_corner0.isValid() && m_size.isValid() 00084 && m_orient.isValid();} 00085 00086 // Descriptive characteristics 00087 00088 size_t numCorners() const {return 1 << dim;} 00089 Point<dim> getCorner(size_t i) const; 00090 Point<dim> getCenter() const {return m_corner0 + Prod(m_size / 2, m_orient);} 00091 00093 const Point<dim>& corner0() const {return m_corner0;} 00095 Point<dim>& corner0() {return m_corner0;} 00097 const Vector<dim>& size() const {return m_size;} 00099 Vector<dim>& size() {return m_size;} 00101 const RotMatrix<dim>& orientation() const {return m_orient;} 00103 RotMatrix<dim>& orientation() {return m_orient;} 00104 00105 // Movement functions 00106 00107 RotBox& shift(const Vector<dim>& v) 00108 {m_corner0 += v; return *this;} 00109 RotBox& moveCornerTo(const Point<dim>& p, size_t corner) 00110 {return shift(p - getCorner(corner));} 00111 RotBox& moveCenterTo(const Point<dim>& p) 00112 {return shift(p - getCenter());} 00113 00114 RotBox& rotateCorner(const RotMatrix<dim>& m, size_t corner) 00115 {rotatePoint(m, getCorner(corner)); return *this;} 00116 RotBox& rotateCenter(const RotMatrix<dim>& m) 00117 {rotatePoint(m, getCenter()); return *this;} 00118 RotBox& rotatePoint(const RotMatrix<dim>& m, const Point<dim>& p) 00119 {m_orient = Prod(m_orient, m); m_corner0.rotate(m, p); return *this;} 00120 00121 // 3D rotation functions 00122 RotBox& rotateCorner(const Quaternion& q, size_t corner); 00123 RotBox& rotateCenter(const Quaternion& q); 00124 RotBox& rotatePoint(const Quaternion& q, const Point<dim>& p); 00125 00126 // Intersection functions 00127 00128 AxisBox<dim> boundingBox() const; 00129 Ball<dim> boundingSphere() const 00130 {return Ball<dim>(getCenter(), m_size.mag() / 2);} 00131 Ball<dim> boundingSphereSloppy() const 00132 {return Ball<dim>(getCenter(), m_size.sqrMag() / 2);} 00133 00134 RotBox toParentCoords(const Point<dim>& origin, 00135 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const 00136 {return RotBox(m_corner0.toParentCoords(origin, rotation), m_size, 00137 m_orient * rotation);} 00138 RotBox toParentCoords(const AxisBox<dim>& coords) const 00139 {return RotBox(m_corner0.toParentCoords(coords), m_size, m_orient);} 00140 RotBox toParentCoords(const RotBox<dim>& coords) const 00141 {return RotBox(m_corner0.toParentCoords(coords), m_size, 00142 m_orient * coords.m_orient);} 00143 00144 // toLocal is just like toParent, expect we reverse the order of 00145 // translation and rotation and use the opposite sense of the rotation 00146 // matrix 00147 00148 RotBox toLocalCoords(const Point<dim>& origin, 00149 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const 00150 {return RotBox(m_corner0.toLocalCoords(origin, rotation), m_size, 00151 rotation * m_orient);} 00152 RotBox toLocalCoords(const AxisBox<dim>& coords) const 00153 {return RotBox(m_corner0.toLocalCoords(coords), m_size, m_orient);} 00154 RotBox toLocalCoords(const RotBox<dim>& coords) const 00155 {return RotBox(m_corner0.toLocalCoords(coords), m_size, 00156 coords.m_orient * m_orient);} 00157 00158 // 3D only 00159 RotBox toParentCoords(const Point<dim>& origin, const Quaternion& rotation) const; 00160 RotBox toLocalCoords(const Point<dim>& origin, const Quaternion& rotation) const; 00161 00162 friend bool Intersect<dim>(const RotBox& r, const Point<dim>& p, bool proper); 00163 friend bool Contains<dim>(const Point<dim>& p, const RotBox& r, bool proper); 00164 00165 friend bool Intersect<dim>(const RotBox& r, const AxisBox<dim>& b, bool proper); 00166 friend bool Contains<dim>(const RotBox& r, const AxisBox<dim>& b, bool proper); 00167 friend bool Contains<dim>(const AxisBox<dim>& b, const RotBox& r, bool proper); 00168 00169 friend bool Intersect<dim>(const RotBox& r, const Ball<dim>& b, bool proper); 00170 friend bool Contains<dim>(const RotBox& r, const Ball<dim>& b, bool proper); 00171 friend bool Contains<dim>(const Ball<dim>& b, const RotBox& r, bool proper); 00172 00173 friend bool Intersect<dim>(const RotBox& r, const Segment<dim>& s, bool proper); 00174 friend bool Contains<dim>(const RotBox& r, const Segment<dim>& s, bool proper); 00175 friend bool Contains<dim>(const Segment<dim>& s, const RotBox& r, bool proper); 00176 00177 friend bool Intersect<dim>(const RotBox& r1, const RotBox& r2, bool proper); 00178 friend bool Contains<dim>(const RotBox& outer, const RotBox& inner, bool proper); 00179 00180 friend bool Intersect<dim>(const Polygon<dim>& p, const RotBox& r, bool proper); 00181 friend bool Contains<dim>(const Polygon<dim>& p, const RotBox& r, bool proper); 00182 friend bool Contains<dim>(const RotBox& r, const Polygon<dim>& p, bool proper); 00183 00184 private: 00185 00186 Point<dim> m_corner0; 00187 Vector<dim> m_size; 00188 RotMatrix<dim> m_orient; 00189 }; 00190 00191 template<int dim> 00192 inline RotBox<dim>& RotBox<dim>::operator=(const RotBox<dim>& a) 00193 { 00194 m_corner0 = a.m_corner0; 00195 m_size = a.m_size; 00196 m_orient = a.m_orient; 00197 00198 return *this; 00199 } 00200 00201 template<int dim> 00202 inline bool RotBox<dim>::isEqualTo(const RotBox<dim>& b, CoordType epsilon) const 00203 { 00204 return Equal(m_corner0, b.m_corner0, epsilon) 00205 && Equal(m_size, b.m_size, epsilon) 00206 && Equal(m_orient, b.m_orient, epsilon); 00207 } 00208 00209 } // namespace WFMath 00210 00211 #endif // WFMATH_ROT_BOX_H