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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue