capture a click without cgrectmake

Posts: 164
Joined: 2010.10
Post: #1
i gave a scene on the screen with openglES object (suppose a fan)
i'm wondering how can i select the triangles of the fan.
with opengl i make something like:
glGetIntegerv (GL_VIEWPORT, viewport);
    glSelectBuffer (BUFSIZE, selectBuf);

    glRenderMode(GL_SELECT); // Enter the SELECT render mode

    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
    glLoadIdentity ();
    gluPickMatrix((GLdouble) point.x,
          (GLdouble) (viewport[3] - point.y),
          5.0, 5.0, viewport);
    PaintScreen(GL_SELECT);//function paint the objects.
    glPopMatrix ();
    glFlush ();

    hits = glRenderMode (GL_RENDER);

in openglES and iphone i have only cgrectmake?
do exist something like cgpolygon?
or i have to make a button in the center of the triangle?if so, how to find the center of the triangle if i translate rotate or scale the images on the screen?

Quote this message in a reply
Posts: 1,563
Joined: 2003.10
Post: #2
My approach to this would be to capture all incoming touch events (in your view's -touchesBegan:withEvent:, -touchesEnded:withEvent:, etc.), project your triangles into screen space, and mathematically test touch coordinates against each triangle to check if they're inside.

To project triangles into screen space, you'd ideally want to call something like gluProject on each of your vertices. glu isn't provided on the iPhone, so you'll have to implement your own gluProject given the formula listed toward the bottom of the man page. You could also use an open source implementation like this one.

Once you have the triangle's vertices in screen space and the touch coordinates, there are several different ways to test if the touch is inside. My current favorite is to use 2D cross product. Pseudocode:

bool isTouchInsideTriangle(point vertex0, point vertex1, point vertex2, point touch) {
    float cross0, cross1, cross2;
    cross0 = cross2D(touch.x - vertex0.x, touch.y - vertex0.y, vertex1.x - vertex0.x, vertex1.y - vertex0.y);
    cross1 = cross2D(touch.x - vertex1.x, touch.y - vertex1.y, vertex2.x - vertex1.x, vertex2.y - vertex1.y);
    cross2 = cross2D(touch.x - vertex2.x, touch.y - vertex2.y, vertex0.x - vertex2.x, vertex0.y - vertex2.y);
    return cross0 <= 0 && cross1 <= 0 && cross2 <= 0;

float cross2D(x0, y0, x1, y1) {
    return x0 * y1 - y0 * x1;

This assumes that the triangle's winding order is counter-clockwise and that your coordinate system's y axis runs from bottom to top. In other cases, you may need to change the test in isTouchInsideTriangle to use >= 0 instead of <= 0.
Quote this message in a reply
Posts: 164
Joined: 2010.10
Post: #3
many thanks!
you are a pit of science!

i have found another method:
do you think it could be interesting...?
Quote this message in a reply
Posts: 1,563
Joined: 2003.10
Post: #4
Also a legitimate technique. You may run into performance problems from glReadPixels, but certainly worth a try to find out.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  New iPiSoft Markerless Motion Capture for Dual Microsoft Kinects. mrbones 0 4,723 Nov 22, 2011 02:57 PM
Last Post: mrbones
  Sfxr - One Click Retro Sound Effects SethWillits 50 45,137 Aug 30, 2011 09:44 PM
Last Post: psykano
  atScreen: iPhone Simulator capture and rendering tool marcbell 0 4,084 Apr 5, 2010 01:43 PM
Last Post: marcbell