2016-10-26 20 views
0

Итак, я пытаюсь получить обнаружение столкновений и реакцию, работающие в моем игровом проекте, используя теорему о разделительной оси. Мне удалось обнаружить столкновение, но для жизни я не могу понять, как реагировать на него. Я пытаюсь найти минимальный вектор перевода, но я не уверен, как сделать его фактическим вектором, чтобы я мог рассчитать, как реагировать на столкновение. Я прочитал учебник после учебника, и я рассмотрел многие ранее заданные вопросы здесь, но мне не удается понять, как его реализовать. У меня очень трудное время понять, как найти и использовать 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; 
} 

А вот простой класс проекции:

class Projection{ 
    public Vector2D minVec, maxVec; 
    public float min, max; 
    public Vector2D axis = new Vector2D(0, 0); 
    public Projection(float min, float max, Vector2D minVec, Vector2D maxVec, Vector2D axis){ 
     this.min = min; 
     this.max = max; 
     this.minVec = minVec; 
     this.maxVec = maxVec; 
     this.axis = axis; 
    } 

    public float minDot(){ 
     return axis.dot(minVec); 
    } 

    public float maxDot(){ 
     return axis.dot(maxVec); 
    } 
} 

Если какой-либо дополнительный код нужен, я был бы счастлив, чтобы поставить его. Простите, что я не понимаю, как найти и использовать MTV, но любая помощь действительно оценена. Спасибо!

ответ

1

Это очень просто на самом деле. Вам нужно знать углы осей, которые вы использовали, и насколько глубоко сталкиваются 2 объекта в каждом случае (глубина - это длина области прогнозируемого столкновения).

Преобразовать каждые данные в вектор с помощью следующей методики:

var vecX = Math.cos(axisAngle) * deepness; 
var vecY = Math.sin(axisAngle) * deepness; 

Затем добавьте вместе векторы:

var sumX = vec1X + vec2X + ...; 
var sumY = vec1Y + vec2Y + ...; 

Afted это вы получаете векторную сумму, которая является вектором смещения вы необходимо использовать (из-за магии)

enter image description here

+0

Этот ответ al наиболее полно отвечает на мой вопрос! Единственная проблема, с которой я столкнулся сейчас, это то, что я не уверен, как найти глубину. Вы сказали мне, что это длина области прогнозируемого столкновения. Я предполагаю, что это основано на оси (это, вероятно, подразумевается), но я не уверен, как получить фактическую длину в единицах или в пикселях в основном, потому что единственное, что я могу представить, похоже на глубину, - это перевод переменная, которая попадает в тысячи. Имеет ли смысл этот вопрос? Тем не менее, спасибо за ваш ответ, он предоставил мне еще очень полезную информацию. – Gyo

+0

@Gyo Добавить изображение –

+0

Картина определенно помогает мне понять ее концептуально, но я до сих пор не знаю, как правильно получить природу. Я думаю, что мне нужно получить расстояние x и y между двумя точками на оси (вот и изображение, которое я сделал, чтобы объяснить: [image] (http://prntscr.com/czbqgf)) И я думаю что расстояние x и y вместе будет mtv для этой оси. Это правильно? Это единственный способ, которым я могу думать об этом, чтобы получить глубину в соответствующих единицах. Я прошу прощения, если мне кажется, что я не получаю его, но я пытаюсь. @ Bálint – Gyo