0

The idea behind this is to create a detection area for a security camera. Currently, I know how to find and use the modelview matrix data as shown below in the function "matrixTransformation". The value for the matrix should then be calculated for each increase of rotation of the security camera in the initialization function.

I would like to know how you would find coordinates of the edges of each security camera, a cylinder shape, using the matrix. I am using Pygame 1.9.2, Python 3.5 and PyOpenGL-3.1.0.

Picture of coordinates on the security camera which need to be calculated

def matrixTransformation(x,y,z):

    matrix = (GLfloat * 16)()
    glGetFloatv(GL_MODELVIEW_MATRIX, matrix)

    xp = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12]
    yp = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13]
    zp = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14]
    wp = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15]

    xp /= wp
    yp /= wp
    zp /= wp

    return xp,yp,zp

def init():

    securityCameraRotation=380

    glEnable(GL_DEPTH_TEST)

    multipleRotations=0
    result=[]

    glPushMatrix()

    glTranslatef(-4,1.5,5.5)
    glRotate(315,1,1,1)

    while True:
        if securityCameraRotation>=380:
            clockwise=True
            multipleRotations+=1
        elif securityCameraRotation<=310:
            clockwise=False
        glRotate(securityCameraRotation,0,1,0)
        #append the transformed coordinates to result

        if clockwise==True:
            securityCameraRotation-=0.2
        elif clockwise==False:
            securityCameraRotation+=0.2
        if multipleRotations>1:
            #End the loop when one complete rotation between 310 and 380 has occured
            break

        glPopMatrix()

        return result

def securityCamera(radius, height, num_slices,frontCircleColour,backCircleColour,tubeColour):
    r = radius
    h = height
    n = float(num_slices)

    circle_pts = []
    for i in range(int(n) + 1):
        angle = 2 * math.pi * (i/n)
        x = r * math.cos(angle)
        y = r * math.sin(angle)
        pt = (x, y)
        circle_pts.append(pt)

    glBegin(GL_TRIANGLE_FAN) #drawing the back circle
    glColor(backCircleColour)
    glVertex(0, 0, h/2.0)
    for (x, y) in circle_pts:
        z = h/2.0
        glVertex(x, y, z)
    glEnd()

    glBegin(GL_TRIANGLE_FAN) #drawing the front circle
    glColor(frontCircleColour)
    glVertex(0, 0, h/2.0)
    for (x, y) in circle_pts:
        z = -h/2.0
        glVertex(x, y, z)
    glEnd()

    glBegin(GL_TRIANGLE_STRIP) #draw the tube
    glColor(tubeColour)
    for (x, y) in circle_pts:
        z = h/2.0
        glVertex(x, y, z)
        glVertex(x, y, -z)
    glEnd()
howardcrick
  • 27
  • 2
  • 7
  • The title of the question seems to differ from what you are asking in the body. Are you trying to get the corners of the "viewing frustum" of the camera to see if it contains your object/model of interest? What exactly do you mean by wanting to "find coordinates around the origin of rotation using the matrix" as it is a little unclear to me? – CodeSurgeon Feb 02 '17 at 04:18
  • Another question, is the security camera referring to the camera you use for drawing the scene, or are you placing a bunch of camera objects that each have their own "cone" of vision in the scene that the player needs to avoid? – CodeSurgeon Feb 02 '17 at 08:13
  • 1
    Sorry, the questions was very ambiguous,. I have now edited it. I am bascically placing a bunch of camera objects that each have their own cone of vision, as you said. Once two respective coordinates have been found(as shown in the image), I can then use vector equations to find the x and z coordinates for when y=-2. – howardcrick Feb 02 '17 at 16:19
  • Take a look at [this](http://www.songho.ca/opengl/files/gl_anglestoaxes01.png) image. Basically, if you get a copy of the modelview matrix for your camera, each of the column vectors has a specific meaning. You should extract the last two columns to get the forward vector (where the camera is pointing) and the position/translation of your camera respectively . That should be enough to calculate your two points. I can write this up as an answer if it is still unclear. – CodeSurgeon Feb 03 '17 at 03:56
  • I am not sure what the 3 z values represent or how to then use them to find the edge points, If you could, a written out answer would be more useful. – howardcrick Feb 03 '17 at 23:18
  • OpenGL is column major so the 3 z values are acutally an x, y, and z value! Regardless I will write something up in a few hours to make this clearer. – CodeSurgeon Feb 03 '17 at 23:34

1 Answers1

0

In OpenGL, there are a bunch of transformations that occur. First, we treat the object as if it is in model space, where the the object is centered at the origin and we draw the mesh (in this case, the cylinder). Then, we apply a model matrix transform (where we translate/rotate/scale our cylinder) and a view matrix transform (where we shift our scene relative to the imaginary camera). Finally we apply the projection matrix that adds the "3d perspective" to our scene by creating a matrix with gluPerspective or some more modern means. All of these matrix multiplications basically put the coordinates of your 3d models in the right place on our 2d screens (sort of, more detailed info here).

In terms of the model space, the yellow points you highlighted in your picture are actually just (0, 0, -h/2.0) and (0, 0, h/2.0). This is fine if you are just drawing your yellow points with glBegin(GL_POINTS) in your securityCamera function. However, you are probably more interested in calculating where these yellow points are located in world space (that is, after multiplication by the modelview matrix).

One simple way to get these world space coordinates is to multiply the yellow points' model space coordinates by the modelview matrix. Use your matrixTransformation function on (0, 0, -h/2.0) and (0, 0, h/2.0) and that should work!

Alternatively, as I hinted at in the comments, matrices like your modelview matrix are actually contain useful information that results from the accumulation of multiplications of translation, rotation, and scaling matrices. I pointed to this picture:

enter image description here

Each of these column axes actually corresponds to the rows of your numpy array (which is interesting since numpy is row-major while OpenGL is column-major). You can get the following axes of how your model is pointing in world spaces with the following snippet:

mv_matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
left, up, forward, position = [v/(np.linalg.norm(v)) for v in mv_matrix[:,:3]]

Note that I cut off the last row in the numpy array and normalized each of the axes. If you take the forward array you get from there, you get the direction in world space of where that particular camera is pointing, while the position array gives you the world space position of the center (model space equivalent of (0, 0, 0)) of the security camera. Multiply the normalized forward array by h/2.0 and add that to position and you should get the world space position of the front of your security camera. This is not too useful for rendering to the screen, but could be used for "behind the scenes" math for interesting objects with the security camera.

As a side note, I realized I made a sign error in this line for the cylinder drawing code:

glBegin(GL_TRIANGLE_FAN) #drawing the front circle
glColor(frontCircleColour)
glVertex(0, 0, -h/2.0)#this was + in the original code!!!

Let me know if this helps you make sense of my earlier comments!

CodeSurgeon
  • 2,435
  • 2
  • 15
  • 36
  • Excellent explanation, has really helped me understand how opengl calculates its coordinates in the world space :) – howardcrick Feb 05 '17 at 10:39