Java 利用分离轴定理求最小平移向量

Java 利用分离轴定理求最小平移向量,java,collision-detection,separating-axis-theorem,Java,Collision Detection,Separating Axis Theorem,因此,我一直在尝试使用分离轴定理在我的游戏项目中实现碰撞检测和响应。我已经设法检测到了碰撞,但就我的一生而言,我无法想出如何应对它。我试图找到最小平移向量,但我不确定如何使其成为实际向量,以便计算如何响应碰撞。我读了一本又一本教程,在这里我看了很多以前问过的问题,但我不知道如何实现它。我真的很难理解如何找到和使用MTV,所以如果有人真的能帮助我理解,也许能给我一些例子,让我在实践中理解它,而不仅仅是理论上的,我将不胜感激,对于由此带来的不便,我深表歉意。我的代码确实成功地检测到了冲突,下面是它:

因此,我一直在尝试使用分离轴定理在我的游戏项目中实现碰撞检测和响应。我已经设法检测到了碰撞,但就我的一生而言,我无法想出如何应对它。我试图找到最小平移向量,但我不确定如何使其成为实际向量,以便计算如何响应碰撞。我读了一本又一本教程,在这里我看了很多以前问过的问题,但我不知道如何实现它。我真的很难理解如何找到和使用MTV,所以如果有人真的能帮助我理解,也许能给我一些例子,让我在实践中理解它,而不仅仅是理论上的,我将不胜感激,对于由此带来的不便,我深表歉意。我的代码确实成功地检测到了冲突,下面是它:

//NOTE: This is within the HitPolygon class, so "this" is referencing itself as a polygon
public Projection project(Vector2D axis){

    float min = axis.dot(this.getVertices().get(0));
    float max = min;
    Vector2D vecMax  = new Vector2D(0, 0), vecMin = new Vector2D(0, 0);

    for(int i = 1; i < this.getVertices().size(); i++){
        float p = axis.dot(this.getVertices().get(i));
        if(p < min){
            min = p;
            vecMin = this.getVertices().get(i);
        }
        if(p > max){
            max = p;
            vecMax = this.getVertices().get(i);
        }
    }

    Projection result = new Projection(min, max, vecMin, vecMax, axis);

    return result;

}

public boolean contains(Projection p1, Projection p2){
    return(p1.min >= p2.min && p1.min <= p2.max) || (p1.max >= p2.min && p1.max <= p2.max);
}

public boolean overlap(Projection a, Projection b){
    if(contains(a, b)) return true;
    if(contains(b, a)) return true;

    return false;
}

public boolean collide(HitPolygon b){

    ArrayList<Vector2D> axes1 = this.getAxes(0);
    ArrayList<Vector2D> axes2 = b.getAxes(0);

    for(int i = 0; i < axes1.size(); i++){
        Vector2D axis = axes1.get(i);
        Projection p1 = this.project(axis), p2 = b.project(axis);

        if(!overlap(p1, p2)) return false;
        else{
            float start = p1.min > p2.min ? p1.min : p2.min;
            float end = p1.max < p2.max ? p1.max : p2.max;
            float translation = end - start;
            //translation might be the MTV, more or less, but it's not a vector and I don't know how to turn it into one.
        }
    }

    for(int i = 0; i < axes2.size(); i++){
        Vector2D axis = axes2.get(i);
        Projection p1 = this.project(axis), p2 = b.project(axis);
        if(!overlap(p2, p1)) return false;
        else{

        }
    }
    System.out.println("collide");
    return true;
}

如果需要任何额外的代码,我很乐意提供。请原谅我对如何查找和使用MTV缺乏了解,但我们真诚感谢您的帮助。谢谢大家!

其实很简单。您需要知道所使用的轴的角度,以及在每种情况下两个对象碰撞的深度(深度是投影碰撞区域的长度)

使用以下技术将每个数据转换为向量:

var vecX = Math.cos(axisAngle) * deepness;
var vecY = Math.sin(axisAngle) * deepness;
然后,将向量相加:

var sumX = vec1X + vec2X + ...;
var sumY = vec1Y + vec2Y + ...;
在此之后,您将得到一个和向量,这是您需要使用的位移向量(因为魔术)


这个答案几乎完全回答了我的问题!在这一点上我唯一的问题是我不确定如何找到深度。你告诉我这是预计碰撞面积的长度。我假设这是基于轴的(这可能是隐含的),但我不确定如何得到以单位或像素为单位的实际长度,因为我能得到的唯一类似于深度的东西是平移变量,它以千为单位。这个问题有意义吗?尽管如此,谢谢你的回答,它仍然为我提供了一些非常有用的信息。@Gyo我添加了一张图片这张图片确实帮助我从概念上理解它,但我仍然不确定如何正确获得深度。我想我需要得到轴上两点之间的x和y距离(这是我用来解释的图像:),我想x和y距离加起来就是该轴的mtv。是这样吗?这是我能想到的在适当单位获得深度的唯一方法。我很抱歉,如果我似乎不明白,我正在努力@巴哈lint@Gyo您需要获得每个轴的深度,使用这些轴的角度创建向量,然后将它们相加。如果您知道这两个点之间的x和y差,那么可以使用
深度=sqrt(x*x+y*y)
公式来计算它们之间的距离。你目前提出的方法(你几乎做同样的事情,但只在一个轴上)不起作用。比如说,。如果你用
v
向量移动蓝色形状,那么你就得不到你想要的。另外,如果你知道两个点的x和y位置,那么你可以使用
Vector2D vec=new Vector2D(pos1.x-pos2.x,pos1.y-pos2.y)
获得向量。
var sumX = vec1X + vec2X + ...;
var sumY = vec1Y + vec2Y + ...;