First I want to say I have done the reading on this one, but I am still lost. I have seen some other posts here regarding how to handle this using 3D matrices, posts on the main Stack Overflow site for handling 2D Vector rotation in C++, and I have some chapters of this book that covers rotating points using Python. From all that research, I have been able to properly rotate around the origin (0,0 - Bottom Left). Code for that below:
import bpy
from mathutils import Vector
from math import pi, sin, cos, atan2, hypot
def to_cartesian(polar_coord):
length, angle = polar_coord.x, polar_coord.y
return Vector((length * cos(angle), length * sin(angle)))
def to_polar(vector):
x, y = vector[0], vector[1]
angle = atan2(y, x)
return Vector((hypot(x, y), angle))
def Rotate2D(v, r):
v_polar = to_polar(v)
v_rotated_polar = Vector((v_polar.x, v_polar.y + r))
v_prime = to_cartesian(v_rotated_polar)
return v_prime
# then call Rotate2D() on all vertices within the UVMap.
def RotateUV(uvMap, rotation, pivot):
for uvIndex in range(len(uvMap.data)):
uvMap.data[uvIndex].uv = Rotate2D(uvMap.data[uvIndex].uv, rotation)
The above code when called on a given object, will rotate it around the point (0,0):
When I have tried to implement the ideas given in the above response on StackOverflow, where you subtract the pivot from the given vector coordinate before you get the angles, then add them back at the end, I get strange results:
The python implementation of the referenced C++ code:
# Assuming input coords are passed as Polar coords
def to_cartesian_pivot(coord, angle, pivot):
x_rotated = ((coord.x - pivot.x) * cos(angle)) - ((coord.y - pivot.y) * sin(angle)) + pivot.x
y_rotated = ((coord.x - pivot.x) * sin(angle)) - ((coord.y - pivot.y) * cos(angle)) + pivot.y
return Vector((x_rotated, y_rotated))
def Rotate2D(v,p,r)
v_polar = to_polar(v)
v_rotated_polar = Vector((v_polar.x, v_polar.y + r))
v_prime = to_cartesian_pivot(v_rotated_polar, r, p)
return v_prime
I am unsure where exactly my algorithm is wrong. I think the issue must be in how I am handling the rotated coordinates. Either my order of operations is wrong, or I am giving it the wrong type of coordinate (Polar vs Cartesian?). If there is any clarification you need, let me know.