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
rotateBBoxBy90.py
Go to the documentation of this file.
1 from __future__ import absolute_import, division
2 #
3 # LSST Data Management System
4 # Copyright 2014 LSST Corporation.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <http://www.lsstcorp.org/LegalNotices/>.
22 #
23 import numpy
24 import lsst.afw.geom as afwGeom
25 
26 __all__ = ["rotateBBoxBy90"]
27 
28 def rotateBBoxBy90(bbox, n90, dimensions):
29  """!Rotate a bounding box by an integer multiple of 90 degrees
30 
31  @todo document dimensions better; what does it specify?
32 
33  @param bbox bbox to rotate
34  @param n90 number of quarter rotations to perform
35  @param dimensions dimensions of the parent grid
36  @return rotated bounding box
37  """
38  while n90 < 0:
39  n90 += 4
40  n90 %= 4
41 
42  # sin/cos of the rotation angle
43  s = 0
44  c = 0
45  if n90 == 0:
46  s = 0
47  c = 1
48  elif n90 == 1:
49  s = 1
50  c = 0
51  elif n90 == 2:
52  s = 0
53  c = -1
54  elif n90 == 3:
55  s = -1
56  c = 0
57  else:
58  raise ValueError("n90 must be an integer")
59 
60  centerPixel = afwGeom.Point2I(int(dimensions[0]/2), int(dimensions[1]/2))
61 
62  xCorner = numpy.array([(corner.getX() - centerPixel[0]) for corner in bbox.getCorners()])
63  yCorner = numpy.array([(corner.getY() - centerPixel[1]) for corner in bbox.getCorners()])
64  x0 = int((c*xCorner - s*yCorner).min())
65  y0 = int((s*xCorner + c*yCorner).min())
66  x1 = int((c*xCorner - s*yCorner).max())
67  y1 = int((s*xCorner + c*yCorner).max())
68 
69  # Fiddle things a little if the detector has an even number of pixels so that square BBoxes
70  # will map into themselves
71 
72  if n90 == 1 :
73  if dimensions[0]%2 == 0:
74  x0 -= 1
75  x1 -= 1
76  elif n90 == 2:
77  if dimensions[0]%2 == 0:
78  x0 -= 1
79  x1 -= 1
80  if dimensions[1]%2 == 0:
81  y0 -= 1
82  y1 -= 1
83  elif n90 == 3:
84  if dimensions[1]%2 == 0:
85  y0 -= 1
86  y1 -= 1
87 
88  LLC = afwGeom.Point2I(centerPixel[0] + x0, centerPixel[1] + y0)
89  URC = afwGeom.Point2I(centerPixel[0] + x1, centerPixel[1] + y1)
90 
91  newBbox = afwGeom.Box2I(LLC, URC)
92 
93  dxy0 = centerPixel[0] - centerPixel[1]
94  if n90%2 == 1 and not dxy0 == 0:
95  newBbox.shift(afwGeom.Extent2I(-dxy0, dxy0))
96 
97  return newBbox
An integer coordinate rectangle.
Definition: Box.h:53
def rotateBBoxBy90
Rotate a bounding box by an integer multiple of 90 degrees.