Fix retard rectangle-point collision check
This commit is contained in:
parent
de510b1f14
commit
5a22d09e47
@ -109,47 +109,63 @@ namespace egn{
|
|||||||
//If not in the rectangle, we can have 1 or 2 candidate edges to project onto. We want the closest one
|
//If not in the rectangle, we can have 1 or 2 candidate edges to project onto. We want the closest one
|
||||||
//to the input point.
|
//to the input point.
|
||||||
math::vec3<float> cand1, cand2;
|
math::vec3<float> cand1, cand2;
|
||||||
if(r1 > r2){
|
|
||||||
cand1 = lineseg_point_proj(line_segment{l.point1, l.point4}, r);
|
|
||||||
if(r4 > r5){
|
|
||||||
//candidates be and bc
|
|
||||||
cand2 = lineseg_point_proj(line_segment{l.point1, l.point2}, r);
|
|
||||||
}else if(r6 < r5){
|
|
||||||
//candidates be and de
|
|
||||||
cand2 = lineseg_point_proj(line_segment{l.point3, l.point4}, r);
|
|
||||||
}else{
|
|
||||||
//candidate be
|
|
||||||
return cand1;
|
|
||||||
}
|
|
||||||
}else if(r3 < r2){
|
|
||||||
cand1 = lineseg_point_proj(line_segment{l.point2, l.point3}, r);
|
|
||||||
if(r4 > r5){
|
|
||||||
//candidates cd and bc
|
|
||||||
cand2 = lineseg_point_proj(line_segment{l.point1, l.point2}, r);
|
|
||||||
}else if(r6 < r5){
|
|
||||||
//candidates cd and de
|
|
||||||
cand2 = lineseg_point_proj(line_segment{l.point3, l.point4}, r);
|
|
||||||
}else{
|
|
||||||
//candidate cd
|
|
||||||
return cand1;
|
|
||||||
}
|
|
||||||
}else if(r4 > r5){
|
|
||||||
//candidate bc
|
|
||||||
cand1 = lineseg_point_proj(line_segment{l.point1, l.point2}, r);
|
|
||||||
return cand1;
|
|
||||||
}else if(r6 < r5){
|
|
||||||
//candidate de
|
|
||||||
cand1 = lineseg_point_proj(line_segment{l.point3, l.point4}, r);
|
|
||||||
return cand1;
|
|
||||||
}else{
|
|
||||||
//point is inside rectangle
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If we make it here, there are 2 candidate edges and we pick the closer one
|
/*
|
||||||
math::vec3<float> diff1 = r - cand1;
|
now we divide the plane into a voronoi diagram where each region is closest
|
||||||
math::vec3<float> diff2 = r - cand2;
|
to either a line or a point on the rectangle. We use the r values calculated above
|
||||||
return (diff1 * diff1) > (diff2 * diff2) ? cand1 : cand2;
|
to determine which region the point lies within.
|
||||||
|
|
||||||
|
a b c
|
||||||
|
. .
|
||||||
|
1 a1 . b1 . c1
|
||||||
|
. .
|
||||||
|
- - - - -*---------*- - - - -
|
||||||
|
| |
|
||||||
|
2 a2 | b2 | c2
|
||||||
|
| |
|
||||||
|
- - - - -*---------*- - - - -
|
||||||
|
. .
|
||||||
|
3 a3 . b3 . c3
|
||||||
|
. .
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(r5 < r4){
|
||||||
|
//in column a
|
||||||
|
if(r2 < r1){
|
||||||
|
//a3
|
||||||
|
return l.point1;
|
||||||
|
}else if(r2 > r3){
|
||||||
|
//a1
|
||||||
|
return l.point2;
|
||||||
|
}else{
|
||||||
|
//a2
|
||||||
|
return lineseg_point_proj(line_segment{l.point1, l.point2}, r);
|
||||||
|
}
|
||||||
|
}else if (r5 > r6){
|
||||||
|
//in column c
|
||||||
|
if(r2 < r1){
|
||||||
|
//c3
|
||||||
|
return l.point4;
|
||||||
|
}else if(r2 > r3){
|
||||||
|
//c1
|
||||||
|
return l.point3;
|
||||||
|
}else{
|
||||||
|
//c2
|
||||||
|
return lineseg_point_proj(line_segment{l.point3, l.point4}, r);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//in column b
|
||||||
|
if(r2 < r1){
|
||||||
|
//b3
|
||||||
|
return lineseg_point_proj(line_segment{l.point1, l.point4}, r);
|
||||||
|
}else if(r2 > r3){
|
||||||
|
//b1
|
||||||
|
return lineseg_point_proj(line_segment{l.point2, l.point3}, r);
|
||||||
|
}else{
|
||||||
|
//b2
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon){
|
/* bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon){
|
||||||
return l.check_collision(r, epsilon);
|
return l.check_collision(r, epsilon);
|
||||||
@ -259,7 +275,8 @@ namespace egn{
|
|||||||
|
|
||||||
//find the nearest point on the rectangle to the newly created coplanar point and see if it's within
|
//find the nearest point on the rectangle to the newly created coplanar point and see if it's within
|
||||||
//epsilon of the original point
|
//epsilon of the original point
|
||||||
return math::magnitude(r - rectangle_point_coplanar_proj(l, projected_point)) <= epsilon;
|
math::vec3<float> proj_dist = r - rectangle_point_coplanar_proj(l, projected_point);
|
||||||
|
return (proj_dist * proj_dist) <= (epsilon * epsilon); //avoid square root
|
||||||
}
|
}
|
||||||
bool check_collision(const point& l, const point& r, float epsilon){
|
bool check_collision(const point& l, const point& r, float epsilon){
|
||||||
return math::fuzzy_eq(l, r, epsilon);
|
return math::fuzzy_eq(l, r, epsilon);
|
||||||
|
|||||||
66
src/tests/collision/rectangle.cpp
Normal file
66
src/tests/collision/rectangle.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2021 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "engine/collision.hpp"
|
||||||
|
|
||||||
|
bool run_test(const egn::rectangle& l, const egn::point& r, bool desired_result){
|
||||||
|
if(egn::check_collision(l, r) != desired_result){
|
||||||
|
printf("FAIL\n");
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
printf("Succ\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct testval{
|
||||||
|
egn::point p;
|
||||||
|
bool desres;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
egn::rectangle rect;
|
||||||
|
rect.point1 = {-1, -2, 1};
|
||||||
|
rect.point2 = {-1, 3, 1};
|
||||||
|
rect.point3 = {2, 3, 1};
|
||||||
|
rect.point4 = {2, -2, 1};
|
||||||
|
|
||||||
|
egn::point p;
|
||||||
|
|
||||||
|
testval tests[] = {
|
||||||
|
{{0,0, 1}, true},
|
||||||
|
{{1,1, 1}, true},
|
||||||
|
{{-1,3, 1}, true},
|
||||||
|
{{2,-2, 1}, true},
|
||||||
|
{{0,0, 0}, false},
|
||||||
|
{{0,0, -1}, false},
|
||||||
|
{{-1.1,0, 1}, false},
|
||||||
|
{{2.1,0, 1}, false},
|
||||||
|
{{0,-2.1, 1}, false},
|
||||||
|
{{0,3.1, 1}, false},
|
||||||
|
{{-1.1,3.1, 1}, false},
|
||||||
|
{{2.1,3.1, 1}, false},
|
||||||
|
{{2.1,-2.1, 1}, false},
|
||||||
|
};
|
||||||
|
|
||||||
|
for(const auto& [point,desres] : tests){
|
||||||
|
if(bool rv;rv = !run_test(rect, point, desres))
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user