LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
lsst.geom.geometry.SphericalBox Class Reference
Inheritance diagram for lsst.geom.geometry.SphericalBox:
lsst.geom.geometry.SphericalRegion

Public Member Functions

def __init__
 
def wraps
 
def getBoundingBox
 
def getMin
 
def getMax
 
def getThetaExtent
 
def getCenter
 
def isEmpty
 
def isFull
 
def containsPoint
 
def contains
 
def intersects
 
def extend
 
def shrink
 
def setEmpty
 
def setFull
 
def __repr__
 
def __eq__
 

Static Public Member Functions

def edge
 

Public Attributes

 min
 
 max
 

Detailed Description

A spherical coordinate space bounding box.

This is similar to a bounding box in cartesian space in that
it is specified by a pair of points; however, a spherical box may
correspond to the entire unit-sphere, a spherical cap, a lune or
the traditional rectangle. Additionally, spherical boxes can span
the 0/360 degree longitude angle discontinuity.

Note that points falling exactly on spherical box edges are
considered to be inside (contained by) the box.

Definition at line 347 of file geometry.py.

Constructor & Destructor Documentation

def lsst.geom.geometry.SphericalBox.__init__ (   self,
  args 
)
Creates a new spherical box. If no arguments are supplied, then
an empty box is created. If the arguments consist of a single
SphericalRegion, then a copy of its bounding box is created.
Otherwise, the arguments must consist of a pair of 2 (spherical)
or 3 (cartesian 3-vector) element coordinate tuples/lists that
specify the minimum/maximum longitude/latitude angles for the box.
Latitude angles must be within [-90, 90] degrees, and the minimum
latitude angle must be less than or equal to the maximum. If both
minimum and maximum longitude angles lie in the range [0.0, 360.0],
then the maximum can be less than the minimum. For example, a box
with min/max longitude angles of 350/10 deg spans the longitude angle
ranges [350, 360) and [0, 10]. Otherwise, the minimum must be less
than or equal to the maximum, though values can be arbitrary. If
the two are are separated by 360 degrees or more, then the box
spans longitude angles [0, 360). Otherwise, both values are range
reduced. For example, a spherical box with min/max longitude angles
specified as 350/370 deg spans longitude angle ranges [350, 360) and
[0, 10].

Definition at line 359 of file geometry.py.

360  def __init__(self, *args):
361  """
362  Creates a new spherical box. If no arguments are supplied, then
363  an empty box is created. If the arguments consist of a single
364  SphericalRegion, then a copy of its bounding box is created.
365  Otherwise, the arguments must consist of a pair of 2 (spherical)
366  or 3 (cartesian 3-vector) element coordinate tuples/lists that
367  specify the minimum/maximum longitude/latitude angles for the box.
368  Latitude angles must be within [-90, 90] degrees, and the minimum
369  latitude angle must be less than or equal to the maximum. If both
370  minimum and maximum longitude angles lie in the range [0.0, 360.0],
371  then the maximum can be less than the minimum. For example, a box
372  with min/max longitude angles of 350/10 deg spans the longitude angle
373  ranges [350, 360) and [0, 10]. Otherwise, the minimum must be less
374  than or equal to the maximum, though values can be arbitrary. If
375  the two are are separated by 360 degrees or more, then the box
376  spans longitude angles [0, 360). Otherwise, both values are range
377  reduced. For example, a spherical box with min/max longitude angles
378  specified as 350/370 deg spans longitude angle ranges [350, 360) and
379  [0, 10].
380  """
381  if len(args) == 0:
382  self.setEmpty()
383  return
384  elif len(args) == 1:
385  if isinstance(args[0], SphericalRegion):
386  bbox = args[0].getBoundingBox()
387  self.min = tuple(bbox.getMin())
388  self.max = tuple(bbox.getMax())
389  return
390  args = args[0]
391  if len(args) == 2:
392  self.min = sphericalCoords(args[0])
393  self.max = sphericalCoords(args[1])
394  else:
395  raise TypeError('Expecting a spherical region, 2 points, '
396  'or a tuple/list containing 2 points')
397  if self.min[1] > self.max[1]:
398  raise RuntimeError(
399  'Latitude angle minimum is greater than maximum')
400  if (self.max[0] < self.min[0] and
401  (self.max[0] < 0.0 or self.min[0] > 360.0)):
402  raise RuntimeError(
403  'Longitude angle minimum is greater than maximum')
404  # Range-reduce longitude angles
405  if self.max[0] - self.min[0] >= 360.0:
406  self.min = (0.0, self.min[1])
407  self.max = (360.0, self.max[1])
408  else:
409  self.min = (reduceTheta(self.min[0]), self.min[1])
410  self.max = (reduceTheta(self.max[0]), self.max[1])

