24#ifndef WFMATH_INTERSECT_H
25#define WFMATH_INTERSECT_H
27#include <wfmath/vector.h>
28#include <wfmath/point.h>
29#include <wfmath/const.h>
30#include <wfmath/intersect_decls.h>
31#include <wfmath/axisbox.h>
32#include <wfmath/ball.h>
33#include <wfmath/segment.h>
34#include <wfmath/rotbox.h>
44template<
class S1,
class S2>
45inline bool Intersect(
const S1& s1,
const S2& s2,
bool proper)
47 return Intersect(s2, s1, proper);
55 return !proper && p1 == p2;
58template<
int dim,
class S>
59inline bool Contains(
const S& s,
const Point<dim>& p,
bool proper)
61 return Intersect(p, s, proper);
67 return !proper && p1 == p2;
75 for(
int i = 0; i < dim; ++i)
76 if(_Greater(b.m_low[i], p[i], proper) || _Less(b.m_high[i], p[i], proper))
85 return !proper && p == b.m_low && p == b.m_high;
91 for(
int i = 0; i < dim; ++i)
92 if(_Greater(b1.m_low[i], b2.m_high[i], proper)
93 || _Less(b1.m_high[i], b2.m_low[i], proper))
102 for(
int i = 0; i < dim; ++i)
103 if(_Less(inner.m_low[i], outer.m_low[i], proper)
104 || _Greater(inner.m_high[i], outer.m_high[i], proper))
115 return _LessEq(SquaredDistance(b.m_center, p), b.m_radius * b.m_radius
116 * (1 + numeric_constants<CoordType>::epsilon()), proper);
122 return !proper && b.m_radius == 0 && p == b.m_center;
130 for(
int i = 0; i < dim; ++i) {
132 if(b.m_center[i] < a.m_low[i])
133 dist_i = b.m_center[i] - a.m_low[i];
134 else if(b.m_center[i] > a.m_high[i])
135 dist_i = b.m_center[i] - a.m_high[i];
138 dist+= dist_i * dist_i;
141 return _LessEq(dist, b.m_radius * b.m_radius, proper);
149 for(
int i = 0; i < dim; ++i) {
150 CoordType furthest = FloatMax(std::fabs(b.m_center[i] - a.m_low[i]),
151 std::fabs(b.m_center[i] - a.m_high[i]));
152 sqr_dist += furthest * furthest;
155 return _LessEq(sqr_dist, b.m_radius * b.m_radius * (1 + numeric_constants<CoordType>::epsilon()), proper);
161 for(
int i = 0; i < dim; ++i)
162 if(_Less(b.m_center[i] - b.m_radius, a.lowerBound(i), proper)
163 || _Greater(b.m_center[i] + b.m_radius, a.upperBound(i), proper))
172 CoordType sqr_dist = SquaredDistance(b1.m_center, b2.m_center);
173 CoordType rad_sum = b1.m_radius + b2.m_radius;
175 return _LessEq(sqr_dist, rad_sum * rad_sum, proper);
181 CoordType rad_diff = outer.m_radius - inner.m_radius;
183 if(_Less(rad_diff, 0, proper))
186 CoordType sqr_dist = SquaredDistance(outer.m_center, inner.m_center);
188 return _LessEq(sqr_dist, rad_diff * rad_diff, proper);
202 if(_Greater(proj, 0, proper))
206 return Equal(proj * proj, v1.sqrMag() * v2.sqrMag());
212 return !proper && p == s.m_p1 && p == s.m_p2;
228 for(
int i = 0; i < dim; ++i) {
231 if(_Less(s.m_p1[i], b.m_low[i], proper)
232 || _Greater(s.m_p1[i], b.m_high[i], proper))
236 CoordType low = (b.m_low[i] - s.m_p1[i]) / dist;
237 CoordType high = (b.m_high[i] - s.m_p1[i]) / dist;
250 return _LessEq(min, max, proper);
259 bool got_difference =
false;
261 for(
int i = 0; i < dim; ++i) {
262 if(b.m_low[i] == b.m_high[i])
267 got_difference =
true;
270 return Contains(s, b.m_low, proper) &&
271 (got_difference ? Contains(s, b.m_high, proper) : true);
277 return Contains(b, s.m_p1, proper) && Contains(b, s.m_p2, proper);
283 Vector<dim> line = s.m_p2 - s.m_p1, offset = b.m_center - s.m_p1;
294 return Intersect(b, s.m_p1, proper);
298 if (proj >= lineSqrMag)
299 return Intersect(b, s.m_p2, proper);
301 Vector<dim> perp_part = offset - line * (proj / lineSqrMag);
303 return _LessEq(perp_part.sqrMag(), b.m_radius * b.m_radius, proper);
309 return Contains(b, s.m_p1, proper) && Contains(b, s.m_p2, proper);
315 return b.m_radius == 0 && Contains(s, b.m_center, proper);
324 Vector<dim> v1 = s1.m_p2 - s1.m_p1, v2 = s2.m_p2 - s2.m_p1,
325 deltav = s2.m_p1 - s1.m_p1;
327 CoordType v1sqr = v1.sqrMag(), v2sqr = v2.sqrMag();
328 CoordType proj12 = Dot(v1, v2), proj1delta = Dot(v1, deltav),
329 proj2delta = Dot(v2, deltav);
331 CoordType denom = v1sqr * v2sqr - proj12 * proj12;
333 if(dim > 2 && !
Equal(v2sqr * proj1delta * proj1delta +
334 v1sqr * proj2delta * proj2delta,
335 2 * proj12 * proj1delta * proj2delta +
336 deltav.sqrMag() * denom))
343 CoordType coord1 = (v2sqr * proj1delta - proj12 * proj2delta) / denom;
344 CoordType coord2 = -(v1sqr * proj2delta - proj12 * proj1delta) / denom;
346 return _LessEq(coord1, 0, proper) && _LessEq(coord1, 1, proper)
347 && _GreaterEq(coord2, 0, proper) && _GreaterEq(coord2, 1, proper);
351 return Contains(s1, s2.m_p1, proper) || Contains(s1, s2.m_p2, proper)
352 || Contains(s2, s1.m_p1, proper) || Contains(s2, s1.m_p2, proper)
354 || ((proper && s1.m_p1 != s1.m_p2)
355 && ((s1.m_p1 == s2.m_p1 && s1.m_p2 == s2.m_p2)
356 || (s1.m_p1 == s2.m_p2 && s1.m_p2 == s2.m_p1)));
363 return Contains(s1, s2.m_p1, proper) && Contains(s1, s2.m_p2, proper);
375 for(
int i = 0; i < dim; ++i) {
376 if(r.m_size[i] < 0) {
377 if(_Less(shift[i], r.m_size[i], proper) || _Greater(shift[i], 0, proper))
381 if(_Greater(shift[i], r.m_size[i], proper) || _Less(shift[i], 0, proper))
395 for(
int i = 0; i < dim; ++i)
399 return p == r.m_corner0;
410 return Contains(
AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size),
412 b.m_high - b.m_low, m), proper);
418 return Contains(b, r.boundingBox(), proper);
424 return Intersect(
AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size),
426 r.m_orient), b.m_radius), proper);
432 return Contains(
AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size),
434 r.m_orient), b.m_radius), proper);
441 r.m_orient), b.m_radius),
442 AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size), proper);
451 return Intersect(
AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size),
461 return Contains(
AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size),
472 AxisBox<dim>(r.m_corner0, r.m_corner0 + r.m_size), proper);
478 return Intersect(
RotBox<dim>(r1).rotatePoint(r2.m_orient.inverse(),
480 AxisBox<dim>(r2.m_corner0, r2.m_corner0 + r2.m_size), proper);
486 return Contains(
AxisBox<dim>(outer.m_corner0, outer.m_corner0 + outer.m_size),
487 RotBox<dim>(inner).rotatePoint(outer.m_orient.inverse(),
488 outer.m_corner0), proper);
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
Point & rotate(const RotMatrix< dim > &m, const Point &p)
Rotate about point p.
Definition point.h:146
A dim dimensional box, lying at an arbitrary angle.
Definition rotbox.h:47
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition rotmatrix.h:87
RotMatrix inverse() const
Get the inverse of the matrix.
Definition rotmatrix_funcs.h:319
A line segment embedded in dim dimensions.
Definition segment.h:46
A dim dimensional vector.
Definition vector.h:121
Generic library namespace.
Definition atlasconv.h:45
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
RotMatrix< dim > ProdInv(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2^-1
Definition rotmatrix_funcs.h:111