Object rotation not working as expected

I have a camera (‘Viewpoint’) and it has a Child Of constraint with a mesh object (‘Model’). I am trying to rotate the object based on the position of camera, so that the camera is aligned with the y axis.

What I am trying to do is:

get the camera location
work out the angle I need to rotate the model around the z-axis to align the camera with the y-axis
work out the angle I need to rotate the model around the x-axis to align the camera with the y-axis
rotate the model around the z-axis
rotate the model around the x-axis

The problem I’m having is that the rotations don’t seem very logical. Even if I try and rotate by pi/2 it doesn’t rotate to where I was expecting. I’m sure it’s probably because my matrix knowledge is rather rusty.

My script is:

    bpy.data.objects['Viewpoint'].select = True
    bpy.context.scene.objects.active = bpy.data.objects['Viewpoint']
    cam_loc = bpy.data.objects['Viewpoint'].location

    # orient the camera by moving the model
    bpy.ops.object.select_all(action='TOGGLE')
    bpy.data.objects['Model'].select = True
    bpy.context.scene.objects.active = bpy.data.objects['Model']
    
    angle_xy = math.atan2(cam_loc[1], cam_loc[0])
    angle_yz = math.atan2(cam_loc[1], cam_loc[2])
    rot_z = -angle_xy + math.pi/2
    rot_x = angle_yz - math.pi/2
    mat_rot_x = mathutils.Matrix.Rotation(rot_x, 4, 'X')
    mat_rot_z = mathutils.Matrix.Rotation(rot_z, 4, 'Z')
    bpy.data.objects['Model'].matrix_world *= mat_rot_x
    bpy.data.objects['Model'].rotation_euler = bpy.data.objects['Model'].matrix_world.to_euler()
    bpy.data.objects['Model'].matrix_world *= mat_rot_z
    bpy.data.objects['Model'].rotation_euler = bpy.data.objects['Model'].matrix_world.to_euler()

I based my script on this (http://blender.stackexchange.com/questions/36672/a-sequence-of-90-degree-rotations-with-python).

Could anyone help me understand how rotations work and how I need to modify my script.

Thanks

Ok I found a solution based on this http://blender.stackexchange.com/questions/19533/align-object-to-vector-using-python

The following script works for my system. I’m not sure I understand rotations any better, I found the solution with rather a lot of trial and error! I think I need to brush up on my vectors and matrices.

    bpy.data.objects['Viewpoint'].select = True
    bpy.context.scene.objects.active = bpy.data.objects['Viewpoint']
    cam_loc = bpy.data.objects['Viewpoint'].matrix_local.translation

    
    bpy.ops.object.select_all(action='TOGGLE')
    bpy.data.objects['Model'].select = True
    bpy.context.scene.objects.active = bpy.data.objects['Model']
           


    # define direction
    if cam_loc[1] > 0:
        Vector=(-cam_loc[0],cam_loc[1],-cam_loc[2])
    elif cam_loc[1] < 0:
       Vector=(-cam_loc[0],cam_loc[1],cam_loc[2])
    DirectionVector = mathutils.Vector(Vector) 
    
    # apply rotation
    bpy.context.object.rotation_mode = 'QUATERNION'
    bpy.context.object.rotation_quaternion = DirectionVector.to_track_quat('Z','Y')

Near the middle of his ‘Humane Rigging’ video series, Nathan Vegdahl does a pretty good job of explaining how blender calculates rotation, including an explanation of the quaternion rotations used in this second script.