collision - 保持两个旋转矩形碰撞检查的高精度 - SAT碰撞
问题描述
我实现了 SAT 来检查 2 个旋转矩形的碰撞。一切正常,但我注意到随着物体的移动,碰撞检查会失去精度。
我将正方形的速度设置为 (v * 5) * dt。在我的模拟中,我确定 5 是一米。
在某些时候,在对象的该位置检测到碰撞:
你能告诉我如何保持碰撞检查的高精度吗?我在某处发现了多重采样可以提供帮助的信息。你能给我解释一下它是什么,它是如何解决精度损失问题的以及如何实现的?
我在 fpc (pascal / lazarus) 中编写了我的解决方案,但这可能并不重要。下面是代码:
创建矩形角:
rectangle[0].x := position.x-15;
rectangle[0].y := position.y-35;
rectangle[1].x := position.x+15;
rectangle[1].y := position.y-35;
rectangle[2].x := position.x+15;
rectangle[2].y := position.y+26;
rectangle[3].x := position.x-15;
rectangle[3].y := position.y+26;
旋转矩形:
for i:= 0 to 3 do
begin
tempX := rectangle[i].x - position.x;
tempY := rectangle[i].y - position.y;
// now apply rotation
rotatedX := tempX * cos(DegToRad(ang)) - tempY * sin(DegToRad(ang));
rotatedY := tempX * sin(DegToRad(ang)) + tempY * cos(DegToRad(ang));
tempRectangle[i].x := position.x + rotatedX;
tempRetangle[i].y := position.y + rotatedY;
end;
rotatedRectangle:=tempRectangle;
和碰撞检查。这是这篇文章的解决方案:如何检查 2 个旋转矩形之间的交集? 移植到帕斯卡:
类型
TRectangle = array[0..3] of TMyPoint;
TMyPoint = record
x:real;
y:real;
end;
碰撞检查:
res:=true;
for i := 0 to 1 do //2 cars
begin
// for each polygon, look at each edge of the polygon, and determine if it separates
// the two shapes
polygon := polygons[i];
for i1 := 0 to Length(polygon)-1 do
begin
// grab 2 vertices to create an edge
i2 := (i1 + 1) mod 4;
p11 := polygon[i1];
p22 := polygon[i2];
// find the line perpendicular to this edge
normal.x := p22.y - p11.y;
normal.y := p11.x - p22.x;
minA.assigned := false;
maxA.assigned := false;
// for each vertex in the first shape, project it onto the line perpendicular to the edge
// and keep track of the min and max of these values
for j := 0 to 3 do
begin
projected := normal.x * rectangleA[j].x + normal.y * rectanglA[j].y;
if ((minA.assigned = false) or (projected < minA.value)) then
begin
minA.value := projected;
minA.assigned:=true;;
end;
if ((maxA.assigned = false) or (projected > maxA.value)) then
begin
maxA.value := projected;
maxA.assigned := true;
end;
end;
// for each vertex in the second shape, project it onto the line perpendicular to the edge
// and keep track of the min and max of these values
minB.assigned:=false;
maxB.assigned:=false;
for j := 0 to 3 do
begin
projected := normal.x * rectanglB[j].x + normal.y * rectanglB[j].y;
if ((minB.assigned = false) or (projected < minB.value)) then
begin
minB.value := projected;
minB.assigned :=true;
end;
if ((maxB.assigned=false) or (projected > maxB.value)) then
begin
maxB.value := projected;
maxB.assigned:=true;
end;
end;
// if there is no overlap between the projects, the edge we are looking at separates the two
// polygons, and we know there is no overlap
if ((maxA.value < minB.value) or (maxB.value < minA.value)) then
begin
res := false;
end;
end;
end;
result := res;
解决方案
推荐阅读
- javascript - 避免雪花中存储过程的重复
- python - 如何使用 BeautifulSoup 获取 p 下的 href 链接
- c++ - 创建 RAII 类时应该如何处理错误?
- typescript - 您可以在单个文件或代码块上拒绝严格模式等吗?
- python - Python recv 丢弃蓝牙数据?
- python - 用 Python 中的 BeautifulSoup、Selenium 解析表格
- google-sheets - 使用脚本硬编码条件格式
- razor - 如何使用 2sxc 和 ac# razor 模板将 CSS 类的动态列表添加到 div?
- android - 使用 react-native-elements 在 android 中显示的图标不正确
- mongodb - 无法在 ubuntu windows 中启动 mongodb 服务器