Member Function Documentation

def lsst.geom.geometry.SphericalBox.__eq__ (   self,
  other 
)

Definition at line 707 of file geometry.py.

708  def __eq__(self, other):
709  if isinstance(other, SphericalBox):
710  if self.isEmpty() and other.isEmpty():
711  return True
712  return self.min == other.min and self.max == other.max
713  return False
def lsst.geom.geometry.SphericalBox.__repr__ (   self)
Returns a string representation of this spherical box.

Definition at line 699 of file geometry.py.

700  def __repr__(self):
701  """Returns a string representation of this spherical box.
702  """
703  if self.isEmpty():
704  return ''.join([self.__class__.__name__, '(', ')'])
705  return ''.join([self.__class__.__name__, '(',
706  repr(self.min), ', ', repr(self.max), ')'])
def lsst.geom.geometry.SphericalBox.contains (   self,
  pointOrRegion 
)
Returns True if this spherical box completely contains the given
point or spherical region. Note that the implementation is
conservative where ellipses are concerned: False may be returned
for an ellipse that is actually completely contained in this box.

Definition at line 478 of file geometry.py.

479  def contains(self, pointOrRegion):
480  """Returns True if this spherical box completely contains the given
481  point or spherical region. Note that the implementation is
482  conservative where ellipses are concerned: False may be returned
483  for an ellipse that is actually completely contained in this box.
484  """
485  if self.isEmpty():
486  return False
487  if isinstance(pointOrRegion, SphericalRegion):
488  b = pointOrRegion.getBoundingBox()
489  if b.isEmpty():
490  return False
491  if b.min[1] < self.min[1] or b.max[1] > self.max[1]:
492  return False
493  if self.wraps():
494  if b.wraps():
495  return b.min[0] >= self.min[0] and b.max[0] <= self.max[0]
496  else:
497  return b.min[0] >= self.min[0] or b.max[0] <= self.max[0]
498  else:
499  if b.wraps():
500  return self.min[0] == 0.0 and self.max[0] == 360.0
501  else:
502  return b.min[0] >= self.min[0] and b.max[0] <= self.max[0]
503  else:
504  return self.containsPoint(sphericalCoords(pointOrRegion))
def lsst.geom.geometry.SphericalBox.containsPoint (   self,
  p 
)
Returns True if this spherical box contains the given point,
which must be specified in spherical coordinates.

Definition at line 466 of file geometry.py.

467  def containsPoint(self, p):
468  """Returns True if this spherical box contains the given point,
469  which must be specified in spherical coordinates.
470  """
471  if p[1] < self.min[1] or p[1] > self.max[1]:
472  return False
473  theta = reduceTheta(p[0])
474  if self.wraps():
475  return theta >= self.min[0] or theta <= self.max[0]
476  else:
477  return theta >= self.min[0] and theta <= self.max[0]
def lsst.geom.geometry.SphericalBox.edge (   v1,
  v2,
  n 
)
static
Returns a spherical bounding box for the great circle edge
connecting v1 to v2 with plane normal n. All arguments must be
cartesian unit vectors.

Definition at line 715 of file geometry.py.

