2013-10-03 131 views
0

我嘗試做一個簡單的比賽遊戲。 爲此,我得到了一輛汽車,它的位置是一個矢量,一個是它面向的方向。Java中的2D矢量旋轉

我有一個更新和輸入方法:

public void update(double delta) { 
    float rotation = 0; 
    if(movement.normalized().getY() < 0) { 
     rotation = (float) (2*Math.PI - Math.acos(movement.normalized().getX())); 
    } else { 
     rotation = (float) Math.acos(movement.normalized().getX()); 
    } 

    pos = pos.add(new Vector3f((float) (Math.cos(rotation) * (movement.length() - 2) * delta), (float) (Math.sin(rotation) * (movement.length() - 2) * delta), 0f)); 

    v1 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((rotation + basicAngel)) * radius), (float) (pos.getY() + (Math.sin((rotation + basicAngel)) * radius)), 0), new Vector2f(0, 0)); 
    v2 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - basicAngel) + rotation)) * radius), (float) (pos.getY() + Math.sin(((2*Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0)); 
    v3 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((Math.PI + rotation + basicAngel)) * radius), (float)(pos.getY() + Math.sin((Math.PI + rotation + basicAngel)) * radius), 0), new Vector2f(0, 0)); 
    v4 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((Math.PI - basicAngel) + rotation)) * radius), (float)(pos.getY() + Math.sin(((Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0)); 
    v5 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((windowAngel + rotation)) * windowRadius), (float)(pos.getY() + Math.sin((windowAngel + rotation)) * windowRadius), 0), new Vector2f(0, 0)); 
    v6 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - windowAngel) + rotation)) * windowRadius), (float)(pos.getY() + Math.sin(((2*Math.PI - windowAngel) + rotation)) * windowRadius), 0), new Vector2f(0, 0)); 
} 

第一if語句檢查是否低於0的歸一化矢量的y分量是。
確保汽車在水平軸下旋轉。
下一行將旋轉和速度應用到位置。
帶有v1 ... v4的程序塊計算汽車的角落進行渲染。
v5和v6是車窗的角落。

public void input() { 

    float tempX = movement.normalized().getX(); 
    float tempY = movement.normalized().getY(); 
    float tempLength = movement.length(); 

    if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) { 
     movement = movement.rotate(3); 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { 
     movement = movement.rotate(-3); 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_UP)) { 
     if (tempLength <= 7) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.2))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.2))); 

     } 
    } else { 
     if(tempLength > 2) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.05))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.05))); 

     } 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { 
     if (tempLength >= 0) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.2))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.2))); 

     } 
    } else { 
     if (tempLength < 2) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.05))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.05))); 

     } 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { 
     reset(); 
    } 
} 

前兩個if語句檢查是按下了左鍵還是右鍵。如果發生這種情況,運動vetor旋轉。 接下來的兩個語句檢查向上和向下鍵,並通過使用該式appliing速度,以移動矢量:

x = cos a * (l + speed) 
y = sin a * (l + speed) 

其中a是運動矢量
和升的角度的長度運動矢量

一切都應該正常工作,它的確如此,只是它有時會錯誤計算,以至於汽車的行駛方向與預期不同。

有人能幫我找到錯誤嗎?

回答

1

你不能使用acos來獲得角度。例如Math.cos(Math.PI * 3/4)和Math.cos(Math.PI * 5/4)都會給你-0.7071。看看餘弦曲線,看看爲什麼。 要獲得矢量的角度,請使用Math.atan2(y,x)。 另外,你爲什麼要將矢量轉換成一個角度,然後回到矢量。這沒有必要。你爲什麼不用方向上的歸一化矢量和速度上的浮點/雙精度來乘上每次更新?或者你可以做movement = movement.add(movement.normalized()。mul(0.2));

+0

謝謝你的回答。我沒有想過曬黑,但你說得對,那樣更好。我將在此之後應用您的建議並提交報告。 – henne90gen