00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
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
00145
00146
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
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 }
00210
00211 #endif // WFMATH_ROT_BOX_H