DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/intersection/Rectangle.h

237 lines
5.5 KiB
C
Raw Normal View History

2024-12-24 23:49:36 +00:00
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2014 Mika Heiskanen <mika.heiskanen@fmi.fi>
*
* 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.
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <memory>
#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
*
* @note Ownership transferred to caller
*/
std::unique_ptr<geom::Polygon> toPolygon(const geom::GeometryFactory& f) const;
std::unique_ptr<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 Rectangle edge
* @param pos Rectangle::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 Rectangle edge
* @param pos1 [Position](@ref Rectangle::Position) of first coordinate
* @param pos2 [Position](@ref Rectangle::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 Rectangle
* @param x x-coordinate
* @param y y-coordinate
* @return [Position](@ref Rectangle::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 && x < xMax && y > yMin && y < yMax) {
return Inside;
}
// Next we assume the point to be outside and test it next
if(x < xMin || x > xMax || y < yMin || y > yMax) {
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 [Position](@ref Rectangle::Position)
* @return next [Position](@ref Rectangle::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