Skip to content

Commit

Permalink
CircularArcIntersector: Pull circle-segment intersection into own method
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaston committed Oct 16, 2024
1 parent cbbe9e0 commit ff72aa4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
3 changes: 3 additions & 0 deletions include/geos/algorithm/CircularArcIntersector.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class GEOS_DLL CircularArcIntersector {
/// points and/or arcs, if any.
void intersects(const CircularArc& arc1, const CircularArc& arc2);

static int
circleIntersects(const CoordinateXY& center, double r, const CoordinateXY& p0, const CoordinateXY& p1, CoordinateXY& isect0, CoordinateXY& isect1);

private:

void intersects(const CoordinateXY& p0, const CoordinateXY& p1, const CoordinateXY& q0, const CoordinateXY& q1);
Expand Down
52 changes: 38 additions & 14 deletions src/algorithm/CircularArcIntersector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,16 @@ nextAngleCCW(double from, double a, double b)
}
}

void
CircularArcIntersector::intersects(const CircularArc& arc, const CoordinateXY& p0, const CoordinateXY& p1)
int
CircularArcIntersector::circleIntersects(const CoordinateXY& center, double r, const CoordinateXY& p0, const CoordinateXY& p1, CoordinateXY& ret0, CoordinateXY& ret1)
{
if (arc.isLinear()) {
intersects(arc.p0, arc.p2, p0, p1);
return;
}
const double& x0 = center.x;
const double& y0 = center.y;

Envelope segEnv(p0, p1);

// TODO: envelope check?
const CoordinateXY& c = arc.getCenter();
const double& x0 = c.x;
const double& y0 = c.y;
const double r = arc.getRadius();

CoordinateXY isect0, isect1;
int n = 0;

if (p1.x == p0.x) {
// vertical line
Expand Down Expand Up @@ -80,11 +73,42 @@ CircularArcIntersector::intersects(const CircularArc& arc, const CoordinateXY& p
isect1 = {X2, m* X2 + b};
}

if (segEnv.contains(isect0) && arc.containsPointOnCircle(isect0)) {
if (segEnv.intersects(isect0)) {
ret0 = isect0;
if (segEnv.intersects(isect1) && !isect1.equals2D(isect0)) {
ret1 = isect1;
n = 2;
} else {
n = 1;
}
} else if (segEnv.intersects(isect1)) {
ret0 = isect1;
n = 1;
}

return n;
}

void
CircularArcIntersector::intersects(const CircularArc& arc, const CoordinateXY& p0, const CoordinateXY& p1)
{
if (arc.isLinear()) {
intersects(arc.p0, arc.p2, p0, p1);
return;
}

// TODO: envelope check?
const CoordinateXY& c = arc.getCenter();
const double r = arc.getRadius();

CoordinateXY isect0, isect1;
auto n = circleIntersects(c, r, p0, p1, isect0, isect1);

if (n > 0 && arc.containsPointOnCircle(isect0)) {
intPt[nPt++] = isect0;
}

if (segEnv.contains(isect1) && arc.containsPointOnCircle(isect1)) {
if (n > 1 && arc.containsPointOnCircle(isect1)) {
intPt[nPt++] = isect1;
}

Expand Down

0 comments on commit ff72aa4

Please sign in to comment.