Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

OpenGL ES - Android.

Hello all, I am unable to rotate the triangle accordingly in such a way that its tip always points to my finger.

What i did : Constructed a triangle in by GL.GL_TRIANGLES. Added touch events to it. I can rotate the triangle along my Z-axis successfully. Even made the vector class for it.

What i need : Each time when I touch the screen, I want to rotate the triangle to face the touch point.

Need some help.

Here's what i implemented. I wonder that where i am going wrong?

My code :

public class Graphic2DTriangle {


private FloatBuffer vertexBuffer;
private ByteBuffer indexBuffer;

private float[] vertices = {

   -1.0f,-1.0f, 0.0f,  
   2.0f, 0.0f, 0.0f,  
   -1.0f, 1.0f, 0.0f           
};

private byte[] indices = { 0, 1, 2 };

public Graphic2DTriangle() {
  ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  vbb.order(ByteOrder.nativeOrder()); // Use native byte order
  vertexBuffer = vbb.asFloatBuffer(); // Convert byte buffer to float
  vertexBuffer.put(vertices);         // Copy data into buffer
  vertexBuffer.position(0);           // Rewind

  // Setup index-array buffer. Indices in byte.
  indexBuffer = ByteBuffer.allocateDirect(indices.length);
  indexBuffer.put(indices);
  indexBuffer.position(0);
}

public void draw(GL10 gl) {
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  }
}

My SurfaceView class where i've done some Touch Events.

public class BallThrowGLSurfaceView extends GLSurfaceView{

MySquareRender _renderObj;
View _viewObj;
float oldX,oldY,dX,dY;
final float TOUCH_SCALE_FACTOR = 0.6f;
Vector2 touchPos = new Vector2();
float angle=0;

public BallThrowGLSurfaceView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    _renderObj = new MySquareRender(context);
    this.setRenderer(_renderObj);
    this.setRenderMode(RENDERMODE_WHEN_DIRTY);


}

   public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
   touchPos.x = (2*event.getX())/getWidth()   -1.0f;
       touchPos.y = (2*event.getY())/getHeight()  -1.0f;
       Log.i("Co-ord", touchPos.x+"hh"+touchPos.y);
       switch(event.getAction()){
          case MotionEvent.ACTION_MOVE :                                                                                                                                       

                _renderObj.mAngle = touchPos.angle() - 180;
                     requestRender();
                    Log.i("AngleCo-ord", _renderObj.mAngle +"hh");
                }
              oldX = touchPos.x;
              oldY = touchPos.y;
              Log.i("OldCo-ord", oldX+" hh "+oldY);
              return true;
        }


 }

Last but not the least. My vector2 class.

   public class Vector2 {
public static float TO_RADIANS = (1 / 180.0f) * (float) Math.PI;
public static float TO_DEGREES = (1 / (float) Math.PI) * 180;
public float x, y;

public Vector2() {
}

public Vector2(float x, float y) {
    this.x = x;
    this.y = y;
}

public Vector2(Vector2 other) {
    this.x = other.x;
    this.y = other.y;
}

public Vector2 cpy() {
    return new Vector2(x, y);
}

public Vector2 set(float x, float y) {
    this.x = x;
    this.y = y;
    return this;
}

public Vector2 set(Vector2 other) {
    this.x = other.x;
    this.y = other.y;
    return this;
}

public Vector2 add(float x, float y) {
    this.x += x;
    this.y += y;
    return this;
}

public Vector2 add(Vector2 other) {
    this.x += other.x;
    this.y += other.y;
    return this;
}

public Vector2 sub(float x, float y) {
    this.x -= x;
    this.y -= y;
    return this;
}

public Vector2 sub(Vector2 other) {
    this.x -= other.x;
    this.y -= other.y;
    return this;
}

public Vector2 mul(float scalar) {
    this.x *= scalar;
    this.y *= scalar;
    return this;
}

public float len() {
    return FloatMath.sqrt(x * x + y * y);
}

public Vector2 nor() {
    float len = len();
    if (len != 0) {
        this.x /= len;
        this.y /= len;
    }
    return this;
}

public float angle() {
    float angle = (float) Math.atan2(y, x) * TO_DEGREES;
    if (angle < 0)
        angle += 360;
    return angle;
}

public Vector2 rotate(float angle) {
    float rad = angle * TO_RADIANS;
    float cos = FloatMath.cos(rad);
    float sin = FloatMath.sin(rad);

    float newX = this.x * cos - this.y * sin;
    float newY = this.x * sin + this.y * cos;

    this.x = newX;
    this.y = newY;

    return this;
}

public float dist(Vector2 other) {
    float distX = this.x - other.x;
    float distY = this.y - other.y;
    return FloatMath.sqrt(distX * distX + distY * distY);
}

public float dist(float x, float y) {
    float distX = this.x - x;
    float distY = this.y - y;
    return FloatMath.sqrt(distX * distX + distY * distY);
}

public float distSquared(Vector2 other) {
    float distX = this.x - other.x;
    float distY = this.y - other.y;
    return distX * distX + distY * distY;
}

public float distSquared(float x, float y) {
    float distX = this.x - x;
    float distY = this.y - y;
    return distX * distX + distY * distY;
}
}

