line intersection formula from GraphicsGems; started Segment class
This commit is contained in:
parent
cea0bb5a21
commit
1861b80aa4
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -11,6 +11,70 @@ void sfw::set_magnitude(glm::vec2& vector, float magnitude)
|
||||||
vector = glm::normalize(vector) * 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)
|
Box sfw::get_texture_box(SDL_Texture* texture)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
#include "glm/gtx/vector_angle.hpp"
|
#include "glm/gtx/vector_angle.hpp"
|
||||||
|
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
|
#include "Segment.hpp"
|
||||||
#include "filesystem.hpp"
|
#include "filesystem.hpp"
|
||||||
|
|
||||||
namespace sfw
|
namespace sfw
|
||||||
|
@ -27,6 +29,8 @@ namespace sfw
|
||||||
|
|
||||||
glm::vec2 get_step(glm::vec2, glm::vec2, float);
|
glm::vec2 get_step(glm::vec2, glm::vec2, float);
|
||||||
void set_magnitude(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*);
|
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*, Uint8, Uint8, Uint8, Uint8 = 0xff);
|
||||||
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
|
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
|
||||||
|
|
Loading…
Reference in New Issue