3
$\begingroup$

Question: My camera towards the target object located at (0,0,0). I know the current camera location (camx, camy, camz), camera rotation eulers. How can I calculate the new camera rotation eulers so that my camera can rotate any angles a long the camera z axis.

Following is the detailed description: My camera is located at [camx,camy,camz] and the target object is located at [0,0,0]. In order to ensure the camera can correctly facing the object center, the following code is used to calculate the camera rotation eulers:

Vector = (0-camx,0-camy,0-camz) 

direction = mathutils.Vector(Vector)

rot_quat = direction.to_track_quat('-Z', 'Y')

myeulers = rot_quat.to_euler()

cam.rotation_euler = myeulers

Everything works fine and the object is located in the center of the rendered image.

Now, I would like to rotate the camera like e.g. 45,90,180,360 degrees along the camera z axis so that the object in the rendered images is also rotated. Thus, I directly change the camera Z euler angle. However, after rendering, the object is not located in the rendered image center. In some images the object is missing. I guess the main reason is that the camera is rotated according to the world coordinate, the the local camera coordinate.

Do some of you know how to calculate the camera euler angles so that it can rotate only around the camera z axis? I need to use Python since those euler angles and the rendered images will be used for CNN training. Thank you very much!

$\endgroup$
6
  • $\begingroup$ So you just want the camera to rotate around the object in the center of the scene? $\endgroup$
    – Bert VdB
    Commented Apr 25, 2017 at 22:07
  • $\begingroup$ Not around the object. The camera location is fixed. The camera is facing the object center. I only want to rotate the camera along the camera z axis. For example, camera rotate 45 degrees, but still at the same location, facing the object center. In such a case, what kind of rotation eulers should be assigned to the camera. $\endgroup$
    – Cong
    Commented Apr 26, 2017 at 7:21
  • $\begingroup$ So you want to 'roll' the camera around the axis it's pointing at? $\endgroup$
    – Bert VdB
    Commented Apr 26, 2017 at 11:44
  • 1
    $\begingroup$ @BertVdB, yes, I want to 'roll' the camera around the z axis :) The question would be how to calculate the eulers for each rolling angle? $\endgroup$
    – Cong
    Commented Apr 26, 2017 at 12:41
  • $\begingroup$ Hmm at first thoughts this will be quite tricky using python scripting, but it is very simpel using blender's viewport handles... Do you realy need this in python? $\endgroup$
    – Bert VdB
    Commented Apr 26, 2017 at 12:43

2 Answers 2

2
$\begingroup$

This is a math problem, so there should be a math-based solution -- one that does not require bpy.ops.

One way to control the order of rotations is to express the desired rotation as a product of component rotations. Then the order of the multiplicands controls the order of operations.

For example, if camera_roll is the rotation matrix for rotation about the Z-axis, and camera_rot is the original rotation of the camera, then to combine the rotations into a single rotation (matrix), you would multiply the two matrices:

matrix_world = camera_rot * camera_roll

The component rotations are applied from right to left. So first the camera is rolled (about the Z-axis) and then rotated into position.


Vector = (0-camx,0-camy,0-camz) 
direction = mathutils.Vector(Vector)
rot_quat = direction.to_track_quat('-Z', 'Y')
rot_quat = rot_quat.to_matrix().to_4x4()

roll = math.radians(45)  # select your desired amount of rotation
camera_roll = mathutils.Matrix.Rotation(roll, 4, 'Z')

# apply the rotation
cam.matrix_world = rot_quat * camera_roll

I've packaged this into a utility function here.


If for some reason you wanted to know the equivalent Euler rotation, you can conver the matrix rotation to an Euler rotation by using:

matrix_world = rot_quat * camera_roll
myeulers = matrix_world.to_euler()

and then apply the rotation to the camera with

cam.rotation_euler = myeulers
$\endgroup$
1
$\begingroup$

Problem solved! Check the following code: (1) Step one: Select camera and change the transformation orientation into 'Local' (2) Step two: Write in Python:

cam = bpy.data.objects["Camera"]

cam.select = True 

bpy.ops.transform.rotate(value=-1, constraint_axis=(False, False, True), constraint_orientation='LOCAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)

print(cam.rotation_euler)

Here you can change -1 into any angle you want to roll

$\endgroup$

You must log in to answer this question.

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