716  def edge(v1, v2, n):
717  """Returns a spherical bounding box for the great circle edge
718  connecting v1 to v2 with plane normal n. All arguments must be
719  cartesian unit vectors.
720  """
721  theta1, phi1 = sphericalCoords(v1)
722  theta2, phi2 = sphericalCoords(v2)
723  # Compute latitude angle range of the edge
724  minPhi = min(phi1, phi2)
725  maxPhi = max(phi1, phi2)
726  d = n[0] * n[0] + n[1] * n[1]
727  if abs(d) > MIN_FLOAT:
728  # compute the 2 (antipodal) latitude angle extrema of n
729  if abs(n[2]) <= SIN_MIN:
730  ex = (0.0, 0.0, -1.0)
731  else:
732  ex = (n[0] * n[2] / d, n[1] * n[2] / d, -d)
733  # check whether either extremum is inside the edge
734  if between(ex, n, v1, v2):
735  minPhi = min(minPhi, sphericalCoords(ex)[1])
736  ex = (-ex[0], -ex[1], -ex[2])
737  if between(ex, n, v1, v2):
738  maxPhi = max(maxPhi, sphericalCoords(ex)[1])
739  # Compute longitude angle range of the edge
740  if abs(n[2]) <= SIN_MIN:
741  # great circle is very close to a pole
742  d = min(abs(theta1 - theta2), abs(360.0 - theta1 + theta2))
743  if d >= 90.0 and d <= 270.0:
744  # d is closer to 180 than 0/360: edge crosses over a pole
745  minTheta = 0.0
746  maxTheta = 360.0
747  else:
748  # theta1 and theta2 are nearly identical
749  minTheta = min(theta1, theta2)
750  maxTheta = max(theta1, theta2)
751  if maxTheta - minTheta > 180.0:
752  # min/max on opposite sides of 0/360
753  # longitude angle discontinuity
754  tmp = maxTheta
755  maxTheta = minTheta
756  minTheta = tmp
757  elif n[2] > 0.0:
758  minTheta = theta1
759  maxTheta = theta2
760  else:
761  minTheta = theta2
762  maxTheta = theta1
763  # return results
764  return SphericalBox((minTheta, minPhi), (maxTheta, maxPhi))
765 
def lsst.geom.geometry.SphericalBox.extend (   self,
  pointOrRegion 
)
Extends this box to the smallest spherical box S containing
the union of this box with the specified point or spherical region.

Definition at line 534 of file geometry.py.

535  def extend(self, pointOrRegion):
536  """Extends this box to the smallest spherical box S containing
537  the union of this box with the specified point or spherical region.
538  """
539  if self == pointOrRegion:
540  return self
541  if isinstance(pointOrRegion, SphericalRegion):
542  b = pointOrRegion.getBoundingBox()
543  if b.isEmpty():
544  return self
545  elif self.isEmpty():
546  self.min = tuple(b.min)
547  self.max = tuple(b.max)
548  minPhi = min(self.min[1], b.min[1])
549  maxPhi = max(self.max[1], b.max[1])
550  minTheta = self.min[0]
551  maxTheta = self.max[0]
552  if self.wraps():
553  if b.wraps():
554  minMinRa = min(self.min[0], b.min[0])
555  maxMaxRa = max(self.max[0], b.max[0])
556  if maxMaxRa >= minMinRa:
557  minTheta = 0.0
558  maxTheta = 360.0
559  else:
560  minTheta = minMinRa
561  maxTheta = maxMaxRa
562  else:
563  if b.min[0] <= self.max[0] and b.max[0] >= self.min[0]:
564  minTheta = 0.0
565  maxTheta = 360.0
566  elif b.min[0] - self.max[0] > self.min[0] - b.max[0]:
567  minTheta = b.min[0]
568  else:
569  maxTheta = b.max[0]
570  else:
571  if b.wraps():
572  if self.min[0] <= b.max[0] and self.max[0] >= b.min[0]:
573  minTheta = 0.0
574  maxTheta = 360.0
575  elif self.min[0] - b.max[0] > b.min[0] - self.max[0]:
576  maxTheta = b.max[0]
577  else:
578  minTheta = b.min[0]
579  else:
580  if b.min[0] > self.max[0]:
581  if (360.0 - b.min[0] + self.max[0] <
582  b.max[0] - self.min[0]):
583  minTheta = b.min[0]
584  else:
585  maxTheta = b.max[0]
586  elif self.min[0] > b.max[0]:
587  if (360.0 - self.min[0] + b.max[0] <
588  self.max[0] - b.min[0]):
589  maxTheta = b.max[0]
590  else:
591  minTheta = b.min[0]
592  else:
593  minTheta = min(self.min[0], b.min[0])
594  maxTheta = max(self.max[0], b.max[0])
595  self.min = (minTheta, minPhi)
596  self.max = (maxTheta, maxPhi)
597  else:
598  p = sphericalCoords(pointOrRegion)
599  theta, phi = reduceTheta(p[0]), p[1]
600  if self.containsPoint(p):
601  return self
602  elif self.isEmpty():
603  self.min = (theta, phi)
604  self.max = (theta, phi)
605  else:
606  minPhi = min(self.min[1], phi)
607  maxPhi = max(self.max[1], phi)
608  minTheta = self.min[0]
609  maxTheta = self.max[0]
610  if self.wraps():
611  if self.min[0] - theta > theta - self.max[0]:
612  maxTheta = theta
613  else:
614  minTheta = theta
615  elif theta < self.min[0]:
616  if self.min[0] - theta <= 360.0 - self.max[0] + theta:
617  minTheta = theta
618  else:
619  maxTheta = theta
620  elif theta - self.max[0] <= 360.0 - theta + self.min[0]:
621  maxTheta = theta
622  else:
623  minTheta = theta
624  self.min = (minTheta, minPhi)
625  self.max = (maxTheta, maxPhi)
626  return self
def lsst.geom.geometry.SphericalBox.getBoundingBox (   self)
Returns a bounding box for this spherical region.

