1
\$\begingroup\$

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

\$\endgroup\$
2

1 Answer 1

4
\$\begingroup\$

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;
}
\$\endgroup\$
18
  • \$\begingroup\$ Okay Marco, I am a bit unsure on how to implement this in my piece of code? \$\endgroup\$ Sep 28, 2012 at 4:33
  • \$\begingroup\$ Marco : thanks a lot. This really solved my problem. \$\endgroup\$ Sep 28, 2012 at 12:05
  • \$\begingroup\$ 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. \$\endgroup\$ Sep 28, 2012 at 12:29
  • \$\begingroup\$ The center of rotation of the new triangle is (0,0,0) or something else? \$\endgroup\$
    – pinco
    Sep 28, 2012 at 15:09
  • \$\begingroup\$ 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); \$\endgroup\$ Oct 1, 2012 at 5:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .