LSSTApplications  19.0.0-14-gb0260a2+f7b33f63ed,20.0.0+028ca7aeb5,20.0.0+578ca8d785,20.0.0+95fe209e70,20.0.0+d1f8484762,20.0.0+ec0eb203f4,20.0.0-1-g253301a+95fe209e70,20.0.0-1-g2b7511a+ce6f728470,20.0.0-1-g5b95a8c+36cabaa438,20.0.0-1-gedffbd8+08e3982e2f,20.0.0-11-gd9dafd18+ee11e5b92d,20.0.0-16-gfab17e72e+f119078cbc,20.0.0-19-gb3c8180+76b8b4580d,20.0.0-2-g4dae9ad+b9c65d2db1,20.0.0-2-g61b8584+62d102034e,20.0.0-2-gb780d76+f45b7d88f4,20.0.0-2-ged6426c+c16e0e6c56,20.0.0-2-gf072044+95fe209e70,20.0.0-2-gf1f7952+b9c65d2db1,20.0.0-22-gdf434b7+b9c65d2db1,20.0.0-23-g10eeb28+266feae6ef,20.0.0-25-g3dcad98+7edba9c73c,20.0.0-3-g1653f94+62d102034e,20.0.0-3-g4cc78c6+1c0c6df15e,20.0.0-3-g8f21e14+cae0a2a29f,20.0.0-3-gbd60e8c+eb59cfae10,20.0.0-3-gbecbe05+a2681a7a86,20.0.0-36-g96d5af2b+330d9ff9b7,20.0.0-4-g97dc21a+7edba9c73c,20.0.0-4-gb4befbc+0084b8bcb8,20.0.0-4-gfea843c+f45b7d88f4,20.0.0-5-gdfe0fee+88049eac2d,20.0.0-6-g64f541c+f45b7d88f4,20.0.0-6-g9a5b7a1+db91213b54,20.0.0-67-g32d6278+0d86c2e7cd,20.0.0-9-g4aef684+e9f4309ef0,w.2020.44
LSSTDataManagementBasePackage
Box.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2014-2015 AURA/LSST.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 
25 
26 #include "lsst/sphgeom/Box.h"
27 
28 #include <cmath>
29 #include <ostream>
30 #include <stdexcept>
31 
32 #include "lsst/sphgeom/Box3d.h"
33 #include "lsst/sphgeom/Circle.h"
35 #include "lsst/sphgeom/Ellipse.h"
36 #include "lsst/sphgeom/codec.h"
37 #include "lsst/sphgeom/utils.h"
38 
39 
40 namespace lsst {
41 namespace sphgeom {
42 
44  if (r <= Angle(0.0)) {
45  return NormalizedAngle(0.0);
46  }
47  // If a circle centered at the given latitude contains a pole, then
48  // its bounding box contains all possible longitudes.
49  if (abs(lat) + r >= Angle(0.5 * PI)) {
50  return NormalizedAngle(PI);
51  }
52  // Now, consider the circle with opening angle r > 0 centered at (0,δ)
53  // with r < π/2 and |δ| ≠ π/2. The circle center vector in ℝ³ is
54  // c = (cos δ, 0, sin δ). Its bounding box spans longitudes [-α,α], where
55  // α is the desired half-width. The plane corresponding to longitude α has
56  // normal vector (-sin α, cos α, 0) and is tangent to the circle at point
57  // p. The great circle segment between the center of the circle and the
58  // plane normal passes through p and has arc length π/2 + r, so that
59  //
60  // (cos δ, 0, sin δ) · (-sin α, cos α, 0) = cos (π/2 + r)
61  //
62  // Solving for α gives
63  //
64  // α = arcsin (sin r / cos δ)
65  //
66  // In the actual computation, there is an absolute value and an explicit
67  // arcsin domain check to cope with rounding errors. An alternate way to
68  // compute this is:
69  //
70  // α = arctan (sin r / √(cos(δ - r) cos(δ + r)))
71  double s = std::fabs(sin(r) / cos(lat));
72  if (s >= 1.0) {
73  return NormalizedAngle(0.5 * PI);
74  }
75  return NormalizedAngle(std::asin(s));
76 }
77 
79  // The basic idea is to compute the union of the bounding boxes for all
80  // circles of opening angle r with centers inside this box.
81  //
82  // The bounding box for a circle of opening angle r with center latitude
83  // |δ| ≤ π/2 - r has height 2r.
84  //
85  // Given fixed r, the width of the bounding box for the circle centered at
86  // latitude δ grows monotonically with |δ| - for justification, see the
87  // derivation in halfWidthForCircle(). The maximum width is therefore
88  // attained when the circle is centered at one of the latitude angle
89  // boundaries of this box. If max(|δ|) ≥ π/2 - r, it is 2π.
90  //
91  // Dilating the longitude interval of this box by the maximum width and
92  // the latitude interval by r gives the desired result.
93  if (isEmpty() || isFull() || r <= Angle(0.0)) {
94  return *this;
95  }
96  Angle maxAbsLatitude = std::max(abs(_lat.getA()), abs(_lat.getB()));
97  NormalizedAngle w = halfWidthForCircle(r, maxAbsLatitude);
98  return dilateBy(w, r);
99 }
100 
102  if (isEmpty() || isFull()) {
103  return *this;
104  }
105  _lon.dilateBy(w);
106  if (!h.isNan()) {
107  Angle a = (_lat.getA() > Angle(-0.5 * PI)) ? _lat.getA() - h : _lat.getA();
108  Angle b = (_lat.getB() < Angle(0.5 * PI)) ? _lat.getB() + h : _lat.getB();
109  _lat = AngleInterval(a, b);
110  }
111  _enforceInvariants();
112  return *this;
113 }
114 
115 double Box::getArea() const {
116  if (isEmpty()) {
117  return 0.0;
118  }
119  // Given a, b ∈ [-π/2, π/2] and a std::sin implementation that is not
120  // correctly rounded, b > a does not imply that std::sin(b) > std::sin(a).
121  // To avoid potentially returning a negative area, defensively take an
122  // absolute value.
123  double dz = sin(_lat.getB()) - sin(_lat.getA());
124  return std::fabs(_lon.getSize().asRadians() * dz);
125 }
126 
128  if (isEmpty()) {
129  return Box3d();
130  }
131  if (isFull()) {
132  return Box3d::aroundUnitSphere();
133  }
134  double slata = sin(_lat.getA()), clata = cos(_lat.getA());
135  double slatb = sin(_lat.getB()), clatb = cos(_lat.getB());
136  double slona = sin(_lon.getA()), clona = cos(_lon.getA());
137  double slonb = sin(_lon.getB()), clonb = cos(_lon.getB());
138  // Compute the minimum/maximum x/y values of the box vertices.
139  double xmin = std::min(std::min(clona * clata, clonb * clata),
140  std::min(clona * clatb, clonb * clatb)) - 2.5 * EPSILON;
141  double xmax = std::max(std::max(clona * clata, clonb * clata),
142  std::max(clona * clatb, clonb * clatb)) + 2.5 * EPSILON;
143  double ymin = std::min(std::min(slona * clata, slonb * clata),
144  std::min(slona * clatb, slonb * clatb)) - 2.5 * EPSILON;
145  double ymax = std::max(std::max(slona * clata, slonb * clata),
146  std::max(slona * clatb, slonb * clatb)) + 2.5 * EPSILON;
147  // Compute the maximum latitude cosine of points in the box.
148  double mlc;
149  if (_lat.contains(Angle(0.0))) {
150  mlc = 1.0;
151  // The box intersects the equator - the x or y extrema of the box may be
152  // at the intersection of the box edge meridians with the equator.
153  xmin = std::min(xmin, std::min(clona, clonb) - EPSILON);
154  xmax = std::max(xmax, std::max(clona, clonb) + EPSILON);
155  ymin = std::min(ymin, std::min(slona, slonb) - EPSILON);
156  ymax = std::max(ymax, std::max(slona, slonb) + EPSILON);
157  } else {
158  // Note that clata and clatb are positive.
159  mlc = std::max(clata, clatb) + EPSILON;
160  }
161  // Check for extrema on the box edges parallel to the equator.
162  if (_lon.contains(NormalizedAngle(0.0))) {
163  xmax = std::max(xmax, mlc);
164  }
165  if (_lon.contains(NormalizedAngle(0.5 * PI))) {
166  ymax = std::max(ymax, mlc);
167  }
168  if (_lon.contains(NormalizedAngle(PI))) {
169  xmin = std::min(xmin, -mlc);
170  }
171  if (_lon.contains(NormalizedAngle(1.5 * PI))) {
172  ymin = std::min(ymin, -mlc);
173  }
174  // Clamp x/y extrema to [-1, 1]
175  xmin = std::max(-1.0, xmin);
176  xmax = std::min(1.0, xmax);
177  ymin = std::max(-1.0, ymin);
178  ymax = std::min(1.0, ymax);
179  // Compute z extrema.
180  double zmin = std::max(-1.0, slata - EPSILON);
181  double zmax = std::min(1.0, slatb + EPSILON);
182  return Box3d(Interval1d(xmin, xmax),
183  Interval1d(ymin, ymax),
184  Interval1d(zmin, zmax));
185 }
186 
188  if (isEmpty()) {
189  return Circle::empty();
190  }
191  if (isFull()) {
192  return Circle::full();
193  }
195  // The minimal bounding circle center p lies on the meridian bisecting
196  // this box. Let δ₁ and δ₂ be the minimum and maximum box latitudes.
197  if (w.asRadians() <= PI) {
198  UnitVector3d p;
199  UnitVector3d boxVerts[4] = {
200  UnitVector3d(_lon.getA(), _lat.getA()),
201  UnitVector3d(_lon.getA(), _lat.getB()),
202  UnitVector3d(_lon.getB(), _lat.getA()),
203  UnitVector3d(_lon.getB(), _lat.getB())
204  };
205  // We take advantage of rotational symmetry to fix the bisecting
206  // meridian at a longitude of zero. The box vertices then have
207  // coordinates (±w/2, δ₁), (±w/2, δ₂), and p = (0, ϕ). Converting
208  // to Cartesian coordinates gives p = (cos ϕ, 0, sin ϕ), and box
209  // vertices at (cos w/2 cos δ₁, ±sin w/2 cos δ₁, sin δ₁) and
210  // (cos w/2 cos δ₂, ±sin w/2 cos δ₂, sin δ₂).
211  //
212  // The point p₁ on the meridian that has minimum angular separation
213  // to the vertices with latitude δ₁ lies on the plane they define.
214  // The sum of the two vertex vectors is on that plane and on the plane
215  // containing the meridian. Normalizing to obtain p₁, we have
216  //
217  // (cos ϕ₁, 0, sin ϕ₁) =
218  // λ ((cos w/2 cos δ₁, sin w/2 cos δ₁, sin δ₁) +
219  // (cos w/2 cos δ₁, -sin w/2 cos δ₁, sin δ₁))
220  //
221  // for some scaling factor λ. Simplifying, we get:
222  //
223  // cos ϕ₁ = λ cos w/2 cos δ₁
224  // sin ϕ₁ = λ sin δ₁
225  //
226  // so that
227  //
228  // tan ϕ₁ = sec w/2 tan δ₁
229  //
230  // Similarly, the point p₂ on the meridian that has minimum angular
231  // separation to the vertices with latitude δ₂ satisfies:
232  //
233  // tan ϕ₂ = sec w/2 tan δ₂
234  //
235  // where ϕ₁ ≤ ϕ₂ (since δ₁ ≤ δ₂). Finally, consider the point p₃
236  // separated from each box vertex by the same angle. The dot
237  // products of p₃ with the box vertices are all identical, so
238  //
239  // cos ϕ₃ cos w/2 cos δ₁ + sin ϕ₃ sin δ₁ =
240  // cos ϕ₃ cos w/2 cos δ₂ + sin ϕ₃ sin δ₂
241  //
242  // Rearranging gives:
243  //
244  // tan ϕ₃ = - cos w/2 (cos δ₁ - cos δ₂)/(sin δ₁ - sin δ₂)
245  //
246  // which can be simplified further using a tangent half-angle identity,
247  // yielding:
248  //
249  // tan ϕ₃ = cos w/2 tan (δ₁ + δ₂)/2
250  //
251  // Consider now the function f₁(ϕ) that gives the angular separation
252  // between p with latitude ϕ and the vertices at latitude δ₁. It has
253  // a line of symmetry at ϕ = ϕ₁, and increases monotonically with
254  // |ϕ - ϕ₁|. Similarly, f₂(ϕ) has a minimum at ϕ₂ and increases
255  // monotonically with |ϕ - ϕ₂|. The two functions cross at ϕ₃. The
256  // opening angle of the bounding circle centered at latitude ϕ is
257  // given by g = max(f₁, f₂), which we seek to minimize.
258  //
259  // If ϕ₁ ≤ ϕ₃ ≤ ϕ₂, then g is minimized at ϕ = ϕ₃. Otherwise, it
260  // is minimized at either ϕ₁ or ϕ₂.
261  double phi1, phi2, phi3;
262  double c = cos(0.5 * w);
263  if (c == 0.0) {
264  // This code should never execute. If it does, the implementation
265  // of std::cos is broken.
266  phi1 = ::copysign(0.5 * PI, _lat.getA().asRadians());
267  phi2 = ::copysign(0.5 * PI, _lat.getB().asRadians());
268  phi3 = 0.0;
269  } else {
270  phi1 = std::atan(tan(_lat.getA()) / c);
271  phi2 = std::atan(tan(_lat.getB()) / c);
272  phi3 = std::atan(c * tan(_lat.getCenter()));
273  }
274  if (phi1 <= phi3 && phi3 <= phi2) {
275  p = UnitVector3d(_lon.getCenter(), Angle(phi3));
276  } else {
277  UnitVector3d p1 = UnitVector3d(_lon.getCenter(), Angle(phi1));
278  UnitVector3d p2 = UnitVector3d(_lon.getCenter(), Angle(phi2));
279  if (p1.dot(boxVerts[0]) > p2.dot(boxVerts[1])) {
280  p = p2;
281  } else {
282  p = p1;
283  }
284  }
285  // Compute the maximum squared chord length between p and the box
286  // vertices, so that each one is guaranteed to lie in the bounding
287  // circle, regardless of numerical error in the above.
288  double cl2 = (p - boxVerts[0]).getSquaredNorm();
289  for (int i = 1; i < 4; ++i) {
290  cl2 = std::max(cl2, (p - boxVerts[i]).getSquaredNorm());
291  }
292  // Add double the maximum squared-chord-length error, so that the
293  // bounding circle we return also reliably CONTAINS this box.
294  return Circle(p, cl2 + 2.0 * MAX_SQUARED_CHORD_LENGTH_ERROR);
295  }
296  // The box spans more than π radians in longitude. First, pick the smaller
297  // of the bounding circles centered at the north and south pole.
298  Angle r;
299  UnitVector3d v;
300  if (abs(_lat.getA()) <= abs(_lat.getB())) {
301  v = UnitVector3d::Z();
302  r = Angle(0.5 * PI) - _lat.getA();
303  } else {
304  v = -UnitVector3d::Z();
305  r = _lat.getB() + Angle(0.5 * PI);
306  }
307  // If the box does not span all longitude angles, we also consider the
308  // equatorial bounding circle with center longitude equal to the longitude
309  // of the box center. The smaller of the polar and equatorial bounding
310  // circles is returned.
311  if (!_lon.isFull() && 0.5 * w < r) {
312  r = 0.5 * w;
313  v = UnitVector3d(_lon.getCenter(), Angle(0.0));
314  }
315  return Circle(v, r + 4.0 * Angle(MAX_ASIN_ERROR));
316 }
317 
318 Relationship Box::relate(Circle const & c) const {
319  if (isEmpty()) {
320  if (c.isEmpty()) {
321  return CONTAINS | DISJOINT | WITHIN;
322  }
323  return DISJOINT | WITHIN;
324  } else if (c.isEmpty()) {
325  return CONTAINS | DISJOINT;
326  }
327  if (isFull()) {
328  if (c.isFull()) {
329  return CONTAINS | WITHIN;
330  }
331  return CONTAINS;
332  } else if (c.isFull()) {
333  return WITHIN;
334  }
335  // Neither region is empty or full. We now determine whether or not the
336  // circle and box boundaries intersect.
337  //
338  // If the box vertices are not all inside or all outside of c, then the
339  // boundaries cross.
340  LonLat vertLonLat[4] = {
341  LonLat(_lon.getA(), _lat.getA()),
342  LonLat(_lon.getA(), _lat.getB()),
343  LonLat(_lon.getB(), _lat.getA()),
344  LonLat(_lon.getB(), _lat.getB())
345  };
346  UnitVector3d verts[4];
347  bool inside = false;
348  for (int i = 0; i < 4; ++i) {
349  verts[i] = UnitVector3d(vertLonLat[i]);
350  double d = (verts[i] - c.getCenter()).getSquaredNorm();
351  if (std::fabs(d - c.getSquaredChordLength()) <
353  // A box vertex is close to the circle boundary.
354  return INTERSECTS;
355  }
356  bool b = d < c.getSquaredChordLength();
357  if (i == 0) {
358  inside = b;
359  } else if (inside != b) {
360  // There are box vertices both inside and outside of c.
361  return INTERSECTS;
362  }
363  }
364  UnitVector3d norms[2] = {
367  };
368  if (inside) {
369  // All box vertices are inside c. Look for points in the box edge
370  // interiors that are outside c.
371  for (int i = 0; i < 2; ++i) {
372  double d = getMaxSquaredChordLength(
373  c.getCenter(), verts[2 * i + 1], verts[2 * i], norms[i]);
374  if (d > c.getSquaredChordLength() -
376  return INTERSECTS;
377  }
378  }
379  LonLat cc(-c.getCenter());
380  if (_lon.contains(cc.getLon())) {
381  // The points furthest from the center of c on the small circles
382  // defined by the box edges with constant latitude are in the box
383  // edge interiors. Find the largest squared chord length to either.
384  Angle a = std::min(getMinAngleToCircle(cc.getLat(), _lat.getA()),
385  getMinAngleToCircle(cc.getLat(), _lat.getB()));
386  double d = Circle::squaredChordLengthFor(Angle(PI) - a);
387  if (d > c.getSquaredChordLength() -
389  return INTERSECTS;
390  }
391  }
392  // The box boundary is completely inside c. However, the box is not
393  // necessarily within c: consider a circle with opening angle equal to
394  // π - ε. If a box contains the complement of such a circle, then
395  // intersecting it with that circle will punch a hole in the box. In
396  // this case each region contains the boundary of the other, but
397  // neither region contains the other.
398  //
399  // To handle this case, check that the box does not contain the
400  // complement of c - since the boundaries do not intersect, this is the
401  // case iff the box contains the center of the complement of c.
402  if (contains(cc)) {
403  return INTERSECTS;
404  }
405  return WITHIN;
406  }
407  // All box vertices are outside c. Look for points in the box edge
408  // interiors that are inside c.
409  for (int i = 0; i < 2; ++i) {
410  double d = getMinSquaredChordLength(
411  c.getCenter(), verts[2 * i + 1], verts[2 * i], norms[i]);
413  return INTERSECTS;
414  }
415  }
416  LonLat cc(c.getCenter());
417  if (_lon.contains(cc.getLon())) {
418  // The points closest to the center of c on the small circles
419  // defined by the box edges with constant latitude are in the box
420  // edge interiors. Find the smallest squared chord length to either.
421  Angle a = std::min(getMinAngleToCircle(cc.getLat(), _lat.getA()),
422  getMinAngleToCircle(cc.getLat(), _lat.getB()));
423  double d = Circle::squaredChordLengthFor(a);
425  return INTERSECTS;
426  }
427  }
428  // The box boundary is completely outside of c. If the box contains the
429  // circle center, then the box contains c. Otherwise, the box and circle
430  // are disjoint.
431  if (contains(cc)) {
432  return CONTAINS;
433  }
434  return DISJOINT;
435 }
436 
438  // ConvexPolygon-Box relations are implemented by ConvexPolygon.
439  return invert(p.relate(*this));
440 }
441 
442 Relationship Box::relate(Ellipse const & e) const {
443  // Ellipse-Box relations are implemented by Ellipse.
444  return invert(e.relate(*this));
445 }
446 
448  std::vector<uint8_t> buffer;
449  uint8_t tc = TYPE_CODE;
450  buffer.reserve(ENCODED_SIZE);
451  buffer.push_back(tc);
452  encodeDouble(_lon.getA().asRadians(), buffer);
453  encodeDouble(_lon.getB().asRadians(), buffer);
454  encodeDouble(_lat.getA().asRadians(), buffer);
455  encodeDouble(_lat.getB().asRadians(), buffer);
456  return buffer;
457 }
458 
459 std::unique_ptr<Box> Box::decode(uint8_t const * buffer, size_t n) {
460  if (buffer == nullptr || n != ENCODED_SIZE || *buffer != TYPE_CODE) {
461  throw std::runtime_error("Byte-string is not an encoded Box");
462  }
463  std::unique_ptr<Box> box(new Box);
464  ++buffer;
465  double a = decodeDouble(buffer); buffer += 8;
466  double b = decodeDouble(buffer); buffer += 8;
468  a = decodeDouble(buffer); buffer += 8;
469  b = decodeDouble(buffer); buffer += 8;
470  box->_lat = AngleInterval::fromRadians(a, b);
471  box->_enforceInvariants();
472  return box;
473 }
474 
476  return os << "{\"Box\": [" << b.getLon() << ", " << b.getLat() << "]}";
477 }
478 
479 }} // namespace lsst::sphgeom
lsst::sphgeom::Interval::getCenter
Scalar getCenter() const
getCenter returns the center of this interval.
Definition: Interval.h:89
lsst::sphgeom::NormalizedAngle::asRadians
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition: NormalizedAngle.h:128
lsst::sphgeom::NormalizedAngleInterval::getCenter
NormalizedAngle getCenter() const
getCenter returns the center of this interval.
Definition: NormalizedAngleInterval.h:139
std::bitset
STL class.
lsst::sphgeom::NormalizedAngleInterval::fromRadians
static NormalizedAngleInterval fromRadians(double a, double b)
Definition: NormalizedAngleInterval.h:65
lsst::sphgeom::Circle::isEmpty
bool isEmpty() const
Definition: Circle.h:109
lsst::sphgeom::NormalizedAngleInterval::isFull
bool isFull() const
isFull returns true if this interval contains all normalized angles.
Definition: NormalizedAngleInterval.h:129
Box3d.h
This file declares a class for representing axis-aligned bounding boxes in ℝ³.
lsst::sphgeom::sin
double sin(Angle const &a)
Definition: Angle.h:102
lsst::sphgeom::PI
constexpr double PI
Definition: constants.h:36
std::fabs
T fabs(T... args)
xmax
int xmax
Definition: SpanSet.cc:49
lsst::sphgeom::Circle::squaredChordLengthFor
static double squaredChordLengthFor(Angle openingAngle)
squaredChordLengthFor computes and returns the squared chord length between points in S² that are sep...
Definition: Circle.cc:41
std::vector::reserve
T reserve(T... args)
lsst::sphgeom::Angle::asRadians
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition: Angle.h:85
std::asin
T asin(T... args)
lsst::sphgeom::Angle::isNan
bool isNan() const
isNan returns true if the angle value is NaN.
Definition: Angle.h:91
std::vector
STL class.
lsst::sphgeom::LonLat
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition: LonLat.h:48
lsst::sphgeom::abs
Angle abs(Angle const &a)
Definition: Angle.h:106
lsst::sphgeom::Box::isFull
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition: Box.h:155
lsst::sphgeom::Box
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition: Box.h:54
lsst::sphgeom::Circle::full
static Circle full()
Definition: Circle.h:52
lsst::sphgeom::UnitVector3d::dot
double dot(Vector3d const &v) const
dot returns the inner product of this unit vector and v.
Definition: UnitVector3d.h:152
lsst::sphgeom::Box::relate
Relationship relate(LonLat const &p) const
Definition: Box.h:297
Ellipse.h
This file declares a class for representing elliptical regions on the unit sphere.
lsst::sphgeom::Box::isEmpty
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
codec.h
This file contains simple helper functions for encoding and decoding primitive types to/from byte str...
lsst::sphgeom::Interval1d
Interval1d represents closed intervals of ℝ.
Definition: Interval1d.h:39
Circle.h
This file declares a class for representing circular regions on the unit sphere.
lsst::sphgeom::Box3d
Box3d represents a box in ℝ³.
Definition: Box3d.h:42
std::vector::push_back
T push_back(T... args)
lsst::sphgeom::Box::getWidth
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition: Box.h:165
lsst::sphgeom::NormalizedAngleInterval::dilateBy
NormalizedAngleInterval & dilateBy(Angle x)
Definition: NormalizedAngleInterval.h:253
lsst::afw::table::Angle
lsst::geom::Angle Angle
Definition: misc.h:33
lsst::sphgeom::UnitVector3d
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
Definition: UnitVector3d.h:55
lsst::sphgeom::ConvexPolygon
ConvexPolygon is a closed convex polygon on the unit sphere.
Definition: ConvexPolygon.h:57
lsst::sphgeom::Interval::getA
Scalar getA() const
getA returns the lower endpoint of this interval.
Definition: Interval.h:76
lsst::sphgeom::Box::getBoundingCircle
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition: Box.cc:187
Box.h
This file declares a class for representing longitude/latitude angle boxes on the unit sphere.
std::ostream
STL class.
lsst::sphgeom::Box::getArea
double getArea() const
getArea returns the area of this box in steradians.
Definition: Box.cc:115
lsst::sphgeom::Box::halfWidthForCircle
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at...
Definition: Box.cc:43
lsst::sphgeom::Ellipse
Ellipse is an elliptical region on the sphere.
Definition: Ellipse.h:169
lsst::sphgeom::tan
double tan(Angle const &a)
Definition: Angle.h:104
lsst::sphgeom::Circle::getSquaredChordLength
double getSquaredChordLength() const
getSquaredChordLength returns the squared length of chords between the circle center and points on th...
Definition: Circle.h:123
lsst::sphgeom::Interval::getB
Scalar getB() const
getB returns the upper endpoint of this interval.
Definition: Interval.h:80
lsst::sphgeom::Interval::contains
bool contains(Scalar x) const
Definition: Interval.h:98
std::atan
T atan(T... args)
lsst::sphgeom::MAX_SQUARED_CHORD_LENGTH_ERROR
constexpr double MAX_SQUARED_CHORD_LENGTH_ERROR
Definition: constants.h:50
lsst::sphgeom::getMinAngleToCircle
Angle getMinAngleToCircle(Angle x, Angle c)
getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the poin...
Definition: utils.h:62
lsst::sphgeom::LonLat::getLat
Angle getLat() const
Definition: LonLat.h:90
lsst::sphgeom::Box::dilateBy
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition: Box.cc:78
std::runtime_error
STL class.
lsst::sphgeom::UnitVector3d::Z
static UnitVector3d Z()
Definition: UnitVector3d.h:101
lsst::sphgeom::getMaxSquaredChordLength
double getMaxSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the...
Definition: utils.cc:58
lsst::sphgeom::Circle::empty
static Circle empty()
Definition: Circle.h:50
lsst::sphgeom::AngleInterval
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:39
b
table::Key< int > b
Definition: TransmissionCurve.cc:467
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
lsst::sphgeom::Box::contains
bool contains(LonLat const &x) const
Definition: Box.h:174
std::min
T min(T... args)
lsst::sphgeom::ConvexPolygon::relate
Relationship relate(Region const &r) const override
Definition: ConvexPolygon.h:141
lsst::sphgeom::decodeDouble
double decodeDouble(uint8_t const *buffer)
decode extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
Definition: codec.h:59
xmin
int xmin
Definition: SpanSet.cc:49
os
std::ostream * os
Definition: Schema.cc:746
lsst::sphgeom::Box3d::aroundUnitSphere
static Box3d aroundUnitSphere()
aroundUnitSphere returns a minimal Box3d containing the unit sphere.
Definition: Box3d.h:56
a
table::Key< int > a
Definition: TransmissionCurve.cc:466
lsst::sphgeom::NormalizedAngleInterval::contains
bool contains(NormalizedAngle x) const
Definition: NormalizedAngleInterval.h:150
lsst::sphgeom::NormalizedAngleInterval::getA
NormalizedAngle getA() const
getA returns the first endpoint of this interval.
Definition: NormalizedAngleInterval.h:119
lsst::sphgeom::NormalizedAngleInterval::getSize
NormalizedAngle getSize() const
getSize returns the size (length, width) of this interval.
Definition: NormalizedAngleInterval.h:145
lsst::sphgeom::Box::TYPE_CODE
static constexpr uint8_t TYPE_CODE
Definition: Box.h:56
utils.h
This file declares miscellaneous utility functions.
lsst::sphgeom::Box::encode
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
Definition: Box.cc:447
lsst::sphgeom::Circle::isFull
bool isFull() const
Definition: Circle.h:114
w
double w
Definition: CoaddPsf.cc:69
lsst::sphgeom::Box::getBoundingBox3d
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
Definition: Box.cc:127
lsst::sphgeom::Angle
Angle represents an angle in radians.
Definition: Angle.h:43
lsst::sphgeom::UnitVector3d::orthogonalTo
static UnitVector3d orthogonalTo(Vector3d const &v)
orthogonalTo returns an arbitrary unit vector that is orthogonal to v.
Definition: UnitVector3d.cc:34
lsst::sphgeom::Ellipse::relate
Relationship relate(Region const &r) const override
Definition: Ellipse.h:286
lsst::sphgeom::getMinSquaredChordLength
double getMinSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cr...
Definition: utils.cc:36
lsst::sphgeom::operator<<
std::ostream & operator<<(std::ostream &, Angle const &)
Definition: Angle.cc:34
std::max
T max(T... args)
lsst::sphgeom::Circle::getCenter
UnitVector3d const & getCenter() const
getCenter returns the center of this circle as a unit vector.
Definition: Circle.h:118
lsst::sphgeom::Circle
Circle is a circular region on the unit sphere that contains its boundary.
Definition: Circle.h:46
lsst::sphgeom::NormalizedAngle
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...
Definition: NormalizedAngle.h:41
lsst::sphgeom::MAX_ASIN_ERROR
constexpr double MAX_ASIN_ERROR
Definition: constants.h:45
std::unique_ptr
STL class.
lsst::sphgeom::cos
double cos(Angle const &a)
Definition: Angle.h:103
lsst::sphgeom::AngleInterval::fromRadians
static AngleInterval fromRadians(double x, double y)
Definition: AngleInterval.h:48
lsst::sphgeom::LonLat::getLon
NormalizedAngle getLon() const
Definition: LonLat.h:88
lsst::sphgeom::Box::decode
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition: Box.h:338
lsst::sphgeom::invert
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55
ConvexPolygon.h
This file declares a class for representing convex polygons with great circle edges on the unit spher...
lsst::sphgeom::NormalizedAngleInterval::getB
NormalizedAngle getB() const
getB returns the second endpoint of this interval.
Definition: NormalizedAngleInterval.h:122
lsst::sphgeom::encodeDouble
void encodeDouble(double item, std::vector< uint8_t > &buffer)
encode appends an IEEE double in little-endian byte order to the end of buffer.
Definition: codec.h:38
lsst::sphgeom::EPSILON
constexpr double EPSILON
Definition: constants.h:54