Definition at line 417 of file geometry.py.

418  def getBoundingBox(self):
419  """Returns a bounding box for this spherical region.
420  """
421  return self
def lsst.geom.geometry.SphericalBox.getCenter (   self)
Returns an 2-tuple of floats corresponding to the longitude/latitude
angles (in degrees) of the center of this spherical box.

Definition at line 442 of file geometry.py.

443  def getCenter(self):
444  """Returns an 2-tuple of floats corresponding to the longitude/latitude
445  angles (in degrees) of the center of this spherical box.
446  """
447  centerTheta = 0.5 * (self.min[0] + self.max[0])
448  centerPhi = 0.5 * (self.min[1] + self.max[1])
449  if self.wraps():
450  if centerTheta >= 180.0:
451  centerTheta -= 180.0
452  else:
453  centerTheta += 180.0
454  return (centerTheta, centerPhi)
def lsst.geom.geometry.SphericalBox.getMax (   self)
Returns the maximum longitude and latitude angles of this
spherical box as a 2-tuple of floats (in units of degrees).

Definition at line 428 of file geometry.py.

429  def getMax(self):
430  """Returns the maximum longitude and latitude angles of this
431  spherical box as a 2-tuple of floats (in units of degrees).
432  """
433  return self.max
def lsst.geom.geometry.SphericalBox.getMin (   self)
Returns the minimum longitude and latitude angles of this
spherical box as a 2-tuple of floats (in units of degrees).

Definition at line 422 of file geometry.py.

423  def getMin(self):
424  """Returns the minimum longitude and latitude angles of this
425  spherical box as a 2-tuple of floats (in units of degrees).
426  """
427  return self.min
def lsst.geom.geometry.SphericalBox.getThetaExtent (   self)
Returns the extent in longitude angle of this box.

Definition at line 434 of file geometry.py.

435  def getThetaExtent(self):
436  """Returns the extent in longitude angle of this box.
437  """
438  if self.wraps():
439  return 360.0 - self.min[0] + self.max[0]
440  else:
441  return self.max[0] - self.min[0]
def lsst.geom.geometry.SphericalBox.intersects (   self,
  pointOrRegion 
)
Returns True if this spherical box intersects the given point
or spherical region. Note that the implementation is conservative:
True may be returned for a region that does not actually intersect
this box.

Definition at line 505 of file geometry.py.

506  def intersects(self, pointOrRegion):
507  """Returns True if this spherical box intersects the given point
508  or spherical region. Note that the implementation is conservative:
509  True may be returned for a region that does not actually intersect
510  this box.
511  """
512  if self.isEmpty():
513  return False
514  if isinstance(pointOrRegion, SphericalBox):
515  b = pointOrRegion
516  if b.isEmpty():
517  return False
518  if b.min[1] > self.max[1] or b.max[1] < self.min[1]:
519  return False
520  if self.wraps():
521  if b.wraps():
522  return True
523  else:
524  return b.min[0] <= self.max[0] or b.max[0] >= self.min[0]
525  else:
526  if b.wraps():
527  return self.min[0] <= b.max[0] or self.max[0] >= b.min[0]
528  else:
529  return self.min[0] <= b.max[0] and self.max[0] >= b.min[0]
530  elif isinstance(pointOrRegion, SphericalRegion):
531  return pointOrRegion.intersects(self)
532  else:
533  return self.containsPoint(sphericalCoords(pointOrRegion))
def lsst.geom.geometry.SphericalBox.isEmpty (   self)
Returns True if this spherical box contains no points.

