33 using CoordinateXY = geom::CoordinateXY;
37 CircularArc(
const CoordinateXY& q0,
const CoordinateXY& q1,
const CoordinateXY& q2)
41 , m_center_known(
false)
42 , m_radius_known(
false)
43 , m_orientation_known(
false)
46 CircularArc(
double theta0,
double theta2,
const CoordinateXY& center,
double radius,
int orientation)
47 : p0(algorithm::CircularArcs::createPoint(center, radius, theta0)),
48 p1(algorithm::CircularArcs::createPoint(center, radius, algorithm::CircularArcs::getMidpointAngle(theta0, theta2, orientation==algorithm::Orientation::COUNTERCLOCKWISE))),
49 p2(algorithm::CircularArcs::createPoint(center, radius, theta2)),
52 m_orientation(orientation),
55 m_orientation_known(
true)
58 CircularArc(
const CoordinateXY& q0,
const CoordinateXY& q2,
const CoordinateXY& center,
double radius,
int orientation)
60 p1(algorithm::CircularArcs::getMidpoint(q0, q2, center, radius, orientation==algorithm::Orientation::COUNTERCLOCKWISE)),
64 m_orientation(orientation),
67 m_orientation_known(
true)
79 if (!m_orientation_known) {
80 m_orientation = algorithm::Orientation::index(p0, p1, p2);
81 m_orientation_known =
true;
87 return getOrientation() == algorithm::Orientation::COUNTERCLOCKWISE;
92 if (!m_center_known) {
93 m_center = algorithm::CircularArcs::getCenter(p0, p1, p2);
94 m_center_known =
true;
102 if (!m_radius_known) {
103 m_radius = getCenter().distance(p0);
104 m_radius_known =
true;
112 return p0.equals(p2);
117 return !std::isfinite(getRadius());
134 if (getOrientation() == algorithm::Orientation::COUNTERCLOCKWISE) {
150 return p0.distance(p2);
153 return getAngle()*getRadius();
162 auto R = getRadius();
163 auto theta = getAngle();
164 return R*R/2*(theta - std::sin(theta));
169 CoordinateXY midpoint = algorithm::CircularArcs::getMidpoint(p0, p2, getCenter(), getRadius(), isCCW());
170 return algorithm::Distance::pointToSegment(midpoint, p0, p2);
175 return algorithm::CircularArcs::getAngle(p0, getCenter());
180 return algorithm::CircularArcs::getAngle(p2, getCenter());
187 double theta = std::atan2(q.y - getCenter().y, q.x - getCenter().x);
188 return containsAngle(theta);
194 if (q == p0 || q == p1 || q == p2) {
204 if (triangulate::quadedge::TrianglePredicate::isInCircleRobust(p0, p1, p2, q) != geom::Location::BOUNDARY) {
208 return containsPointOnCircle(q);
216 if (theta == t0 || theta == t2) {
220 if (getOrientation() == algorithm::Orientation::COUNTERCLOCKWISE) {
241 auto quad = geom::Quadrant::quadrant(getCenter(), q);
244 if (getOrientation() == algorithm::Orientation::CLOCKWISE) {
245 isUpward = (quad == geom::Quadrant::SW || quad == geom::Quadrant::NW);
247 isUpward = (quad == geom::Quadrant::SE || quad == geom::Quadrant::NE);
255 std::pair<CircularArc, CircularArc> splitAtPoint(
const CoordinateXY& q)
const {
257 CircularArc(p0, q, getCenter(), getRadius(), getOrientation()),
258 CircularArc(q, p2, getCenter(), getRadius(), getOrientation())
264 using iterator_category = std::forward_iterator_tag;
265 using difference_type = std::ptrdiff_t;
266 using value_type = geom::CoordinateXY;
267 using pointer =
const geom::CoordinateXY*;
268 using reference =
const geom::CoordinateXY&;
270 Iterator(
const CircularArc& arc,
int i) : m_arc(arc), m_i(i) {}
272 reference operator*()
const {
273 return m_i == 0 ? m_arc.p0 : (m_i == 1 ? m_arc.p1 : m_arc.p2);
276 Iterator& operator++() {
281 Iterator operator++(
int) {
282 Iterator ret = *
this;
287 bool operator==(
const Iterator& other)
const {
288 return m_i == other.m_i;
291 bool operator!=(
const Iterator& other)
const {
292 return !(*
this == other);
296 const CircularArc& m_arc;
301 Iterator begin()
const {
302 return Iterator(*
this, 0);
305 Iterator end()
const {
306 return Iterator(*
this, 3);
310 mutable CoordinateXY m_center;
311 mutable double m_radius;
312 mutable int m_orientation;
313 mutable bool m_center_known =
false;
314 mutable bool m_radius_known =
false;
315 mutable bool m_orientation_known =
false;
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:168