26 #ifndef WFMATH_POLYGON_H
27 #define WFMATH_POLYGON_H
29 #include <wfmath/axisbox.h>
30 #include <wfmath/ball.h>
31 #include <wfmath/vector.h>
32 #include <wfmath/point.h>
33 #include <wfmath/quaternion.h>
34 #include <wfmath/rotbox.h>
35 #include <wfmath/intersect_decls.h>
41 template<
int dim>
class Polygon;
44 std::ostream& operator<<(std::ostream& os, const Polygon<dim>& r);
46 std::istream& operator>>(std::istream& is, Polygon<dim>& r);
56 explicit Polygon(
const AtlasInType& a) : m_points() {fromAtlas(a);}
60 friend std::ostream& operator<< <2>(std::ostream& os,
const Polygon& p);
61 friend std::istream&
operator>> <2>(std::istream& is, Polygon& p);
65 AtlasOutType toAtlas()
const;
67 void fromAtlas(
const AtlasInType& a);
69 Polygon& operator=(
const Polygon& p)
70 {m_points = p.m_points;
return *
this;}
72 bool isEqualTo(
const Polygon& p,
double epsilon = WFMATH_EPSILON)
const;
74 bool operator==(
const Polygon& p)
const {
return isEqualTo(p);}
75 bool operator!=(
const Polygon& p)
const {
return !isEqualTo(p);}
81 int numCorners()
const {
return m_points.size();}
82 Point<2> getCorner(
int i)
const {
return m_points[i];}
83 Point<2> getCenter()
const {
return Barycenter(m_points);}
90 bool addCorner(
int i,
const Point<2>& p,
double epsilon = WFMATH_EPSILON)
91 {m_points.insert(m_points.begin() + i, p);
return true;}
94 void removeCorner(
int i) {m_points.erase(m_points.begin() + i);}
97 bool moveCorner(
int i,
const Point<2>& p,
double epsilon = WFMATH_EPSILON)
98 {m_points[i] = p;
return true;}
101 void clear() {m_points.clear();}
103 const Point<2>& operator[](
int i)
const {
return m_points[i];}
104 Point<2>& operator[](
int i) {
return m_points[i];}
106 void resize(
unsigned int size) {m_points.resize(size);}
110 Polygon& shift(
const Vector<2>& v);
111 Polygon& moveCornerTo(
const Point<2>& p,
int corner)
112 {
return shift(p - getCorner(corner));}
113 Polygon& moveCenterTo(
const Point<2>& p)
114 {
return shift(p - getCenter());}
116 Polygon& rotateCorner(
const RotMatrix<2>& m,
int corner)
117 {rotatePoint(m, getCorner(corner));
return *
this;}
118 Polygon& rotateCenter(
const RotMatrix<2>& m)
119 {rotatePoint(m, getCenter());
return *
this;}
120 Polygon& rotatePoint(
const RotMatrix<2>& m,
const Point<2>& p);
124 AxisBox<2> boundingBox()
const {
return BoundingBox(m_points);}
128 Polygon toParentCoords(
const Point<2>& origin,
129 const RotMatrix<2>& rotation = RotMatrix<2>().identity())
const;
130 Polygon toParentCoords(
const AxisBox<2>& coords)
const;
131 Polygon toParentCoords(
const RotBox<2>& coords)
const;
137 Polygon toLocalCoords(
const Point<2>& origin,
138 const RotMatrix<2>& rotation = RotMatrix<2>().identity())
const;
139 Polygon toLocalCoords(
const AxisBox<2>& coords)
const;
140 Polygon toLocalCoords(
const RotBox<2>& coords)
const;
142 friend bool Intersect<2>(
const Polygon& r,
const Point<2>& p,
bool proper);
143 friend bool Contains<2>(
const Point<2>& p,
const Polygon& r,
bool proper);
145 friend bool Intersect<2>(
const Polygon& p,
const AxisBox<2>& b,
bool proper);
146 friend bool Contains<2>(
const Polygon& p,
const AxisBox<2>& b,
bool proper);
147 friend bool Contains<2>(
const AxisBox<2>& b,
const Polygon& p,
bool proper);
149 friend bool Intersect<2>(
const Polygon& p,
const Ball<2>& b,
bool proper);
150 friend bool Contains<2>(
const Polygon& p,
const Ball<2>& b,
bool proper);
151 friend bool Contains<2>(
const Ball<2>& b,
const Polygon& p,
bool proper);
153 friend bool Intersect<2>(
const Polygon& r,
const Segment<2>& s,
bool proper);
154 friend bool Contains<2>(
const Polygon& p,
const Segment<2>& s,
bool proper);
155 friend bool Contains<2>(
const Segment<2>& s,
const Polygon& p,
bool proper);
157 friend bool Intersect<2>(
const Polygon& p,
const RotBox<2>& r,
bool proper);
158 friend bool Contains<2>(
const Polygon& p,
const RotBox<2>& r,
bool proper);
159 friend bool Contains<2>(
const RotBox<2>& r,
const Polygon& p,
bool proper);
161 friend bool Intersect<2>(
const Polygon& p1,
const Polygon& p2,
bool proper);
162 friend bool Contains<2>(
const Polygon& outer,
const Polygon& inner,
bool proper);
165 std::vector<Point<2> > m_points;
166 typedef std::vector<Point<2> >::iterator theIter;
167 typedef std::vector<Point<2> >::const_iterator theConstIter;
175 _WFMATH_POLY2REORIENT_NONE,
176 _WFMATH_POLY2REORIENT_CLEAR_AXIS2,
177 _WFMATH_POLY2REORIENT_CLEAR_BOTH_AXES,
178 _WFMATH_POLY2REORIENT_MOVE_AXIS2_TO_AXIS1,
179 _WFMATH_POLY2REORIENT_SCALE1_CLEAR2
180 } _Poly2ReorientType;
187 _Poly2Reorient(_Poly2ReorientType type,
CoordType scale = 0.0)
188 : m_type(type), m_scale(scale) {}
191 void reorient(Polygon<2>& poly,
int skip = -1)
const;
194 _Poly2ReorientType m_type;
198 template<
int dim>
class _Poly2Orient;
200 struct _Poly2OrientIntersectData {
203 Vector<2> v1, v2, off;
204 bool o1_is_line, o2_is_line;
212 int _Intersect(
const _Poly2Orient<dim> &,
const _Poly2Orient<dim> &,
213 _Poly2OrientIntersectData &);
220 _Poly2Orient() : m_origin() {}
221 _Poly2Orient(
const _Poly2Orient& p) : m_origin() {operator=(p);}
224 _Poly2Orient& operator=(
const _Poly2Orient& p);
227 Point<dim> convert(
const Point<2>& p)
const;
232 bool expand(
const Point<dim>& pd, Point<2>& p2,
double epsilon = WFMATH_EPSILON);
237 _Poly2Reorient reduce(
const Polygon<2>& poly,
int skip = -1);
239 void shift(
const Vector<dim>& v) {
if(m_origin.isValid()) m_origin += v;}
240 void rotate(
const RotMatrix<dim>& m,
const Point<dim>& p);
242 void rotate2(
const RotMatrix<dim>& m,
const Point<2>& p);
245 void rotate(
const Quaternion& q,
const Point<3>& p);
247 void rotate2(
const Quaternion& q,
const Point<2>& p);
249 _Poly2Orient toParentCoords(
const Point<dim>& origin,
250 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity())
const
251 {_Poly2Orient p(*
this); p.m_origin = m_origin.toParentCoords(origin, rotation);
252 p.m_axes[0].rotate(rotation); p.m_axes[1].rotate(rotation);
return p;}
253 _Poly2Orient toParentCoords(
const AxisBox<dim>& coords)
const
254 {_Poly2Orient p(*
this); p.m_origin = m_origin.toParentCoords(coords);
return p;}
255 _Poly2Orient toParentCoords(
const RotBox<dim>& coords)
const
256 {_Poly2Orient p(*
this); p.m_origin = m_origin.toParentCoords(coords);
257 p.m_axes[0].rotate(coords.orientation());
258 p.m_axes[1].rotate(coords.orientation());
return p;}
264 _Poly2Orient toLocalCoords(
const Point<dim>& origin,
265 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity())
const
266 {_Poly2Orient p(*
this); p.m_origin = m_origin.toLocalCoords(origin, rotation);
267 p.m_axes[0] = rotation * p.m_axes[0];
268 p.m_axes[1] = rotation * p.m_axes[1];
return p;}
269 _Poly2Orient toLocalCoords(
const AxisBox<dim>& coords)
const
270 {_Poly2Orient p(*
this); p.m_origin = m_origin.toLocalCoords(coords);
return p;}
271 _Poly2Orient toLocalCoords(
const RotBox<dim>& coords)
const
272 {_Poly2Orient p(*
this); p.m_origin = m_origin.toLocalCoords(coords);
273 p.m_axes[0] = coords.orientation() * p.m_axes[0];
274 p.m_axes[1] = coords.orientation() * p.m_axes[1];
return p;}
277 _Poly2Orient<3> toParentCoords(
const Point<3>& origin,
const Quaternion& rotation)
const
278 {_Poly2Orient p(*
this); p.m_origin = m_origin.toParentCoords(origin, rotation);
279 p.m_axes[0].rotate(rotation); p.m_axes[0].rotate(rotation);
return p;}
280 _Poly2Orient<3> toLocalCoords(
const Point<3>& origin,
const Quaternion& rotation)
const
281 {_Poly2Orient p(*
this); p.m_origin = m_origin.toLocalCoords(origin, rotation);
282 p.m_axes[0].rotate(rotation.inverse());
283 p.m_axes[0].rotate(rotation.inverse());
return p;}
287 Vector<dim> offset(
const Point<dim>& pd, Point<2>& p2)
const;
290 bool checkContained(
const Point<dim>& pd, Point<2> & p2)
const;
294 bool checkIntersect(
const AxisBox<dim>& b, Point<2>& p2,
bool proper)
const;
296 friend int _Intersect<dim>(
const _Poly2Orient<dim> &,
const _Poly2Orient<dim> &,
297 _Poly2OrientIntersectData &);
301 bool checkIntersectPlane(
const AxisBox<dim>& b, Point<2>& p2,
bool proper)
const;
304 Vector<dim> m_axes[2];
308 template<
int dim = 3>
312 Polygon() : m_orient(), m_poly() {}
313 Polygon(
const Polygon& p) : m_orient(p.m_orient), m_poly(p.m_poly) {}
317 friend std::ostream& operator<< <dim>(std::ostream& os,
const Polygon& p);
318 friend std::istream&
operator>> <dim>(std::istream& is,
Polygon& p);
321 {m_orient = p.m_orient; m_poly = p.m_poly;
return *
this;}
323 bool isEqualTo(
const Polygon& p2,
double epsilon = WFMATH_EPSILON)
const;
325 bool operator==(
const Polygon& p)
const {
return isEqualTo(p);}
326 bool operator!=(
const Polygon& p)
const {
return !isEqualTo(p);}
328 bool isValid()
const {
return m_poly.isValid();}
332 int numCorners()
const {
return m_poly.numCorners();}
333 Point<dim> getCorner(
int i)
const {
return m_orient.convert(m_poly[i]);}
334 Point<dim> getCenter()
const {
return m_orient.convert(m_poly.getCenter());}
341 bool addCorner(
int i,
const Point<dim>& p,
double epsilon = WFMATH_EPSILON);
344 void removeCorner(
int i);
350 bool moveCorner(
int i,
const Point<dim>& p,
double epsilon = WFMATH_EPSILON);
353 void clear() {m_poly.clear(); m_orient = _Poly2Orient<dim>();}
358 {m_orient.shift(v);
return *
this;}
360 {
return shift(p - getCorner(corner));}
362 {
return shift(p - getCenter());}
365 {m_orient.rotate2(m, m_poly[corner]);
return *
this;}
367 {
if(m_poly.numCorners() > 0)
368 m_orient.rotate2(m, m_poly.getCenter());
371 {m_orient.rotate(m, p);
return *
this;}
375 {m_orient.rotate2(q, m_poly[corner]);
return *
this;}
377 {
if(m_poly.numCorners() > 0)
378 m_orient.rotate2(q, m_poly.getCenter());
381 {m_orient.rotate(q, p);
return *
this;}
391 {
Polygon p(*
this); p.m_orient = m_orient.toParentCoords(origin, rotation);
return p;}
393 {
Polygon p(*
this); p.m_orient = m_orient.toParentCoords(coords);
return p;}
395 {
Polygon p(*
this); p.m_orient = m_orient.toParentCoords(coords);
return p;}
403 {
Polygon p(*
this); p.m_orient = m_orient.toLocalCoords(origin, rotation);
return p;}
405 {
Polygon p(*
this); p.m_orient = m_orient.toLocalCoords(coords);
return p;}
407 {
Polygon p(*
this); p.m_orient = m_orient.toLocalCoords(coords);
return p;}
411 {
Polygon<3> p(*
this); p.m_orient = m_orient.toParentCoords(origin, rotation);
return p;}
413 {
Polygon<3> p(*
this); p.m_orient = m_orient.toLocalCoords(origin, rotation);
return p;}
422 friend bool Intersect<dim>(
const Polygon& p,
const Ball<dim>& b,
bool proper);
423 friend bool Contains<dim>(
const Polygon& p,
const Ball<dim>& b,
bool proper);
424 friend bool Contains<dim>(
const Ball<dim>& b,
const Polygon& p,
bool proper);
434 friend bool Intersect<dim>(
const Polygon& p1,
const Polygon& p2,
bool proper);
435 friend bool Contains<dim>(
const Polygon& outer,
const Polygon& inner,
bool proper);
439 _Poly2Orient<dim> m_orient;
445 #endif // WFMATH_POLYGON_H