diff options
author | Greg Studer <greg@10gen.com> | 2014-05-14 11:15:21 -0400 |
---|---|---|
committer | Greg Studer <greg@10gen.com> | 2014-05-19 18:46:06 -0400 |
commit | 65b71020e3f51467a42b13784abb63d87225bd39 (patch) | |
tree | a434b705aaec49850a2ddd2fb154f100ae1eaae5 /src/mongo/db/geo/shapes.cpp | |
parent | 62d49d464c7f2a7181dec9b822e30b196107fa01 (diff) | |
download | mongo-65b71020e3f51467a42b13784abb63d87225bd39.tar.gz |
SERVER-5800 R2Region interface for 2d index covering support, minor refactor
Diffstat (limited to 'src/mongo/db/geo/shapes.cpp')
-rw-r--r-- | src/mongo/db/geo/shapes.cpp | 100 |
1 files changed, 62 insertions, 38 deletions
diff --git a/src/mongo/db/geo/shapes.cpp b/src/mongo/db/geo/shapes.cpp index 2be932344c3..efb6ee1c05b 100644 --- a/src/mongo/db/geo/shapes.cpp +++ b/src/mongo/db/geo/shapes.cpp @@ -71,9 +71,24 @@ namespace mongo { Box::Box() {} - Box::Box(double x, double y, double size) : _min(x, y), _max(x + size, y + size) { } + Box::Box(double x, double y, double size) : + _min(x, y), _max(x + size, y + size) { + } + + Box::Box(const Point& ptA, const Point& ptB) { + init(ptA, ptB); + } + + void Box::init(const Point& ptA, const Point& ptB) { + _min.x = min(ptA.x, ptB.x); + _min.y = min(ptA.y, ptB.y); + _max.x = max(ptA.x, ptB.x); + _max.y = max(ptA.y, ptB.y); + } - Box::Box(Point min, Point max) : _min(min), _max(max) { } + void Box::init(const Box& other) { + init(other._min, other._max); + } BSONArray Box::toBSON() const { return BSON_ARRAY(BSON_ARRAY(_min.x << _min.y) << BSON_ARRAY(_max.x << _max.y)); @@ -151,7 +166,14 @@ namespace mongo { _max.y += error; } - bool Box::onBoundary(Point p, double fudge) { + void Box::expandToInclude(const Point& pt) { + _min.x = min(_min.x, pt.x); + _min.y = min(_min.y, pt.y); + _max.x = max(_max.x, pt.x); + _max.y = max(_max.y, pt.y); + } + + bool Box::onBoundary(Point p, double fudge) const { return onBoundary(_min.x, p.x, fudge) || onBoundary(_max.x, p.x, fudge) || onBoundary(_min.y, p.y, fudge) || @@ -168,21 +190,30 @@ namespace mongo { between(_min.y, _max.y , y, fudge); } - bool Box::contains(const Box& other, double fudge) { + bool Box::contains(const Box& other, double fudge) const { return inside(other._min, fudge) && inside(other._max, fudge); } ////////////// Polygon - Polygon::Polygon(void) : _centroidCalculated(false), _boundsCalculated(false) {} + Polygon::Polygon() { + } - Polygon::Polygon(vector<Point> points) : _centroidCalculated(false), - _boundsCalculated(false), _points(points) { } + Polygon::Polygon(const vector<Point>& points) { + init(points); + } - void Polygon::add(Point p) { - _centroidCalculated = false; - _boundsCalculated = false; - _points.push_back(p); + void Polygon::init(const vector<Point>& points) { + + _points.clear(); + _bounds.reset(); + _centroid.reset(); + + _points.insert(_points.begin(), points.begin(), points.end()); + } + + void Polygon::init(const Polygon& other) { + init(other._points); } int Polygon::size(void) const { return _points.size(); } @@ -306,13 +337,14 @@ namespace mongo { } } - Point Polygon::centroid(void) { - /* Centroid is cached, it won't change betwen points */ - if (_centroidCalculated) { - return _centroid; + const Point& Polygon::centroid() const { + + if (_centroid) { + return *_centroid; } - Point cent; + _centroid.reset(new Point()); + double signedArea = 0.0; double area = 0.0; // Partial signed area @@ -321,43 +353,35 @@ namespace mongo { for (i = 0; i < size() - 1; ++i) { area = _points[i].x * _points[i+1].y - _points[i+1].x * _points[i].y ; signedArea += area; - cent.x += (_points[i].x + _points[i+1].x) * area; - cent.y += (_points[i].y + _points[i+1].y) * area; + _centroid->x += (_points[i].x + _points[i+1].x) * area; + _centroid->y += (_points[i].y + _points[i+1].y) * area; } // Do last vertex area = _points[i].x * _points[0].y - _points[0].x * _points[i].y; - cent.x += (_points[i].x + _points[0].x) * area; - cent.y += (_points[i].y + _points[0].y) * area; + _centroid->x += (_points[i].x + _points[0].x) * area; + _centroid->y += (_points[i].y + _points[0].y) * area; signedArea += area; signedArea *= 0.5; - cent.x /= (6 * signedArea); - cent.y /= (6 * signedArea); - - _centroidCalculated = true; - _centroid = cent; + _centroid->x /= (6 * signedArea); + _centroid->y /= (6 * signedArea); - return cent; + return *_centroid; } - Box Polygon::bounds(void) { - if (_boundsCalculated) { - return _bounds; + const Box& Polygon::bounds() const { + + if (_bounds) { + return *_bounds; } - _bounds._max = _points[0]; - _bounds._min = _points[0]; + _bounds.reset(new Box(_points[0], _points[0])); for (int i = 1; i < size(); i++) { - _bounds._max.x = max(_bounds._max.x, _points[i].x); - _bounds._max.y = max(_bounds._max.y, _points[i].y); - _bounds._min.x = min(_bounds._min.x, _points[i].x); - _bounds._min.y = min(_bounds._min.y, _points[i].y); - + _bounds->expandToInclude(_points[i]); } - _boundsCalculated = true; - return _bounds; + return *_bounds; } /////// Other methods |