Skip to content

Commit

Permalink
Merge pull request #20 from lsst/tickets/DM-19409
Browse files Browse the repository at this point in the history
DM-19409: Add Box2I.getCenter()
  • Loading branch information
timj committed Apr 23, 2019
2 parents fd17674 + 796d531 commit b9095d2
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 38 deletions.
11 changes: 11 additions & 0 deletions include/lsst/geom/Box.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@ class Box2I final {
int getArea() const { return getWidth() * getHeight(); }
//@}

/**
* @name Center Accessors
*
* Return the center coordinate of the box.
*/
//@{
Point2D const getCenter() const noexcept;
double getCenterX() const noexcept { return this->getCenter().getX(); }
double getCenterY() const noexcept { return this->getCenter().getY(); }
//@}

/// Return slices to extract the box's region from an ndarray::Array.
ndarray::View<boost::fusion::vector2<ndarray::index::Range, ndarray::index::Range> > getSlices() const;

Expand Down
3 changes: 3 additions & 0 deletions python/lsst/geom/_Box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ void wrapBox(utils::python::WrapperCollection & wrappers) {
cls.def("getWidth", &Box2I::getWidth);
cls.def("getHeight", &Box2I::getHeight);
cls.def("getArea", &Box2I::getArea);
cls.def("getCenter", &Box2I::getCenter);
cls.def("getCenterX", &Box2I::getCenterX);
cls.def("getCenterY", &Box2I::getCenterY);
cls.def("isEmpty", &Box2I::isEmpty);
cls.def("contains", (bool (Box2I::*)(Point2I const &) const) & Box2I::contains);
cls.def("contains", (bool (Box2I::*)(Box2I const &) const) & Box2I::contains);
Expand Down
4 changes: 4 additions & 0 deletions src/Box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ Box2I::Box2I(Box2D const& other, EdgeHandlingEnum edgeHandling) : _minimum(), _d
}
}

Point2D const Box2I::getCenter() const noexcept {
return Box2D(*this).getCenter();
}

Box2I Box2I::makeCenteredBox(Point2D const& center, Box2I::Extent const& size) {
if (!std::isfinite(center[0]) || !std::isfinite(center[1])) {
throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, "Cannot make Box2I with non-finite center");
Expand Down
45 changes: 7 additions & 38 deletions tests/test_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ def testAccessors(self):
self.assertEqual(box.getHeight(), (ymax - ymin + 1))
self.assertAlmostEqual(box.getArea(), box.getWidth() * box.getHeight(),
places=14)
self.assertEqual(box.getCenterX(), 0.5*(pmax.getX() + pmin.getX()))
self.assertEqual(box.getCenterY(), 0.5*(pmax.getY() + pmin.getY()))
self.assertEqual(box.getCenter().getX(), box.getCenterX())
self.assertEqual(box.getCenter().getY(), box.getCenterY())
corners = box.getCorners()
self.assertEqual(corners[0], box.getMin())
self.assertEqual(corners[1].getX(), box.getMaxX())
Expand Down Expand Up @@ -561,50 +565,15 @@ def _checkBoxConstruction(self, boxClass, size, center, precision):
if all(np.isfinite(center)):
box = boxClass.makeCenteredBox(center, size)
if all(size.gt(0)):
self._checkBoxProperties(box, size, center, precision, msg)
self.assertIsNotNone(box, msg=msg)
self.assertPairsAlmostEqual(box.getCenter(), center, maxDiff=precision, msg=msg)
self.assertPairsAlmostEqual(box.getDimensions(), size, msg=msg)
else:
self.assertTrue(box.isEmpty(), msg=msg)
elif boxClass == geom.Box2I:
with self.assertRaises(lsst.pex.exceptions.InvalidParameterError, msg=msg):
boxClass.makeCenteredBox(center, size)

def _checkBoxProperties(self, box, size, center, precision, msg):
"""Test whether a box has the desired size and position.
Parameters
----------
box : `lsst.geom.Box2I` or `lsst.geom.Box2D`
The box to test.
size : ``box.Extent``
The expected dimensions of ``box``.
center : `lsst.geom.Point2D`
The expected center of ``box``.
precision : `float`
The maximum distance between the center of ``box`` and ``center``.
msg : `str`
An error message suffix describing test parameters.
"""
newCenter = self._getBoxCenter(box)
self.assertIsNotNone(box, msg=msg)
self.assertPairsAlmostEqual(newCenter, center, maxDiff=precision, msg=msg)
self.assertPairsAlmostEqual(box.getDimensions(), size, msg=msg)

def _getBoxCenter(self, box):
"""Return the coordinates of a Box's center.
Parameters
----------
box : `lsst.geom.Box2I` or `lsst.geom.Box2D`
The box whose center is desired.
Returns
-------
center : `lsst.geom.Point2D`
The position at the center of ``box``. If ``box`` is a ``Box2I``,
this will always have integer or half-integer coordinates.
"""
return geom.Box2D(box).getCenter()


class MemoryTester(lsst.utils.tests.MemoryTestCase):
pass
Expand Down

0 comments on commit b9095d2

Please sign in to comment.