Skip to content

Commit

Permalink
More progress on intersecting
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Nov 9, 2023
1 parent 31defc1 commit c540ec5
Showing 1 changed file with 49 additions and 46 deletions.
95 changes: 49 additions & 46 deletions polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,64 +12,56 @@ struct point {

typedef std::pair<point, point> segment;

// https://stackoverflow.com/questions/9043805/test-if-two-lines-intersect-javascript-function/16725715#16725715
// this does not seem to be correct
bool intersects(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
double det = (x2 - x1) * (y4 - y3) - (x4 - x3) * (y2 - y1);
if (det == 0) {
return false;
} else {
double lambda = ((y4 - y3) * (x4 - x1) + (x3 - x4) * (y4 - y1)) / det;
double gamma = ((y1 - y2) * (x4 - x1) + (x2 - x1) * (y4 - y1)) / det;

if (lambda > 0 && lambda < 1 && gamma > 0 && gamma < 1) {
printf("%f,%f to %f,%f and %f,%f to %f,%f: %f and %f\n",
x1, y1, x2, y2, x3, y3, x4, y4, lambda, gamma);
printf("%f,%f or %f,%f\n",
x1 + (x2 - x1) * lambda, y1 + (y2 - y1) * lambda,
x3 + (x4 - x3) * gamma, y3 + (y4 - y3) * gamma);
}
return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
}
}

// https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
// this seems to produce the same point along both segments
bool get_line_intersection(double p0_x, double p0_y, double p1_x, double p1_y,
double p2_x, double p2_y, double p3_x, double p3_y) {
double s1_x, s1_y, s2_x, s2_y;
s1_x = p1_x - p0_x;
s1_y = p1_y - p0_y;
s2_x = p3_x - p2_x;
s2_y = p3_y - p2_y;
//
// beware of
// https://stackoverflow.com/questions/9043805/test-if-two-lines-intersect-javascript-function/16725715#16725715
// which does not seem to produce correct results.
std::pair<double, double> get_line_intersection(double p0_x, double p0_y, double p1_x, double p1_y,
double p2_x, double p2_y, double p3_x, double p3_y) {
double d01_x, d01_y, d23_x, d23_y;
d01_x = p1_x - p0_x;
d01_y = p1_y - p0_y;
d23_x = p3_x - p2_x;
d23_y = p3_y - p2_y;

float det = (-s2_x * s1_y + s1_x * s2_y);
float det = (-d23_x * d01_y + d01_x * d23_y);

if (det != 0) {
double s, t;
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / det;
t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / det;
double t, s;
t = (d23_x * (p0_y - p2_y) - d23_y * (p0_x - p2_x)) / det;
s = (-d01_y * (p0_x - p2_x) + d01_x * (p0_y - p2_y)) / det;

if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
return std::make_pair(t, s);

#if 0
printf("%f,%f to %f,%f and %f,%f to %f,%f: %f and %f\n",
p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y, t, s);
printf("%f,%f or %f,%f\n",
p0_x + t * s1_x, p0_y + t * s1_y,
p2_x + s * s2_x, p2_y + s * s2_y);

return 1;
p0_x + t * d01_x, p0_y + t * d01_y,
p2_x + s * d23_x, p2_y + s * d23_y);
#endif
}
}

return 0; // No collision
return std::make_pair(-1, -1);
}

bool intersect(std::vector<segment> &segs, size_t s1, size_t s2) {
get_line_intersection(std::round(segs[s1].first.x), std::round(segs[s1].first.y),
std::round(segs[s1].second.x), std::round(segs[s1].second.y),
std::round(segs[s2].first.x), std::round(segs[s2].first.y),
std::round(segs[s2].second.x), std::round(segs[s2].second.y));
return false;
auto intersections = get_line_intersection(std::round(segs[s1].first.x), std::round(segs[s1].first.y),
std::round(segs[s1].second.x), std::round(segs[s1].second.y),
std::round(segs[s2].first.x), std::round(segs[s2].first.y),
std::round(segs[s2].second.x), std::round(segs[s2].second.y));

bool changed = false;
if (intersections.first >= 0) {
// XXX introduce a new node
} else {
// XXX handle collinear
}

return changed;
}

struct scan_transition {
Expand Down Expand Up @@ -120,8 +112,8 @@ std::vector<segment> snap_round(std::vector<segment> segs) {

// do the scan

std::set<std::pair<size_t, size_t>> already;
std::set<size_t> active;
std::set<std::pair<size_t, size_t>> already;
size_t bottom = 0;

for (size_t i = 0; i < tops.size(); i++) {
Expand All @@ -145,6 +137,7 @@ std::vector<segment> snap_round(std::vector<segment> segs) {
// may have caused new intersections
again = true;
}

already.insert(std::make_pair(s1, s2));
}
}
Expand All @@ -161,6 +154,18 @@ std::vector<segment> snap_round(std::vector<segment> segs) {
}
}
}

if (again) {
// let the intersections settle down before we start trying
// to make additional changes
continue;
}

// find identical opposite-winding segments and adjust for them
//
// this is in the same loop because we may introduce new self-intersections
// in the course of trying to keep spindles alive, and will then need to
// resolve those.
}

return segs;
Expand Down Expand Up @@ -199,8 +204,6 @@ drawvec clean_polygon(drawvec const &geom, int z, int detail) {

segments = snap_round(segments);

// remove duplicate segments with opposite windings

// reassemble segments into rings

// remove collinear points?
Expand Down

0 comments on commit c540ec5

Please sign in to comment.