2

三角形のポインティング方向に基づいて、三角形を回転させて特定の方向に移動しようとしています。理論的には、方向(0〜360度)の正弦と余弦を計算し、これらの値をx位置とy位置に追加します。それはうまくいきません。

また、三角形は最初は下ではなく上を向いている必要があります。

public void speedUp() {
  float dirX, dirY;
  speed *= acceleration;
  if(speed > 50) speed = 50;
  println("dir: " + direction + " x: " + cos(direction) + " y: " + sin(direction));
  dirX = cos(direction);
  dirY = sin(direction);
  xPos+=dirX;
  yPos+=dirY;
}

public void redraw() {
  GL gl = pgl.beginGL();  // always use the GL object returned by beginGL
  gl.glTranslatef(xPos, yPos, 0);
  gl.glRotatef(direction, 0, 0, 1000);

  gl.glBegin(GL.GL_TRIANGLES);
  gl.glColor4f(0.1, 0.9, 0.7, 0.8);
  gl.glVertex3f(-10, -10, 0);    // lower left vertex
  gl.glVertex3f( 10, -10, 0);    // lower right vertex
  gl.glVertex3f( 0,  15, 0);    // upper vertex
  gl.glEnd();
}
4

4 に答える 4

5

極座標(角度と半径を使用して移動)からデカルト座標(xとyを使用して移動)に変換する必要があるようです。

式は次のようになります。

x = cos(angle) * radius;
y = sin(angle) * radius;

したがって、@ Lie Ryanが言及しているように、速度(極座標での半径)を乗算する必要もあります。

角度は度単位ですが、ラジアンで機能するcos、sinを使用する場合はradians()を使用するか、ラジアンを使用してglRotatefでdegrees()を使用します。

また、glPushMatrix()とglPopMatrix()も確認することをお勧めします。基本的に、それらは変換をネストすることを可能にします。ブロックを使用してどのような変換を行っても、それらはローカルでそのブロックにのみ影響します。

これが私が意味することです、w、a、s、dキーを使用してください:

import processing.opengl.*;
import javax.media.opengl.*;

float direction = 0;//angle in degrees
float speed = 0;//radius
float xPos,yPos;

void setup() {
  size(600, 500, OPENGL);
}

void keyPressed(){
  if(key == 'w') speed += 1;
  if(key == 'a') direction -= 10;
  if(key == 'd') direction += 10;
  if(key == 's') speed -= 1;
  if(speed > 10) speed = 10;
  if(speed < 0) speed = 0;
  println("direction: " + direction + " speed: " + speed);
}

void draw() {
  //update
  xPos += cos(radians(direction)) * speed;
  yPos += sin(radians(direction)) * speed;
  //draw
  background(255);
  PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; 
  GL gl = pgl.beginGL();
  gl.glTranslatef(width * .5,height * .5,0);//start from center, not top left

  gl.glPushMatrix();
  {//enter local/relative
    gl.glTranslatef(xPos,yPos,0);
    gl.glRotatef(direction-90,0,0,1);
    gl.glColor3f(.75, 0, 0);
    gl.glBegin(GL.GL_TRIANGLES);
    gl.glVertex2i(0, 10);
    gl.glVertex2i(-10, -10);
    gl.glVertex2i(10, -10);
    gl.glEnd();
  }//exit local, back to global/absolute coords
  gl.glPopMatrix();

  pgl.endGL();
}

プッシュおよびポップマトリックス呼び出しには実際には{}は必要ありません。視覚的な補助のように、それらを追加しました。また、トランスフォームを連結することで、プッシュ/ポップなしでこれを行うことができますが、必要なときにそれらが存在することを知っておくと便利です。その三角形からいくつかのGL_LINESを撃ちたいときに便利かもしれません...pewpew pew!

HTH

于 2010-11-21T14:25:24.340 に答える
5

あなたはあなたのユニットを台無しにしています。glRotatefを除いて、三角関数はラジアンを期待します。これは最も明白な間違いです。


また、speedスニペットで使用されることはありません。どういうわけかそれを使用しているすべてのフレームだと思いますが、貼り付けたコードには次のようなものがあります。

xPos+=dirX

これは基本的に「位置に方向を追加する」です。「が呼び出された瞬間に、指定された方向に正確に1単位移動しspeedUp()たい場合を除いて、あまり意味がありません。継続的な移動の通常のアプローチは次のとおりです。

// each frame:
xPos += dirX * speed * deltaTime;
yPos += dirY * speed * deltaTime;
于 2010-11-21T13:18:12.673 に答える
3

これを試して:

dirX = speed * cos(direction);
dirY = speed * sin(direction);
于 2010-11-21T13:22:37.223 に答える
3

あなたは明らかにOpenGlに慣れていないので、ローテーションを行うためにクォータニオンを調べることをお勧めします。これは、この問題に関する2つの非常に優れた記事です。GamedevNeheです。JMonkeyEngineのQuaternionクラスを使用することをお勧めします。保存可能なインターフェースやその他のインターフェースを削除するだけで、簡単に使用できます。ここにそれらがあります:JMonkey Source

私は自分のプロジェクトにもJME数学クラスを使用しています。私はすでにほとんどの依存関係を取り除きました、そしてあなたはここからいくつかのクラスをダウンロードすることができます:ボリュームシャドウ。ただし、Quaternionクラスがありませんが、Vector3f:Dが必要になります。

于 2010-11-21T13:04:13.577 に答える