OpenGL + Processing: Rotate and move based on direction
I'm trying to rotate and move a triangle into a certain direction, bas开发者_如何学运维ed on the pointing direction of the triangle. In theory, I calculate the sine and cosine of the direction (0-360 degrees) and add these values to the x- and y-position, right? It just doesn't work.
Also, the triangle should point up in the beginning, not down.
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();
}
It looks like you need to convert from polar coordinates(moving about using an angle and a radius) to cartesian coordinates(moving about using the x and y).
The formula looks a bit like this:
x = cos(angle) * radius;
y = sin(angle) * radius;
So, as @Lie Ryan mentions, you also need to multiply with speed (which is your radius in polar coordinates).
Either have your angle in degrees but use radians() when using cos,sin as they work with radians, or use radians, and use degrees() with glRotatef, up to you
Also, you might want to have a look at glPushMatrix() and glPopMatrix(). Bascially, they allow you to nest transformations. Whatever transformations you do withing the blocks, they affect just that block locally.
Here's what I mean, use w,a,s,d keys:
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();
}
You don't actually need the { } for the push and pop matrix calls, I added them like a visual aid. Also, you can do this without push/pop, by concatenating your transforms, but it's handy to know those are there for your when you need them. Might come in handy when you want to shoot some GL_LINES out of that triangle...pew pew pew!
HTH
You have your units messed up. glRotatef
excepts degrees and the trigonometrical functions expect radians. This is the most obvious mistake.
Also, speed
is never used in your snippet. I suppose that every frame you're using it somehow, but in the code you pasted there's:
xPos+=dirX
Which is basically "add direction to the position" - not making much sense, unless you want to "move it exactly 1 unit in the given direction instantenously at the moment when speedUp()
is called. The usual approach for continous movement would be to:
// each frame:
xPos += dirX * speed * deltaTime;
yPos += dirY * speed * deltaTime;
Try this:
dirX = speed * cos(direction);
dirY = speed * sin(direction);
You are obviously new to OpenGl, so I would recommend you, that you look into quaternions to do your roations. Here are two pretty nice article about this matter: Gamedev and Nehe. I would recommend you to use the Quaternion class from the JMonkeyEngine. Just remove the savable and some other interfaces and you can use them with ease. Here they are located: JMonkey Source
I also use the JME math classes for my own projects. I have already striped most of the dependencies and you can download some classes from here: Volume Shadow. However the Quaternion class is missing, but you WILL need Vector3f :D.
精彩评论