Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: drawing an arrow: A line + a cone (problems with the cone, rotation!)

  1. #1
    Intern Contributor
    Join Date
    Aug 2011
    Posts
    73

    drawing an arrow: A line + a cone (problems with the cone, rotation!)

    What seems to be the problem with this rotation here (python-code) ?

    I'm drawing an arrow from (x1,y1,z2) to (x2,y2,z2). Please see this and I hope you can explain what is going on...
    Code :
    def coordSysArrow(x1, y1, z1, x2, y2, z2):
        glPushMatrix()
        glPushAttrib( GL_POLYGON_BIT ) # includes GL_CULL_FACE
        glDisable(GL_CULL_FACE) # draw from all sides
     
        # Size of cone in arrow:
        coneFractionAxially = 0.2
        coneFractionRadially = 0.1
     
        # Calculate cone parameters:
        v = numpy.array((x2-x1, y2-y1, z2-z1))
        norm_of_v = numpy.sqrt( numpy.dot(v,v) )
        coneHgt = coneFractionAxially * norm_of_v
        coneRadius = coneFractionRadially * norm_of_v
        vConeLocation = (1.0-coneFractionAxially) * v
     
        # Construct transformation matrix
        mat44 = numpy.eye(4)
        normalized_v = v/norm_of_v
     
        mat44[0,0] = normalized_v[0]
        mat44[1,1] = normalized_v[1]
        mat44[2,2] = normalized_v[2]
     
        # -----------------------
        #   Draw line + cone
        # -----------------------
        # Draw single line:
        glBegin(GL_LINES)
        glVertex3f(x1, y1, z1) # from
        glVertex3f(x2, y2, z2) # to
        glEnd() # GL_LINES
     
        # Move and rotate in position:
        glTranslate( *vConeLocation )
        if 0: # turn on/off here
            #glLoadIdentity()
            glMultMatrixf( mat44 ) #  <===== PROBLEM HERE?!?! WHAT?
     
        # Make a cone!
        cone_obj = gluNewQuadric();
        # gluCylinder(gluNewQuadr, Radius_base, Radius_top,
        #               height, slices, stacks)
        gluCylinder(cone_obj, 0, coneRadius,\
            coneHgt, 8, 1);
     
        glPopAttrib() # GL_CULL_FACE
        glPopMatrix()
    As you can see I've made an option to disable using the mat44-matrix. When I disable it, the cone gets drawn but the rotation is wrong. When I enable it, the cone is NOT drawn... Am I multiplying with a wrong rotation matrix and does that explain why nothing gets drawn?

    There are no errors/warnings or anything... I don't understand this...

  2. #2
    Intern Contributor
    Join Date
    Aug 2011
    Posts
    73
    Quote Originally Posted by newsb View Post
    There are no errors/warnings or anything... I don't understand this...
    Ok, to help myself and some of you, I've tried to make a complete program in C which you can compile and run:

    Code :
    // gcc arrowTest.c -lglut -lGLU && ./a.out//-------------------------
    #include <GL/glut.h>
    #include <math.h>
    #include <stdio.h>
     
    void coordSysArrow(float x1, float y1_, float z1, float x2, float y2, float z2)
    {
      glPushMatrix();
      glPushAttrib( GL_POLYGON_BIT ); // includes GL_CULL_FACE
      glDisable(GL_CULL_FACE); // draw from all sides
     
      float v[3];
      // Calculate arrow parameters:
      v[0] = x2-x1;
      v[1] = y2-y1_;
      v[2] = z2-z1;
     
      // Draw single line:
      glBegin(GL_LINES);
      glVertex3f(x1, y1_, z1); // from
      glVertex3f(x2, y2, z2); // to
      glEnd(); // GL_LINES
     
      // Easy enough - now let's make the cone in the arrow!
      if (1 == 1) // Make a cone! Change test to "0 == 1" to disable this part...
        {
          float norm_of_v = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
     
          // Size of cone in arrow:
          float coneFractionAxially = 0.2;
          float coneFractionRadially = 0.1;
     
          float coneHgt = coneFractionAxially * norm_of_v;
          float coneRadius = coneFractionRadially * norm_of_v;
     
          float normalized_v[3];
          normalized_v[0] = v[0] / norm_of_v;
          normalized_v[1] = v[1] / norm_of_v;
          normalized_v[2] = v[2] / norm_of_v;
     
          // Construct transformation matrix
          float mat44[16] =
            {1,0,0,0,
             0,1,0,0,
             0,0,1,0,
             0,0,0,1};
     
          mat44[0] = normalized_v[0]; // [0,0]
          mat44[5] = normalized_v[1]; // [1,1]
          mat44[10] = normalized_v[2]; // [2,2]
          mat44[15] = 1.0;
     
          if (0==1)
            {
              int i;
              for (i=0; i<16; i++)
                {
                  printf ("[%i]: %f\n", i, mat44[i]);
                }
              exit(EXIT_FAILURE);
            }
     
          float vConeLocation[3];
          vConeLocation[0] = (1.0-coneFractionAxially) * v[0];
          vConeLocation[1] = (1.0-coneFractionAxially) * v[1];
          vConeLocation[2] = (1.0-coneFractionAxially) * v[2];
     
          // Move and rotate in position:
          glTranslatef( vConeLocation[0], vConeLocation[1], vConeLocation[2] );
          if (0 == 1) //  <===== PROBLEM HERE?!?! WHAT?
            {
              //glLoadIdentity()
              glMultMatrixf( mat44 );
            }
          GLUquadric* cone_obj = gluNewQuadric();
          gluCylinder(cone_obj, 0, coneHgt, coneRadius, 8, 1);
        }
      glPopAttrib(); // GL_CULL_FACE
      glPopMatrix();
    }
     
    float x1 = 0.0; float y1_ = 0.0; float z1 = 0.0;
    float x2 = 1.0; float y2 = 1.0; float z2 = 0.0;
     
    void display()
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glTranslatef(0, 0, -5);
     
      glColor4ub(255,128,128,255); // red, green, blue, alpha
     
      int drawArrow = 1; // turn on/off here
      if (drawArrow == 1)
        coordSysArrow(x1, y1_, z1, x2, y2, z2);
      else {
        glBegin(GL_LINES);
        glVertex3f(x1, y1_, z1); // from
        glVertex3f(x2, y2, z2); // to
        glEnd(); // GL_LINES
      }
      glFlush();
      glutSwapBuffers();
    }
     
    void reshape(int w, int h)
    {
      glViewport(0, 0, w, h);
     
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective( 60, (double)w / (double)h, 0.01, 100 );
    }
     
    int main(int argc, char **argv)
    {
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
     
      glutInitWindowSize(800,600);
      glutCreateWindow("Arrowing");
     
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutMainLoop();
      return EXIT_SUCCESS;
    }

    I don't understand why the cone doesn't get displayed correctly... I would REALLY appreciate some feedback, thank you... And now you should be able to copy/paste the code and run it (test on linux with gcc - I think windows would work out of the box too). You can then disable/enable the cone stuff (which I don't understand why is not working)...

    I hope to hear from someone soon. Thanks.

  3. #3
    Intern Contributor
    Join Date
    Apr 2012
    Posts
    55
    I've run your code and had slightly better results than you.
    The cone does show up when I do glMultMatrixf (mat44).
    But it is not oriented or positioned properly.
    Make sure you're not calling glLoadIdentity before MultMatrix.
    That will definitely mess things up.

    I noticed that you have the ability to print out the contents of mat44.
    It's a good idea. When you do that do you get what you expected?
    Do you know what the contents of a rotation transformation matrix should look like?
    This can be Googled. Trig functions are involved.
    Do you know what axis you should be rotating the cone around to put it in the proper orientation?

    Did you know that you can use the glRotate command to accomplish what you
    are trying to do without ever messing around with matrices?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •