/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2014 Mika Heiskanen * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/ #ifndef GEOS_OP_INTERSECTION_RECTANGLE_H #define GEOS_OP_INTERSECTION_RECTANGLE_H #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class #endif // Forward declarations namespace geos { namespace geom { class GeometryFactory; class Geometry; class Polygon; class LinearRing; } } namespace geos { namespace operation { // geos::operation namespace intersection { // geos::operation::intersection /** * \brief Clipping rectangle * * A clipping rectangle defines the boundaries of the rectangle * by defining the limiting x- and y-coordinates. The clipping * rectangle must be non-empty. In addition, methods are provided * for specifying the location of a given coordinate with respect * to the clipping rectangle similarly to the Cohen-Sutherland * clipping algorithm. * */ class GEOS_DLL Rectangle { public: /** * \brief Construct a clipping rectangle * * @param x1 x-coordinate of the left edge * @param y1 y-coordinate of the bottom edge * @param x2 x-coordinate of the right edge * @param y2 y-coordinate of the right edge * @throws IllegalArgumentException if the rectangle is empty */ Rectangle(double x1, double y1, double x2, double y2); /** * \@return the minimum x-coordinate of the rectangle */ double xmin() const { return xMin; } /** * \@return the minimum y-coordinate of the rectangle */ double ymin() const { return yMin; } /** * \@return the maximum x-coordinate of the rectangle */ double xmax() const { return xMax; } /** * \@return the maximum y-coordinate of the rectangle */ double ymax() const { return yMax; } /** * \@return the rectangle as a polygon geometry * * Ownership transferred to caller */ geom::Polygon* toPolygon(const geom::GeometryFactory &f) const; geom::LinearRing* toLinearRing(const geom::GeometryFactory &f) const; /** * @brief Position with respect to a clipping rectangle */ enum Position { Inside = 1, Outside = 2, Left = 4, Top = 8, Right = 16, Bottom = 32, TopLeft = Top|Left, // 12 TopRight = Top|Right, // 24 BottomLeft = Bottom|Left, // 36 BottomRight = Bottom|Right // 48 }; /** * @brief Test if the given position is on a {@link Rectangle] edge * @param pos {@link Rectangle} {@link Position} * @return true, if the position is on an edge */ static bool onEdge(Position pos) { return (pos > Outside); } /** * @brief Test if the given positions are on the same {@link Rectangle} edge * @param pos1 {@link Rectangle} {@link Position} of first coordinate * @param pos2 {@link Rectangle} {@link Position} of second coordinate * @return true, if the positions are on the same edge */ static bool onSameEdge(Position pos1, Position pos2) { return onEdge(Position(pos1 & pos2)); } /** * @brief Establish position of coordinate with respect to a {@link Rectangle} * @param x x-coordinate * @param y y-coordinate * @return {@link Position} of the coordinate */ Position position(double x, double y) const { // We assume the point to be inside and test it first if(x>xMin && xyMin && yxMax || yyMax) return Outside; // Slower cases unsigned int pos = 0; if(x==xMin) pos |= Left; else if(x==xMax) pos |= Right; if(y==yMin) pos |= Bottom; else if(y==yMax) pos |= Top; return Position(pos); } /** * @brief Next edge in clock-wise direction * @param pos {@link Rectangle} {@link Position} * @return next {@Rectangle} {@link Position} in clock-wise direction */ static Position nextEdge(Position pos) { switch(pos) { case BottomLeft: case Left: return Top; case TopLeft: case Top: return Right; case TopRight: case Right: return Bottom; case BottomRight: case Bottom: return Left; /* silences compiler warnings, Inside & Outside are not handled explicitly */ default: return pos; } } private: Rectangle(); double xMin; double yMin; double xMax; double yMax; }; // class RectangleIntersection } // namespace geos::operation::intersection } // namespace geos::operation } // namespace geos #endif // GEOS_OP_INTERSECTION_RECTANGLE_H