Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix the ray2 line intersection

  • Loading branch information...
commit 928082e572f480aed9d3be89e9bfb0d4d15ebfbc 1 parent af84773
@Kazade authored
Showing with 80 additions and 25 deletions.
  1. +2 −2 include/kazmath/ray2.h
  2. +70 −16 src/ray2.c
  3. +8 −7 tests/test_ray2.cpp
View
4 include/kazmath/ray2.h
@@ -39,8 +39,8 @@ typedef struct kmRay2 {
} kmRay2;
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy);
-kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2 p1, const kmVec2 p2, kmVec2* intersection);
-kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2 p1, const kmVec2 p2, const kmVec2 p3, kmVec2* intersection, kmVec2* normal_out);
+kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection);
+kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out);
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
#ifdef __cplusplus
View
86 src/ray2.c
@@ -9,7 +9,54 @@ void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy)
ray->dir.y = vy;
}
-kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2 p1, const kmVec2 p2, kmVec2* intersection) {
+kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
+
+ float x1 = ray->start.x;
+ float y1 = ray->start.y;
+ float x2 = ray->start.x + ray->dir.x;
+ float y2 = ray->start.y + ray->dir.y;
+ float x3 = p1->x;
+ float y3 = p1->y;
+ float x4 = p2->x;
+ float y4 = p2->y;
+
+ float denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
+
+ //If denom is zero, the lines are parallel
+ if(denom > -kmEpsilon && denom < kmEpsilon) {
+ return KM_FALSE;
+ }
+
+ float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
+ float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
+
+ float x = x1 + ua * (x2 - x1);
+ float y = y1 + ua * (y2 - y1);
+
+ if(x < min(p1->x, p2->x) - kmEpsilon ||
+ x > max(p1->x, p2->x) + kmEpsilon ||
+ y < min(p1->y, p2->y) - kmEpsilon ||
+ y > max(p1->y, p2->y) + kmEpsilon) {
+ //Outside of line
+ printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
+ return KM_FALSE;
+ }
+
+ if(x < min(x1, x2) - kmEpsilon ||
+ x > max(x1, x2) + kmEpsilon ||
+ y < min(y1, y2) - kmEpsilon ||
+ y > max(y1, y2) + kmEpsilon) {
+ printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
+ return KM_FALSE;
+ }
+
+ intersection->x = x;
+ intersection->y = y;
+
+ return KM_TRUE;
+
+
+/*
kmScalar A1, B1, C1;
kmScalar A2, B2, C2;
@@ -17,9 +64,9 @@ kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2 p1, const kmVe
B1 = ray->dir.x;
C1 = A1 * ray->start.x + B1 * ray->start.y;
- A2 = p2.y - p1.y;
- B2 = p2.x - p1.x;
- C2 = A2 * p1.x + B2 * p1.y;
+ A2 = p2->y - p1->y;
+ B2 = p2->x - p1->x;
+ C2 = A2 * p1->x + B2 * p1->y;
double det = (A1 * B2) - (A2 * B1);
if(det == 0) {
@@ -30,18 +77,25 @@ kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2 p1, const kmVe
double x = (B2*C1 - B1*C2) / det;
double y = (A1*C2 - A2*C1) / det;
- if(x < min(p1.x, p2.x) - kmEpsilon || x > max(p1.x, p2.x) + kmEpsilon ||
- y < min(p1.y, p2.y) - kmEpsilon || y > max(p1.y, p2.y) + kmEpsilon) {
+ if(x < min(p1->x, p2->x) - kmEpsilon ||
+ x > max(p1->x, p2->x) + kmEpsilon ||
+ y < min(p1->y, p2->y) - kmEpsilon ||
+ y > max(p1->y, p2->y) + kmEpsilon) {
//Outside of line
- printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1.x, p1.y, p2.x, p2.y);
+ printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
return KM_FALSE;
}
- kmScalar x1 = ray->start.x, x2 = ray->start.x + ray->dir.x;
- kmScalar y1 = ray->start.y, y2 = ray->start.y + ray->dir.y;
+ kmScalar x1 = ray->start.x;
+ kmScalar x2 = ray->start.x + ray->dir.x;
- if(x < min(x1, x2) - kmEpsilon || x > max(x1, x2) + kmEpsilon ||
- y < min(y1, y2) - kmEpsilon || y > max(y1, y2) + kmEpsilon) {
+ kmScalar y1 = ray->start.y;
+ kmScalar y2 = ray->start.y + ray->dir.y;
+
+ if(x < min(x1, x2) - kmEpsilon ||
+ x > max(x1, x2) + kmEpsilon ||
+ y < min(y1, y2) - kmEpsilon ||
+ y > max(y1, y2) + kmEpsilon) {
printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
return KM_FALSE;
}
@@ -49,7 +103,7 @@ kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2 p1, const kmVe
intersection->x = x;
intersection->y = y;
- return KM_TRUE;
+ return KM_TRUE;*/
}
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2* normal_out) {
@@ -63,7 +117,7 @@ void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2* normal_out) {
//TODO: should check that the normal is pointing out of the triangle
}
-kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2 p1, const kmVec2 p2, const kmVec2 p3, kmVec2* intersection, kmVec2* normal_out) {
+kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out) {
kmVec2 intersect;
kmVec2 normal;
@@ -73,21 +127,21 @@ kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2 p1, const kmVec2
intersection->x = intersect.x;
intersection->y = intersect.y;
intersected = KM_TRUE;
- calculate_line_normal(p1, p2, &normal);
+ calculate_line_normal(*p1, *p2, &normal);
}
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
intersection->x = intersect.x;
intersection->y = intersect.y;
intersected = KM_TRUE;
- calculate_line_normal(p2, p3, &normal);
+ calculate_line_normal(*p2, *p3, &normal);
}
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
intersection->x = intersect.x;
intersection->y = intersect.y;
intersected = KM_TRUE;
- calculate_line_normal(p3, p1, &normal);
+ calculate_line_normal(*p3, *p1, &normal);
}
if(intersected) {
View
15 tests/test_ray2.cpp
@@ -12,7 +12,7 @@ TEST(test_line_segment_intersection) {
kmVec2 intersect;
- CHECK(kmRay2IntersectLineSegment(&ray, line_start, line_end, &intersect));
+ CHECK(kmRay2IntersectLineSegment(&ray, &line_start, &line_end, &intersect));
CHECK_CLOSE(0.0f, intersect.x, 0.001f);
CHECK_CLOSE(1.0f, intersect.y, 0.001f);
@@ -20,24 +20,25 @@ TEST(test_line_segment_intersection) {
ray.dir.y = -3.0f;
//Shouldn't reach the line (ray is too short)
- CHECK(!kmRay2IntersectLineSegment(&ray, line_start, line_end, &intersect));
+ CHECK(!kmRay2IntersectLineSegment(&ray, &line_start, &line_end, &intersect));
ray.dir.y = -10.0f;
ray.start.x = -100.0f;
//Shouldn't reach the line (ray is too far to the left)
- CHECK(!kmRay2IntersectLineSegment(&ray, line_start, line_end, &intersect));
+ CHECK(!kmRay2IntersectLineSegment(&ray, &line_start, &line_end, &intersect));
line_start.x = -150.0f;
//Should now hit the line as it's been extended
- CHECK(kmRay2IntersectLineSegment(&ray, line_start, line_end, &intersect));
+ CHECK(kmRay2IntersectLineSegment(&ray, &line_start, &line_end, &intersect));
//Check diagonal case
- kmRay2Fill(&ray, 0.0, 0.7f, 0.0f, -1.0f);
+ kmRay2Fill(&ray, 0.0, 1.0f, 0.0f, -1.0f);
kmVec2Fill(&line_start, -1.0f, 0.0f);
kmVec2Fill(&line_end, 10.0f, 5.0f);
- CHECK(kmRay2IntersectLineSegment(&ray, line_start, line_end, &intersect));
+ CHECK(kmRay2IntersectLineSegment(&ray, &line_start, &line_end, &intersect));
+ CHECK_CLOSE(0.0f, intersect.x, 0.001f);
CHECK(intersect.y > 0.0f);
}
@@ -60,7 +61,7 @@ TEST(test_triangle_intersection) {
ray.dir.y = -0.5f;
kmVec2 intersect, normal;
- CHECK(kmRay2IntersectTriangle(&ray, p1, p2, p3, &intersect, &normal));
+ CHECK(kmRay2IntersectTriangle(&ray, &p1, &p2, &p3, &intersect, &normal));
CHECK_CLOSE(0.0f, intersect.x, 0.001f);
CHECK_CLOSE(0.0f, intersect.y, 0.001f);
CHECK_CLOSE(0.0f, normal.x, 0.001f);
Please sign in to comment.
Something went wrong with that request. Please try again.