2010-11-21 3 views
2

Ich versuche, ein Dreieck in eine bestimmte Richtung zu drehen und zu bewegen, basierend auf der Richtung des Dreiecks. Theoretisch berechne ich den Sinus und den Kosinus der Richtung (0-360 Grad) und addiere diese Werte zur x- und y-Position, richtig? Es funktioniert einfach nicht.OpenGL + Verarbeitung: Drehen und bewegen basierend auf Richtung

Auch sollte das Dreieck am Anfang zeigen, nicht nach unten.

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(); 
} 
+0

Ich bin nicht sicher, ob ich das richtig verstehen, aber Sie wollen Ihr Dreieck in Richtung eine Richtung (x, y) und drehen in Richtung zu übersetzen, nicht wahr? –

Antwort

5

Es sieht so aus, als müssten Sie von Polarkoordinaten (die sich unter Verwendung eines Winkels und eines Radius bewegen) in kartesische Koordinaten umwandeln (die sich mit x und y bewegen).

Die Formel sieht ein bisschen wie folgt aus:

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

So, wie @Lie Ryan erwähnt, können Sie auch mit Geschwindigkeit multiplizieren müssen (die in Polarkoordinaten Ihr Radius ist).

Entweder haben Sie Ihre Winkel in Grad, aber verwenden Radian() wenn cos verwenden, sin wie sie mit Radiant arbeiten, oder verwenden Sie Radiant und Grad() mit glRotatef, verwenden Sie bis zu Ihnen

Sie können sich auch glPushMatrix() und glPopMatrix() ansehen. Im Grunde erlauben sie es, Transformationen zu verschachteln. Welche Transformationen Sie auch immer mit den Blöcken durchführen, sie wirken sich nur lokal auf diesen Block aus.

Hier ist, was ich meine, W, A, S, D Tasten:

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(); 
} 

Sie eigentlich nicht die {} für die Push- und Pop-Matrix Anrufe müssen, ich sie wie eine Sehhilfe hinzugefügt . Sie können dies auch ohne Push/Pop tun, indem Sie Ihre Transformationen verketten, aber es ist praktisch zu wissen, dass diese für Sie da sind, wenn Sie sie brauchen. Könnte sich als nützlich erweisen, wenn Sie einige GL_LINES aus diesem Dreieck schießen wollen ... Kirchenbank!

HTH

+0

Danke. Der Schussteil war richtig und wird später umgesetzt. Ich weiß, es ist eher, als würde man das Rad neu erfinden, aber ich benutze das Beispiel, um endlich mit OpenGL ein bisschen zu spielen. – Patrick

3

Sie sind offensichtlich zu OpenGl neu, also würde ich Ihnen empfehlen, dass Sie in quaternions schauen, um Ihre roations zu tun. Hier sind zwei ziemlich schöne Artikel zu diesem Thema: Gamedev und Nehe. Ich würde dir empfehlen, die Quaternion-Klasse von der JMonkeyEngine zu verwenden. Entfernen Sie einfach die speicherbaren und einige andere Schnittstellen und Sie können sie mit Leichtigkeit verwenden. Hier sind sie: JMonkey Source

Ich verwende auch die JME Math Klassen für meine eigenen Projekte. Ich habe bereits die meisten der Abhängigkeiten gestreift und Sie können einige Klassen von hier herunterladen: . Allerdings fehlt die Quaternion-Klasse, aber Sie benötigen Vector3f: D.

+1

Quaternions scheinen für 2D ein Overkill zu sein, nehme ich an. – Kos

+0

Oh, ich habe nicht gemerkt, dass es nur für 2D war :). Ja, Quaternions sind definitiv zu viel für 2D. Aber deine Antwort sollte schon zum Trick :). – iuiz

+1

Danke für die Links! Ich werde sie ausprobieren. Mit 31 Rep können Sie möglicherweise so viele Links posten und die Antwort bearbeiten, nur um sie zu vervollständigen. :) – Patrick

5

Sie haben Ihre Einheiten durcheinander gebracht. glRotatef excepts Grad und die trigonometrischen Funktionen erwarten Radianten. Dies ist der offensichtlichste Fehler.


Auch ist speed nie in Ihrem Snippet verwendet. Ich nehme an, dass jeder Frame Sie es irgendwie verwenden, aber in dem Code, den Sie klebte es:

xPos+=dirX

das ist im Grunde „add Richtung auf die Position“ - nicht viel Sinn machen, es sei denn, Sie wollen „bewegen sie genau 1 Einheit in der gegebenen Richtung instantenously im Moment, wenn speedUp() genannt wird der übliche Ansatz zur kontinuierlichen Bewegung wäre.

// each frame: 
xPos += dirX * speed * deltaTime; 
yPos += dirY * speed * deltaTime; 
+0

Ok, ich vermutete schon, dass es ein Radiant/Grad Problem sein würde. Die Geschwindigkeit wird absichtlich weggelassen, da ich gerade 1 Einheit bewegen möchte. Es läuft in einer Schleife, ausgelöst durch die Pfeiltasten. Danke für die Antwort! – Patrick

3

starten:

dirX = speed * cos(direction); 
dirY = speed * sin(direction);