Something went wrong. Try again.
Sweep line experiments with Raylib
Something went wrong. Try again.
sweep-line helpers.cpp
5.1 kB · 172 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
#include "helpers.h"
bool operator==(const Vector2 &v, const Vector2 &w){ return v.x == w.x and v.y == w.y;}
Vector2 operator-(const Vector2 &v, const Vector2 &w){ return Vector2{v.x - w.x, v.y - w.y};}
Vector2 operator+(const Vector2 &v, const Vector2 &w){ return Vector2{v.x + w.x, v.y + w.y};}
Color darkenBy(const Color &c, int amount){ return Color{std::max(c.r - amount, 0), std::max(c.g - amount, 0), std::max(c.b - amount, 0)};}
/* This fucntion tells us wether a loop pqr is clockwise, counterclockwise, * or if they're colinear */Orientation orientation(const Point &p, const Point &q, const Point &r){ Vector2 pq = p - q; Vector2 pr = p - r;
float o = pq.x * pr.y - pr.x * pq.y;
if (o > 0) return CW; else if (o < 0) return CCW; return CL;}
bool sharedEndpoint(const LineSegment &s, const LineSegment &t){ return s.first == t.first or s.second == t.second or s.first == t.second or s.second == t.second;}
/* This function checks if a point p is inside a rectangle of diagonal t */bool insideRectangle(const LineSegment &t, const Point &p){ float x_min = std::min(t.first.x, t.second.x); float y_min = std::min(t.first.y, t.second.y); float x_max = std::max(t.first.x, t.second.x); float y_max = std::max(t.first.y, t.second.y);
return ((p.x >= x_min and p.x <= x_max) and (p.y >= y_min and p.y <= y_max));}
bool insideRectangle(const LineSegment &t, const LineSegment &s){ return insideRectangle(t, s.first) and insideRectangle(t, s.second);}
bool intersect(const LineSegment &s, const LineSegment &t){ int t1 = orientation(s.first, s.second, t.first); int t2 = orientation(s.first, s.second, t.second); int s1 = orientation(t.first, t.second, s.first); int s2 = orientation(t.first, t.second, s.second);
// They cross at a middle point if (t1 != t2 and s1 != s2) return true;
// s.first lies inside t if (t1 == 0 and insideRectangle(t, s.first)) return true; // s.second lies inside t if (t2 == 0 and insideRectangle(t, s.second)) return true; // t.first lies inside s if (s1 == 0 and insideRectangle(s, t.first)) return true; // t.second lies inside s if (s2 == 0 and insideRectangle(s, t.second)) return true;
return false;}
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour, std::string &desc){ colour = GRAY; desc = "No intersection";
int t1 = orientation(s.first, s.second, t.first); int t2 = orientation(s.first, s.second, t.second); int s1 = orientation(t.first, t.second, s.first); int s2 = orientation(t.first, t.second, s.second);
//Segment t has endpoints on either side of s if ((t1 < 0) != (t2 < 0)) { //Segment s has endpoints on either side of t if ((s1 < 0) != (s2 < 0)) { desc = "Intersection in a middle point (red)"; colour = RED; } //Segment s has just one endpoint on the line over segment t else if ((s1 > 0) != (s2 > 0)) { desc = "Endpoint on the intersection (green)"; colour = GREEN; } } //Segment t has just one endpoint on the line over segment s else if ((t1 > 0) != (t2 > 0)) { //Segment t and segment s share an endpoint if (sharedEndpoint(s, t)) { desc = "Intersection at a shared endpoint (dark green)"; colour = DARKGREEN; } //Segment s has endpoints on either side of t else if ((s1 < 0) != (s2 < 0)) { desc = "Endpoint on the intersection (green)"; colour = GREEN; } } //Segment t has both endpoints on the line over segment s else if ((t1 == 0) and (t2 == 0)) { desc = " on a shared line";
//Segment s and segment t share one endpoint if (sharedEndpoint(s, t)) { //Segment s and t share both endpoints if (sharedEndpoint(s, t)) { desc = "Full overlap (purple)"; colour = PURPLE; } else { desc = "Intersection at a shared endpoint (pink)"; colour = PINK; } } //Segment t has one endpoint inside the rectangle covering both endpoints of s //Since t's endpoints are already on the line over s, this means having it on s else if (insideRectangle(s, t)) { desc = "Overlap (intersection)" + desc + " (dark blue)"; colour = DARKBLUE; } //Segment t has both endpoints on the line over s, but none inside s else { desc = "No intersection, but" + desc + " (blue)"; colour = BLUE; } }}
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour){ std::string unused; classifyIntersection(s, t, colour, unused);}