LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
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
double min
Definition: attributes.cc:216
double max
Definition: attributes.cc:218
def rotateBBoxBy90
Rotate a bounding box by an integer multiple of 90 degrees.