保持两个旋转矩形碰撞检查的高精度 - SAT碰撞

问题描述

我实施了 SAT 来检查 2 个旋转矩形的碰撞。一切正常,但我注意到随着物体的移动,碰撞检查失去了精度。

我将方块的速度设置为 (v * 5) * dt。 我在模拟中确定 5 是一米。

在某些时候,在物体的那个位置检测到碰撞:

enter image description here

你能告诉我如何保持碰撞检查的高精度吗?我在某处找到了多重采样可以提供帮助的信息。你能向我解释一下它是什么,它如何解决精度损失问题以及如何实现它?

我在 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;

还有碰撞检查。这是这篇文章的解决方案:How to check intersection between 2 rotated rectangles? 移植到帕斯卡:

类型

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;

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)