line intersection formula from GraphicsGems; started Segment class

This commit is contained in:
Frank DeMarco 2020-08-02 00:52:50 -04:00
parent cea0bb5a21
commit 1861b80aa4
4 changed files with 132 additions and 0 deletions

37
src/Segment.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "Segment.hpp"
Segment::Segment() : Segment({0, 0}, {0, 0}) {};
Segment::Segment(const glm::vec2& location) : Segment(location, location) {};
Segment::Segment(const glm::vec2& start, const glm::vec2& end) : start(start), end(end) {};
glm::vec2 Segment::get_intersection()
{
}
float Segment::get_dx()
{
return end.x - start.x;
}
float Segment::get_length()
{
return glm::distance(start, end);
}
void Segment::move(const glm::vec2& delta)
{
start += delta;
end += delta;
}
glm::vec2 Segment::get_center()
{
}
std::ostream& operator<<(std::ostream& out, const Segment& segment)
{
out << "{(" << segment.start.x << ", " << segment.start.y << "), (" << segment.end.x << ", " << segment.end.y << ")}";
return out;
}

27
src/Segment.hpp Normal file
View File

@ -0,0 +1,27 @@
#ifndef Segment_h_
#define Segment_h_
#include <ostream>
#include "glm/vec2.hpp"
#include "glm/geometric.hpp"
struct Segment
{
glm::vec2 start, end;
Segment();
Segment(const glm::vec2&);
Segment(const glm::vec2&, const glm::vec2&);
glm::vec2 get_intersection();
float get_dx();
float get_length();
void move(const glm::vec2&);
glm::vec2 get_center();
};
std::ostream& operator<<(std::ostream&, const Segment&);
#endif

View File

@ -11,6 +11,70 @@ void sfw::set_magnitude(glm::vec2& vector, float magnitude)
vector = glm::normalize(vector) * magnitude;
}
bool sfw::lines_intersect(const Segment& segment_a, const Segment& segment_b)
{
glm::vec2 intersection;
return lines_intersect(segment_a, segment_b, intersection);
}
/*
from http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
*/
bool sfw::lines_intersect(const Segment& segment_a, const Segment& segment_b, glm::vec2& intersection)
{
float x1 = segment_a.start.x, y1 = segment_a.start.y, x2 = segment_a.end.x,
y2 = segment_a.end.y, x3 = segment_b.start.x, y3 = segment_b.start.y,
x4 = segment_b.end.x, y4 = segment_b.end.y;
float a1, a2, b1, b2, c1, c2; // Coefficients of line eqns.
float r1, r2, r3, r4; // 'Sign' values
float denom, num; // Intermediate values
// Compute a1, b1, c1, where line joining points 1 and 2 is "a1 x + b1 y + c1 = 0"
a1 = y2 - y1;
b1 = x1 - x2;
c1 = x2 * y1 - x1 * y2;
// Compute r3 and r4
r3 = a1 * x3 + b1 * y3 + c1;
r4 = a1 * x4 + b1 * y4 + c1;
// Check signs of r3 and r4. If both point 3 and point 4 lie on same side of
// line 1, the line segments do not intersect
if (r3 != 0 && r4 != 0 && std::copysign(1, r3) == std::copysign(1, r4))
{
return false;
}
// Compute a2, b2, c2
a2 = y4 - y3;
b2 = x3 - x4;
c2 = x4 * y3 - x3 * y4;
// Compute r1 and r2
r1 = a2 * x1 + b2 * y1 + c2;
r2 = a2 * x2 + b2 * y2 + c2;
// Check signs of r1 and r2. If both point 1 and point 2 lie on same side
// of second line segment, the line segments do not intersect
if (r1 != 0 && r2 != 0 && std::copysign(1, r1) == std::copysign(1, r2))
{
return false;
}
// Line segments intersect: compute intersection point
denom = a1 * b2 - a2 * b1;
if (denom == 0)
{
return false;
}
num = b1 * c2 - b2 * c1;
intersection.x = num / denom;
num = a2 * c1 - a1 * c2;
intersection.y = num / denom;
return true;
}
Box sfw::get_texture_box(SDL_Texture* texture)
{
int w, h;

View File

@ -9,6 +9,7 @@
#include <iomanip>
#include <stdexcept>
#include <map>
#include <cmath>
#include "SDL.h"
#include "SDL_image.h"
@ -19,6 +20,7 @@
#include "glm/gtx/vector_angle.hpp"
#include "Box.hpp"
#include "Segment.hpp"
#include "filesystem.hpp"
namespace sfw
@ -27,6 +29,8 @@ namespace sfw
glm::vec2 get_step(glm::vec2, glm::vec2, float);
void set_magnitude(glm::vec2&, float);
bool lines_intersect(const Segment&, const Segment&);
bool lines_intersect(const Segment&, const Segment&, glm::fvec2&);
Box get_texture_box(SDL_Texture*);
void fill_texture(SDL_Renderer*, SDL_Texture*, Uint8, Uint8, Uint8, Uint8 = 0xff);
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);