Matrix Math and 2D Rotations

Many years later, I’m glad I payed attention in my freshmen year geometry class.

Today I figured out rotations, something I thought I’d never done before, but as I did it I recalled it vaguely from out of the foggy memory that is high school mathematics.

A 2D rotation matrix is as follows:

| xcos(Ø)  -ysin(Ø) |

| xsin(Ø)    ycos(Ø) |

In this matrix, positive values will rotate counterclockwise. Also, theta must be in radians.

For a 3d application like Maya, the axis that you leave out (in this case, z) is the axis about which you will rotate. So if I wanted to rotate around the y axis, I’d have the variables x and z.

Matrices are fun and all, but I like direct formulas. And hooray! There is one!

x’ = xcos(Ø) – ysin(Ø)

y’ = xsin(Ø) + ysin(Ø)

For example, let’s say I want to rotate the vector [1,0] 90 degrees. That gives me:

x’ = 1(cos(90)) – 0(sin(90)) = 1(0) – 0(1) = 0

y’ = 1(sin(90)) + 0(sin(90)) = 1(1) + 0(1) = 1

So our new point it [0,1]. This works with any 2d vector and any degree.

Here’s a script of me applying some of this vector math. I use it to create an array of points and draw an nGon using those points. I then am able to rotate and scale that nGon. Baby steps!

import math
import maya.cmds as cmds

"""
The equation for 2d rotation is:
    x' = xcos(theta) - ysin(theta)
    y' = xcos(theta) + ycos(theta)
Positive values will rotate counterclockwise
"""

# our start vector p
p = [1,0,0]
# n is the number of sides on our nGon
n = 16
# the arc variable determines the angle we need to rotate the start vector to make the points for the nGon. 
# For example, an equilateral triangle would have an arc value of 360/3 or 120 degrees.
arc = 360 / n
# A is our variable we'll use to store the current degree value
a = arc
# Store the verts in an array so we can mess with them later
vertices = []
# append our first point to the vertices array
vertices.append(p)


while a < 360:
    # rot value must be in radians
    rot = math.radians(a)
    newX = p[0] * math.cos(rot) - p[1] * math.sin(rot)
    newY = p[0] * math.sin(rot) + p[1] * math.cos(rot)
    newPnt = [newX,newY,0]
    vertices.append(newPnt)
    a += arc
    
vertices.append(p)

# try a 30 degree rotation along the y axis
# start a at 1 
a = 1
while a < len(vertices):
    rot = math.radians(30)
    newX = vertices[a][0] * math.cos(rot) - vertices[a][2] * math.sin(rot)
    newZ = vertices[a][0] * math.sin(rot) - vertices[a][2] * math.cos(rot)
    vertices[a][0] = newX
    vertices[a][2] = newZ
    a += 1
    
print("_")
# it worked! now let's try scaling by .5
a = 1

while a < len(vertices):
    vertices[a][0] = vertices[a][0] * .5
    vertices[a][1] = vertices[a][1] * .5
    vertices[a][2] = vertices[a][2] * .5
    a += 1
    
# now let's try moving up the y axis 1 unit
a = 1
while a < len(vertices):
    vertices[a][1] = vertices[a][1] + 1
    a += 1

# finally draw a curve to represent that shape. Pass it that array of points
cmds.curve(d=1,point=vertices)
Advertisements
Image

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s