PS : Please see the image for better understanding.

Triangle Problem

share|improve this question
    
    
@tsturzl Thank you, But i am unable to understand it. –  Sid Sep 27 '12 at 18:06
add comment

1 Answer

up vote 4 down vote accepted

You can use atan2 to find the angle of rotation. If (tx, ty) is your touch coordinate and (x,y) is the center of your rotation you can call

double rot = Math.atan2(ty-y, tx-x); //first y then x

rot is an angle in radians [-pi, pi] just rotate your triangle using it


EDIT

Implementation.

Assuming that you have setted up opengl so that screen coordinates goes from [-1, 1] on both the axes, you need to scale the touch coordinates so that they match your opengl coordinates like this.

touchPos.x = (2*event.getX())/getWidth()  -1.f;
touchPos.y = (2*event.getY())/getHeight() -1.f;

From your code above I think that your center of rotation is (0,0,0) so you don't need to translate touchPos.

touchPos is a Vector2, your class already have an angle() method.

float angle = touchPos.angle() - 90;

I'm not really sure about -90 degrees here, don't have time to test the code so if the rotation is off of 90 degrees adjust this. I don't know how the rest of your code is implemented but probably you should edit your onTouchEvent and set

_renderObj.mAngle = angle;

Reassuming your should replace onTouchEvent with this

public boolean onTouchEvent(MotionEvent event) {
    touchPos.x = (2*event.getX())/getWidth()  -1.f;
    touchPos.y = (2*event.getY())/getHeight() -1.f;
    Log.i("Co-ord", touchPos.x+"hh"+touchPos.y);
    switch(event.getAction()){
    case MotionEvent.ACTION_MOVE:
        _renderObj.mAngle = touchPos.angle() - 90;
        requestRender();
        Log.i("AngleCo-ord", _renderObj.mAngle +"hh");
    }
    oldX = touchPos.x;
    oldY = touchPos.y;
    Log.i("OldCo-ord", oldX+" hh "+oldY);
    return true;
}
share|improve this answer
    
Okay Marco, I am a bit unsure on how to implement this in my piece of code? –  Sid Sep 28 '12 at 4:33
    
Marco : thanks a lot. This really solved my problem. –  Sid Sep 28 '12 at 12:05
    
This really solved my problem. So i tried this in another example, the results are being opposite, where ever i point my finger, the triangle seems to point in another random direction. –  Sid Sep 28 '12 at 12:29
    
The center of rotation of the new triangle is (0,0,0) or something else? –  Marco Martinelli Sep 28 '12 at 15:09
    
Marco : the center of rotation of the triangle changes with respect to the the center of the ball, and by scaling i didn't actually get you, i have a background which is basically a square, scaled as... gl.glScalef(6.5f, 4.0f, 0.0f); and gl.glTranslatef(0.0f, 0.0f, -3.0f); and for the triangle it is translated at.... gl.glTranslatef(2.0f, 3.0f, 0.0f); –  Sid Oct 1 '12 at 5:21
show 13 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.