I would like to know how to rotate an object around its center point,that the angle from the z axis is theta and the XY plane rotates in angle phi via python scripting.
2 Answers
To avoid any misunderstanding let me reiterate with this illustration.
$\theta$ will control the orientation on the red axis.
$\phi$ will control the orientation on the blue axis.
If $\theta$ is a multiple of $\pi$, $\phi$ won't change the final orientation.
We can construct a quaternion from the $\theta$ and $\phi$ rotation and chain them. The mathutils.Quaternion
class provides a rotate(other)
function for this purpose.
import bpy
import math
import mathutils
θ = math.pi / 3
ϕ = math.pi / 2
q = mathutils.Quaternion((0, -1, 0), θ)
qϕ = mathutils.Quaternion((0, 0, 1), ϕ)
q.rotate(qϕ)
bpy.context.object.rotation_mode = 'QUATERNION'
bpy.context.object.rotation_quaternion = q
While this works, it doesn't really produce polar coordinates. Certain polar coordinates should be the same, and they currently aren't.
Calculation the spherical position
You can directly calculate the x, y and z values.
$x = \sin{\theta} \cos{\phi}$
$y = \sin{\theta} \sin{\phi}$
$z = \cos{\theta}$
Then you can generate a quaternion pointing to that position with the to_track_quat
function.
position = mathutils.Vector((math.sin(θ) * math.cos(ϕ),
math.sin(θ) * math.sin(ϕ),
math.cos(θ) ))
q = position.to_track_quat('-Z', 'X')
This will give you good control over which axis is oriented where.
Latitude and longitude.
It appears you are describing a system akin to latitude and longitude. Can pretty much emulate this by changing the Euler order to 'ZYX' and setting Z rotation for longitude and X for latitude.
Below is a sphere such that -Y with no rotation points to lat, long = (0, 0)
A camera is globally position above this point.
Test script
With the setup above, can set the absolute rotation of the sphere to latitude and longitude.
Set the rotation of the sphere such that the cities using latitude and longitude are randomly presented under camera.
import bpy
from math import radians
from mathutils import Euler
from random import choice
context = bpy.context
ob = context.object
data = (
(40, -73., "New York"),
(-33, 151, "Sydney"),
(51, 0, "London"),
(-22, -42, "Rio"),
(-1, 37, "Nairobi"),
)
lat, long, name = choice(data)
R = Euler((radians(lat), 0, radians(-long)), 'ZYX').to_matrix()
ob.matrix_world = R.to_4x4()
Equirectangular world image used as map texture.
By Strebe - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=16115228