开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