Definition at line 455 of file geometry.py.

456  def isEmpty(self):
457  """Returns True if this spherical box contains no points.
458  """
459  return self.min[1] > self.max[1]
def lsst.geom.geometry.SphericalBox.isFull (   self)
Returns True if this spherical box contains every point
on the unit sphere.

Definition at line 460 of file geometry.py.

461  def isFull(self):
462  """Returns True if this spherical box contains every point
463  on the unit sphere.
464  """
465  return self.min == (0.0, -90.0) and self.max == (360.0, 90.0)
def lsst.geom.geometry.SphericalBox.setEmpty (   self)
Empties this spherical box.

Definition at line 685 of file geometry.py.

686  def setEmpty(self):
687  """Empties this spherical box.
688  """
689  self.min = (0.0, 90.0)
690  self.max = (0.0, -90.0)
691  return self
def lsst.geom.geometry.SphericalBox.setFull (   self)
Expands this spherical box to fill the unit sphere.

Definition at line 692 of file geometry.py.

693  def setFull(self):
694  """Expands this spherical box to fill the unit sphere.
695  """
696  self.min = (0.0, -90.0)
697  self.max = (360.0, 90.0)
698  return self
def lsst.geom.geometry.SphericalBox.shrink (   self,
  box 
)
Shrinks this box to the smallest spherical box containing
the intersection of this box and the specified one.

Definition at line 627 of file geometry.py.

628  def shrink(self, box):
629  """Shrinks this box to the smallest spherical box containing
630  the intersection of this box and the specified one.
631  """
632  b = box
633  if not isinstance(b, SphericalBox):
634  raise TypeError('Expecting a SphericalBox object')
635  if self == b or self.isEmpty():
636  return self
637  elif b.isEmpty():
638  return self.setEmpty()
639  minPhi = max(self.min[1], b.min[1])
640  maxPhi = min(self.max[1], b.max[1])
641  minTheta = self.min[0]
642  maxTheta = self.max[0]
643  if self.wraps():
644  if b.wraps():
645  minTheta = max(minTheta, b.min[0])
646  maxTheta = min(maxTheta, b.max[0])
647  else:
648  if b.max[0] >= minTheta:
649  if b.min[0] <= maxTheta:
650  if b.max[0] - b.min[0] <= 360.0 - minTheta + maxTheta:
651  minTheta = b.min[0]
652  maxTheta = b.max[0]
653  else:
654  minTheta = max(minTheta, b.min[0])
655  maxTheta = b.max[0]
656  elif b.min[0] <= maxTheta:
657  minTheta = b.min[0]
658  maxTheta = min(maxTheta, b.max[0])
659  else:
660  minPhi = 90.0
661  maxPhi = -90.0
662  else:
663  if b.wraps():
664  if maxTheta >= b.min[0]:
665  if minTheta <= b.max[0]:
666  if maxTheta - minTheta > 360.0 - b.min[0] + b.max[0]:
667  minTheta = b.min[0]
668  maxTheta = b.max[0]
669  else:
670  minTheta = max(minTheta, b.min[0])
671  elif minTheta <= b.max[0]:
672  maxTheta = b.max[0]
673  else:
674  minPhi = 90.0
675  maxPhi = -90.0
676  elif minTheta > b.max[0] or maxTheta < b.min[0]:
677  minPhi = 90.0
678  maxPhi = -90.0
679  else:
680  minTheta = max(minTheta, b.min[0])
681  maxTheta = min(maxTheta, b.max[0])
682  self.min = (minTheta, minPhi)
683  self.max = (maxTheta, maxPhi)
684  return self
def lsst.geom.geometry.SphericalBox.wraps (   self)
Returns True if this spherical box wraps across the 0/360
degree longitude angle discontinuity.

Definition at line 411 of file geometry.py.

412  def wraps(self):
413  """Returns True if this spherical box wraps across the 0/360
414  degree longitude angle discontinuity.
415  """
416  return self.min[0] > self.max[0]

Member Data Documentation

lsst.geom.geometry.SphericalBox.max

Definition at line 387 of file geometry.py.

lsst.geom.geometry.SphericalBox.min

Definition at line 386 of file geometry.py.


The documentation for this class was generated from the following file: