30#ifndef LSST_SPHGEOM_CONVEXPOLYGONIMPL_H_
31#define LSST_SPHGEOM_CONVEXPOLYGONIMPL_H_
54template <
typename VertexIterator>
55UnitVector3d centroid(VertexIterator
const begin, VertexIterator
const end) {
63 VertexIterator i = std::prev(end);
64 VertexIterator j = begin;
65 for (; j != end; i = j, ++j) {
66 Vector3d v = (*i).robustCross(*j);
67 double s = 0.5 * v.normalize();
68 double c = (*i).dot(*j);
69 double a = (s == 0.0 && c == 0.0) ? 0.0 : std::atan2(s, c);
72 return UnitVector3d(cm);
75template <
typename VertexIterator>
76Circle boundingCircle(VertexIterator
const begin, VertexIterator
const end) {
77 UnitVector3d c = centroid(begin, end);
80 VertexIterator i = begin;
82 for (; i != end; ++i) {
83 cl2 = std::max(cl2, (*i - c).getSquaredNorm());
87 return Circle(c, cl2 + 2.0 * MAX_SQUARED_CHORD_LENGTH_ERROR);
91template <
typename VertexIterator>
92Box boundingBox(VertexIterator
const begin, VertexIterator
const end) {
93 Angle
const eps(5.0e-10);
95 VertexIterator i = std::prev(end);
96 VertexIterator j = begin;
110 for (; j != end; i = j, ++j) {
112 bbox.expandTo(Box(p, eps, eps));
113 if (!haveCW || !haveCCW) {
115 haveCCW = haveCCW || (o > 0);
116 haveCW = haveCW || (o < 0);
119 Vector3d n = (*i).robustCross(*j);
127 Vector3d v(-n.x() * n.z(),
129 n.x() * n.x() + n.y() * n.y());
130 if (v != Vector3d()) {
134 double zni = i->y() * n.x() - i->x() * n.y();
135 double znj = j->y() * n.x() - j->x() * n.y();
137 if (zni > 0.0 && znj < 0.0) {
138 bbox = Box(bbox.getLon(), bbox.getLat().expandedTo(
140 }
else if (zni < 0.0 && znj > 0.0) {
141 bbox = Box(bbox.getLon(), bbox.getLat().expandedTo(
150 bbox.expandTo(northPole);
151 }
else if (!haveCCW) {
153 bbox.expandTo(southPole);
158template <
typename VertexIterator>
159Box3d boundingBox3d(VertexIterator
const begin, VertexIterator
const end) {
160 static double const maxError = 1.0e-14;
162 VertexIterator j = begin;
163 double emin[3] = { j->x(), j->y(), j->z() };
164 double emax[3] = { j->x(), j->y(), j->z() };
165 for (++j; j != end; ++j) {
166 for (
int i = 0; i < 3; ++i) {
167 double v = j->operator()(i);
168 emin[i] = std::min(emin[i], v);
169 emax[i] = std::max(emax[i], v);
192 VertexIterator k = begin;
193 for (; k != end; j = k, ++k) {
194 UnitVector3d n(j->robustCross(*k));
195 for (
int i = 0; i < 3; ++i) {
197 double d = std::fabs(1.0 - ni * ni);
199 Vector3d e(i == 0 ? -d : n.x() * ni,
200 i == 1 ? -d : n.y() * ni,
201 i == 2 ? -d : n.z() * ni);
205 Vector3d v = e.cross(n);
206 double vdj = v.dot(*j);
207 double vdk = v.dot(*k);
208 if (vdj >= 0.0 && vdk <= 0.0) {
209 emin[i] = std::min(emin[i], -std::sqrt(d));
211 if (vdj <= 0.0 && vdk >= 0.0) {
212 emax[i] = std::max(emax[i], std::sqrt(d));
219 bool a[3] = {
true,
true,
true };
220 bool b[3] = {
true,
true,
true };
223 for (; k != end; j = k, ++k) {
228 a[0] = a[0] && (ox <= 0);
229 b[0] = b[0] && (ox >= 0);
231 a[1] = a[1] && (oy <= 0);
232 b[1] = b[1] && (oy >= 0);
234 a[2] = a[2] && (oz <= 0);
235 b[2] = b[2] && (oz >= 0);
240 for (
int i = 0; i < 3; ++i) {
241 emin[i] = a[i] ? -1.0 : std::max(-1.0, emin[i] - maxError);
242 emax[i] = b[i] ? 1.0 : std::min(1.0, emax[i] + maxError);
244 return Box3d(Interval1d(emin[0], emax[0]),
245 Interval1d(emin[1], emax[1]),
246 Interval1d(emin[2], emax[2]));
249template <
typename VertexIterator>
250bool contains(VertexIterator
const begin,
251 VertexIterator
const end,
252 UnitVector3d
const & v)
254 VertexIterator i = std::prev(end);
255 VertexIterator j = begin;
256 for (; j != end; i = j, ++j) {
264template <
typename VertexIterator>
266 VertexIterator
const end,
270 return boundingBox(begin, end).relate(b) & (DISJOINT | WITHIN);
273template <
typename VertexIterator>
275 VertexIterator
const end,
279 return CONTAINS | DISJOINT;
288 for (VertexIterator v = begin; v != end; ++v) {
289 double d = (*v - c.getCenter()).getSquaredNorm();
290 if (std::fabs(d - c.getSquaredChordLength()) <
291 MAX_SQUARED_CHORD_LENGTH_ERROR) {
295 bool b = d < c.getSquaredChordLength();
298 }
else if (inside != b) {
306 for (VertexIterator a = std::prev(end), b = begin; b != end; a = b, ++b) {
307 Vector3d n = a->robustCross(*b);
309 if (d > c.getSquaredChordLength() -
310 MAX_SQUARED_CHORD_LENGTH_ERROR) {
318 if (contains(begin, end, -c.getCenter())) {
325 for (VertexIterator a = std::prev(end), b = begin; b != end; a = b, ++b) {
326 Vector3d n = a->robustCross(*b);
328 if (d < c.getSquaredChordLength() + MAX_SQUARED_CHORD_LENGTH_ERROR) {
335 if (contains(begin, end, c.getCenter())) {
341template <
typename VertexIterator1,
342 typename VertexIterator2>
344 VertexIterator1
const end1,
345 VertexIterator2
const begin2,
346 VertexIterator2
const end2)
361 for (VertexIterator1 i = begin1; i != end1; ++i) {
362 bool b = contains(begin2, end2, *i);
366 for (VertexIterator2 j = begin2; j != end2; ++j) {
367 bool b = contains(begin1, end1, *j);
373 return (all1 ? WITHIN : INTERSECTS) | (all2 ? CONTAINS : INTERSECTS);
381 for (VertexIterator1 a = std::prev(end1), b = begin1;
382 b != end1; a = b, ++b) {
383 for (VertexIterator2 c = std::prev(end2), d = begin2;
384 d != end2; c = d, ++d) {
387 if (acd == bdc && acd != 0) {
390 if (cba == dab && cba == acd) {
400template <
typename VertexIterator>
402 VertexIterator
const end,
403 ConvexPolygon
const & p)
405 return relate(begin, end, p.getVertices().begin(), p.getVertices().end());
408template <
typename VertexIterator>
410 VertexIterator
const end,
413 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:88
static Angle latitudeOf(Vector3d const &v)
Definition LonLat.cc:44
int orientationZ(UnitVector3d const &b, UnitVector3d const &c)
orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c).
Definition orientation.cc:244
double getMaxSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Definition utils.cc:65
double getMinSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Definition utils.cc:43
int orientation(UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
Definition orientation.cc:142
int orientationX(UnitVector3d const &b, UnitVector3d const &c)
orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c).
Definition orientation.cc:234
int orientationY(UnitVector3d const &b, UnitVector3d const &c)
orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c).
Definition orientation.cc:239
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition Relationship.h:42
This file declares functions for orienting points on the sphere.
This file declares miscellaneous utility functions.