26#ifndef WFMATH_POLYGON_FUNCS_H
27#define WFMATH_POLYGON_FUNCS_H
29#include <wfmath/polygon.h>
31#include <wfmath/vector.h>
32#include <wfmath/point.h>
33#include <wfmath/ball.h>
43inline _Poly2Orient<dim>& _Poly2Orient<dim>::operator=(
const _Poly2Orient<dim>& a)
45 m_origin = a.m_origin;
47 for(
int i = 0; i < 2; ++i)
48 m_axes[i] = a.m_axes[i];
59 size_t size = m_poly.numCorners();
60 if(size != p.m_poly.numCorners())
63 for(
size_t i = 0; i < size; ++i)
64 if(!
Equal(getCorner(i), p.getCorner(i), epsilon))
73 assert(m_origin.isValid());
77 for(
int j = 0; j < 2; ++j) {
78 if(m_axes[j].isValid())
79 out += m_axes[j] * p[j];
95 if(!m_origin.isValid()) {
101 Vector<dim> shift = pd - m_origin, start_shift = shift;
103 CoordType bound = shift.sqrMag() * epsilon;
108 if(Dot(shift, start_shift) <= bound)
116 if(!m_axes[j].isValid()) {
118 m_axes[j] = shift / p2[j];
119 m_axes[j].setValid();
123 p2[j] = Dot(shift, m_axes[j]);
124 shift -= m_axes[j] * p2[j];
130_Poly2Reorient _Poly2Orient<dim>::reduce(
const Polygon<2>& poly,
size_t skip)
132 if(poly.numCorners() <= ((skip == 0) ? 1 : 0)) {
133 m_origin.setValid(
false);
134 m_axes[0].setValid(
false);
135 m_axes[1].setValid(
false);
136 return _WFMATH_POLY2REORIENT_NONE;
139 assert(m_origin.isValid());
141 if(!m_axes[0].isValid())
142 return _WFMATH_POLY2REORIENT_NONE;
146 bool still_valid[2] = {
false,}, got_ratio =
false;
147 CoordType ratio = std::numeric_limits<CoordType>::max();
148 CoordType size = std::numeric_limits<CoordType>::max();
150 size_t i, end = poly.numCorners();
153 for(i = 0; i < end; ++i) {
159 max = (x > y) ? x : y;
160 if(i == 0 || max < size)
164 (void) std::frexp(size, &exponent);
165 epsilon = std::ldexp(numeric_constants<CoordType>::epsilon(), exponent);
179 if(diff.sqrMag() < epsilon * epsilon)
181 if(!m_axes[1].isValid())
182 return _WFMATH_POLY2REORIENT_NONE;
183 for(
int j = 0; j < 2; ++j) {
184 if(std::fabs(diff[j]) < epsilon) {
185 assert(diff[j ? 0 : 1] >= epsilon);
186 if(still_valid[j ? 0 : 1] || got_ratio)
187 return _WFMATH_POLY2REORIENT_NONE;
188 still_valid[j] =
true;
192 if(still_valid[0] || still_valid[1])
193 return _WFMATH_POLY2REORIENT_NONE;
200 if(!
Equal(ratio, new_ratio))
201 return _WFMATH_POLY2REORIENT_NONE;
207 assert(m_axes[1].isValid());
208 assert(!still_valid[1]);
211 m_origin += m_axes[1] * first_point[1];
212 m_axes[1].setValid(
false);
213 return _WFMATH_POLY2REORIENT_CLEAR_AXIS2;
217 assert(m_axes[1].isValid());
220 m_origin += m_axes[0] * first_point[0];
221 m_axes[0] = m_axes[1];
222 m_axes[1].setValid(
false);
223 return _WFMATH_POLY2REORIENT_MOVE_AXIS2_TO_AXIS1;
228 m_origin += m_axes[0] * first_point[0];
229 if(m_axes[1].isValid())
230 m_origin += m_axes[1] * first_point[1];
231 m_axes[0].setValid(
false);
232 m_axes[1].setValid(
false);
233 return _WFMATH_POLY2REORIENT_CLEAR_BOTH_AXES;
236 assert(m_axes[1].isValid());
242 new0 = m_axes[0] + m_axes[1] * ratio;
252 m_origin += m_axes[1] * (first_point[1] - ratio * first_point[0]);
255 m_axes[1].setValid(
false);
256 return _Poly2Reorient(_WFMATH_POLY2REORIENT_SCALE1_CLEAR2, norm);
262 m_origin.rotate(m, p);
264 for(
int j = 0; j < 2; ++j)
265 m_axes[j] =
Prod(m_axes[j], m);
271 assert(m_origin.isValid());
273 if(!m_axes[0].isValid()) {
274 assert(p[0] == 0 && p[1] == 0);
279 m_axes[0] =
Prod(m_axes[0], m);
281 if(m_axes[1].isValid()) {
282 shift += m_axes[1] * p[1];
283 m_axes[1] =
Prod(m_axes[1], m);
288 m_origin += shift -
Prod(shift, m);
294 m_origin.rotate(q, p);
296 for(
int j = 0; j < 2; ++j)
303 assert(m_origin.isValid());
305 if(!m_axes[0].isValid()) {
306 assert(p[0] == 0 && p[1] == 0);
313 if(m_axes[1].isValid()) {
314 shift += m_axes[1] * p[1];
320 m_origin += shift - shift.rotate(q);
326 assert(m_poly.numCorners() > 0);
328 Point<dim> min = m_orient.convert(m_poly[0]), max = min;
329 bool valid = min.isValid();
331 for(
size_t i = 1; i != m_poly.numCorners(); ++i) {
333 valid = valid && p.isValid();
334 for(
int j = 0; j < dim; ++j) {
349inline Ball<dim> Polygon<dim>::boundingSphere()
const
351 Ball<2> b = m_poly.boundingSphere();
353 return Ball<dim>(m_orient.convert(b.center()), b.radius());
357inline Ball<dim> Polygon<dim>::boundingSphereSloppy()
const
359 Ball<2> b = m_poly.boundingSphereSloppy();
361 return Ball<dim>(m_orient.convert(b.center()), b.radius());
A dim dimensional axis-aligned box.
Definition axisbox.h:63
A dim dimensional ball.
Definition ball.h:61
A dim dimensional point.
Definition point.h:96
void setValid(bool valid=true)
make isValid() return true if you've initialized the point by hand
Definition point.h:129
A polygon, all of whose points lie in a plane, embedded in dim dimensions.
Definition polygon.h:307
A normalized quaterion.
Definition quaternion.h:36
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition rotmatrix.h:87
A dim dimensional vector.
Definition vector.h:121
Vector & rotate(int axis1, int axis2, CoordType theta)
Rotate the vector in the (axis1, axis2) plane by the angle theta.
Definition vector_funcs.h:191
Generic library namespace.
Definition atlasconv.h:45
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition rotmatrix_funcs.h:89
bool Equal(const C &c1, const C &c2, CoordType epsilon=numeric_constants< CoordType >::epsilon())
Test for equality up to precision epsilon.
Definition const.h:158
float CoordType
Basic floating point type.
Definition const.h:140