23 #ifndef LSST_SPHGEOM_CONVEXPOLYGONIMPL_H_
24 #define LSST_SPHGEOM_CONVEXPOLYGONIMPL_H_
47 template <
typename VertexIterator>
48 UnitVector3d centroid(VertexIterator
const begin, VertexIterator
const end) {
56 VertexIterator i = std::prev(end);
57 VertexIterator j = begin;
58 for (; j != end; i = j, ++j) {
59 Vector3d v = (*i).robustCross(*j);
60 double s = 0.5 * v.normalize();
61 double c = (*i).dot(*j);
62 double a = (s == 0.0 && c == 0.0) ? 0.0 : std::atan2(s, c);
65 return UnitVector3d(cm);
68 template <
typename VertexIterator>
69 Circle boundingCircle(VertexIterator
const begin, VertexIterator
const end) {
70 UnitVector3d c = centroid(begin, end);
73 VertexIterator i = begin;
75 for (; i != end; ++i) {
76 cl2 = std::max(cl2, (*i - c).getSquaredNorm());
80 return Circle(c, cl2 + 2.0 * MAX_SQUARED_CHORD_LENGTH_ERROR);
84 template <
typename VertexIterator>
85 Box boundingBox(VertexIterator
const begin, VertexIterator
const end) {
86 Angle
const eps(5.0e-10);
88 VertexIterator i = std::prev(end);
89 VertexIterator j = begin;
103 for (; j != end; i = j, ++j) {
105 bbox.expandTo(Box(p, eps, eps));
106 if (!haveCW || !haveCCW) {
108 haveCCW = haveCCW || (o > 0);
109 haveCW = haveCW || (o < 0);
112 Vector3d n = (*i).robustCross(*j);
120 Vector3d v(-n.x() * n.z(),
122 n.x() * n.x() + n.y() * n.y());
123 if (v != Vector3d()) {
127 double zni = i->y() * n.x() - i->x() * n.y();
128 double znj = j->y() * n.x() - j->x() * n.y();
130 if (zni > 0.0 && znj < 0.0) {
131 bbox = Box(bbox.getLon(), bbox.getLat().expandedTo(
133 }
else if (zni < 0.0 && znj > 0.0) {
134 bbox = Box(bbox.getLon(), bbox.getLat().expandedTo(
143 bbox.expandTo(northPole);
144 }
else if (!haveCCW) {
146 bbox.expandTo(southPole);
151 template <
typename VertexIterator>
152 Box3d boundingBox3d(VertexIterator
const begin, VertexIterator
const end) {
153 static double const maxError = 1.0e-14;
155 VertexIterator j = begin;
156 double emin[3] = { j->x(), j->y(), j->z() };
157 double emax[3] = { j->x(), j->y(), j->z() };
158 for (++j; j != end; ++j) {
159 for (
int i = 0; i < 3; ++i) {
160 double v = j->operator()(i);
161 emin[i] = std::min(emin[i], v);
162 emax[i] = std::max(emax[i], v);
185 VertexIterator k = begin;
186 for (; k != end; j = k, ++k) {
187 UnitVector3d n(j->robustCross(*k));
188 for (
int i = 0; i < 3; ++i) {
190 double d = std::fabs(1.0 - ni * ni);
192 Vector3d e(i == 0 ? -d : n.x() * ni,
193 i == 1 ? -d : n.y() * ni,
194 i == 2 ? -d : n.z() * ni);
198 Vector3d v = e.cross(n);
199 double vdj = v.dot(*j);
200 double vdk = v.dot(*k);
201 if (vdj >= 0.0 && vdk <= 0.0) {
202 emin[i] = std::min(emin[i], -std::sqrt(d));
204 if (vdj <= 0.0 && vdk >= 0.0) {
205 emax[i] = std::max(emax[i], std::sqrt(d));
212 bool a[3] = {
true,
true,
true };
213 bool b[3] = {
true,
true,
true };
216 for (; k != end; j = k, ++k) {
221 a[0] = a[0] && (ox <= 0);
222 b[0] = b[0] && (ox >= 0);
224 a[1] = a[1] && (oy <= 0);
225 b[1] = b[1] && (oy >= 0);
227 a[2] = a[2] && (oz <= 0);
228 b[2] = b[2] && (oz >= 0);
233 for (
int i = 0; i < 3; ++i) {
234 emin[i] = a[i] ? -1.0 : std::max(-1.0, emin[i] - maxError);
235 emax[i] = b[i] ? 1.0 : std::min(1.0, emax[i] + maxError);
237 return Box3d(Interval1d(emin[0], emax[0]),
238 Interval1d(emin[1], emax[1]),
239 Interval1d(emin[2], emax[2]));
242 template <
typename VertexIterator>
243 bool contains(VertexIterator
const begin,
244 VertexIterator
const end,
245 UnitVector3d
const & v)
247 VertexIterator i = std::prev(end);
248 VertexIterator j = begin;
249 for (; j != end; i = j, ++j) {
257 template <
typename VertexIterator>
259 VertexIterator
const end,
263 return boundingBox(begin, end).relate(b) & (DISJOINT | WITHIN);
266 template <
typename VertexIterator>
268 VertexIterator
const end,
272 return CONTAINS | DISJOINT;
281 for (VertexIterator v = begin; v != end; ++v) {
282 double d = (*v - c.getCenter()).getSquaredNorm();
283 if (std::fabs(d - c.getSquaredChordLength()) <
284 MAX_SQUARED_CHORD_LENGTH_ERROR) {
288 bool b = d < c.getSquaredChordLength();
291 }
else if (inside != b) {
299 for (VertexIterator a = std::prev(end), b = begin; b != end; a = b, ++b) {
300 Vector3d n = a->robustCross(*b);
302 if (d > c.getSquaredChordLength() -
303 MAX_SQUARED_CHORD_LENGTH_ERROR) {
311 if (contains(begin, end, -c.getCenter())) {
318 for (VertexIterator a = std::prev(end), b = begin; b != end; a = b, ++b) {
319 Vector3d n = a->robustCross(*b);
321 if (d < c.getSquaredChordLength() + MAX_SQUARED_CHORD_LENGTH_ERROR) {
328 if (contains(begin, end, c.getCenter())) {
334 template <
typename VertexIterator1,
335 typename VertexIterator2>
337 VertexIterator1
const end1,
338 VertexIterator2
const begin2,
339 VertexIterator2
const end2)
354 for (VertexIterator1 i = begin1; i != end1; ++i) {
355 bool b = contains(begin2, end2, *i);
359 for (VertexIterator2 j = begin2; j != end2; ++j) {
360 bool b = contains(begin1, end1, *j);
366 return (all1 ? WITHIN : INTERSECTS) | (all2 ? CONTAINS : INTERSECTS);
374 for (VertexIterator1 a = std::prev(end1), b = begin1;
375 b != end1; a = b, ++b) {
376 for (VertexIterator2 c = std::prev(end2), d = begin2;
377 d != end2; c = d, ++d) {
380 if (acd == bdc && acd != 0) {
383 if (cba == dab && cba == acd) {
393 template <
typename VertexIterator>
395 VertexIterator
const end,
396 ConvexPolygon
const & p)
398 return relate(begin, end, p.getVertices().begin(), p.getVertices().end());
401 template <
typename VertexIterator>
403 VertexIterator
const end,
406 return relate(begin, end, e.getBoundingCircle()) & (CONTAINS | DISJOINT);
This file declares a class for representing axis-aligned bounding boxes in ℝ³.
This file declares a class for representing longitude/latitude angle boxes on the unit sphere.
This file declares a class for representing circular regions on the unit sphere.
This file declares a class for representing elliptical regions on the unit sphere.
static NormalizedAngleInterval allLongitudes()
Definition: Box.h:81
static Angle latitudeOf(Vector3d const &v)
Definition: LonLat.cc:37
This file declares functions for orienting points on the sphere.
int orientationZ(UnitVector3d const &b, UnitVector3d const &c)
orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c).
Definition: orientation.cc:237
int orientation(UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
Definition: orientation.cc:135
int orientationX(UnitVector3d const &b, UnitVector3d const &c)
orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c).
Definition: orientation.cc:227
int orientationY(UnitVector3d const &b, UnitVector3d const &c)
orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c).
Definition: orientation.cc:232
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition: Relationship.h:35
This file declares miscellaneous utility functions.
double getMaxSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Definition: utils.cc:58
double getMinSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Definition: utils.cc:36