17#include <geos/export.h>
18#include <geos/geom/Coordinate.h>
19#include <geos/geom/LineSegment.h>
20#include <geos/geom/Quadrant.h>
21#include <geos/algorithm/CircularArcs.h>
22#include <geos/algorithm/Orientation.h>
47 CircularArc(std::unique_ptr<CoordinateSequence>, std::size_t pos);
48 CircularArc(std::unique_ptr<CoordinateSequence>, std::size_t pos,
const CoordinateXY& center,
double radius,
int orientation);
62 template<typename CoordType>
63 static
CircularArc create(const CoordType& p0, const CoordType& p1, const CoordType& p2)
65 auto seq = std::make_unique<CoordinateSequence>(3, CoordType::template has<Ordinate::Z>(), CoordType::template has<Ordinate::M>());
75 static CircularArc create(
const CoordinateXY& p0,
const CoordinateXY& p2,
const CoordinateXY& center,
double radius,
int orientation);
77 static CircularArc create(
const CoordinateXYM& p0,
const CoordinateXYM& p2,
const CoordinateXY& center,
double radius,
int orientation);
78 static CircularArc create(
const CoordinateXYZM& p0,
const CoordinateXYZM& p2,
const CoordinateXY& center,
double radius,
int orientation);
88 if (!m_center_known) {
90 m_center = algorithm::CircularArcs::getCenter(p0(), p1(), p2());
92 m_center = algorithm::CircularArcs::getCenter(p2(), p1(), p0());
94 m_center_known =
true;
104 std::size_t getCoordinatePosition()
const {
123 if (!m_orientation_known) {
124 m_orientation = algorithm::Orientation::index(p0(), p1(), p2());
125 m_orientation_known =
true;
127 return m_orientation;
132 if (!m_radius_known) {
134 m_radius = getCenter().distance(p0());
136 m_radius = getCenter().distance(p2());
138 m_radius_known =
true;
146 CoordinateXY midpoint = algorithm::CircularArcs::getMidpoint(p0(), p2(), getCenter(), getRadius(), isCCW());
147 return algorithm::Distance::pointToSegment(midpoint, p0(), p2());
151 return getOrientation() == algorithm::Orientation::COUNTERCLOCKWISE;
156 return p0().equals(p2());
161 return !std::isfinite(getRadius());
166 return algorithm::CircularArcs::getAngle(p0(), getCenter());
171 return algorithm::CircularArcs::getAngle(p1(), getCenter());
176 return algorithm::CircularArcs::getAngle(p2(), getCenter());
189 double theta = std::atan2(q.y - getCenter().y, q.x - getCenter().x);
190 return containsAngle(theta);
204 bool equals(
const CircularArc& other,
double tol)
const;
208 using iterator_category = std::forward_iterator_tag;
209 using difference_type = std::ptrdiff_t;
210 using value_type = geom::CoordinateXY;
211 using pointer =
const geom::CoordinateXY*;
212 using reference =
const geom::CoordinateXY&;
214 Iterator(
const CircularArc& arc,
int i) : m_arc(arc), m_i(i) {}
216 reference operator*()
const {
217 return m_i == 0 ? m_arc.p0() : (m_i == 1 ? m_arc.p1() : m_arc.p2());
220 Iterator& operator++() {
225 Iterator operator++(
int) {
226 Iterator ret = *
this;
231 bool operator==(
const Iterator& other)
const {
232 return m_i == other.m_i;
235 bool operator!=(
const Iterator& other)
const {
236 return !(*
this == other);
240 const CircularArc& m_arc;
245 Iterator begin()
const {
246 return Iterator(*
this, 0);
249 Iterator end()
const {
250 return Iterator(*
this, 3);
253 template<
typename T=CoordinateXY>
254 const T& p0()
const {
255 return m_seq->getAt<T>(m_pos);
258 template<
typename T=CoordinateXY>
259 const T& p1()
const {
260 return m_seq->getAt<T>(m_pos + 1);
263 template<
typename T=CoordinateXY>
264 const T& p2()
const {
265 return m_seq->getAt<T>(m_pos + 2);
268 std::string toString()
const;
271 auto applyAt(std::size_t i, F&& f)
const {
272 return m_seq->applyAt(m_pos + i, f);
276 const CoordinateSequence* m_seq;
279 mutable CoordinateXY m_center;
280 mutable double m_radius;
281 mutable int m_orientation;
282 mutable bool m_center_known =
false;
283 mutable bool m_radius_known =
false;
284 mutable bool m_orientation_known =
false;
285 bool m_own_coordinates;
Definition CircularArc.h:29
CoordinateXY getDirectionPoint() const
bool containsPointOnCircle(const CoordinateXY &q) const
Definition CircularArc.h:188
bool isUpwardAtPoint(const CoordinateXY &q) const
CircularArc(std::unique_ptr< CoordinateSequence >, std::size_t pos)
bool isCircle() const
Return whether this arc forms a complete circle.
Definition CircularArc.h:155
CircularArc(const CoordinateSequence &, std::size_t pos)
bool containsAngle(double theta) const
Check to see if a given angle lies on this arc.
int getOrientation() const
Definition CircularArc.h:122
const CoordinateXY & getCenter() const
Return the center point of the circle associated with this arc.
Definition CircularArc.h:87
double getSagitta() const
Return the distance from the centerpoint of the arc to the line segment formed by the end points of t...
Definition CircularArc.h:145
bool isLinear() const
Returns whether this arc forms a straight line (p0, p1, and p2 are collinear)
Definition CircularArc.h:160
double getAngle() const
Return the inner angle of the sector associated with this arc.
double getLength() const
Return the length of the arc.
double getArea() const
Return the area enclosed by the arc p0-p1-p2 and the line segment p2-p0.
double getRadius() const
Return the radius of the circle associated with this arc.
Definition CircularArc.h:131
bool containsPoint(const CoordinateXY &q) const
double theta0() const
Return the angle of p0.
Definition CircularArc.h:165
double theta1() const
Return the angle of p1.
Definition CircularArc.h:170
double theta2() const
Return the angle of p2.
Definition CircularArc.h:175
The internal representation of a list of coordinates inside a Geometry.
Definition CoordinateSequence.h:56
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:220
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition Envelope.h:59
Basic namespace for all GEOS functionalities.
Definition geos.h:38