dopatraman
dopatraman

Reputation: 13908

Projecting a cube onto a plane using matrix transformations and numpy

I wasn't sure if this topic was a better fit here or on math overflow. Since I'm using numpy, I thought I'd post it here.

I'm trying to rotate a cube in 3 dimensional space and then project it onto a 2 dimensional plane.

I begin with the Identiy Matrix:

import numpy as np

I = [[1,0,0],
     [0,1,0],
     [0,0,1]]

Then, I apply a rotational transformation to the Y Axis:

from math import sin, cos

theta = radians(30)
c, s = cos(theta), sin(theta)
RY = np.array([[c, 0, s],[0, 1, 0], [-s, 0, c]])
# at this point I'd be dotting the Identiy matrix, but I'll include for completeness
I_RY = np.dot(I, RY)

At this point I have a new basis space that has been rotated 30 degrees about the Y axis.

Now, I want to project this onto a 2-dimensional space. I figured, this new space is basically the identity basis with the Z axis set to zero:

FLAT = [[1,0,0],
        [0,1,0],
        [0,0,0]]

So now, I figure I can compose with this to complete a full transformation from cube to square:

NEW_SPACE = np.dot(I_RY, FLAT)

All that's left is to transform the points of the original cube. Assuming that the original cube had its northeast points set to [1,1,1] and [1,1,-1], I can get the new points like so:

NE_1 = np.array([1,1,1])
NE_2 = np.array([1,1,-1])
np.dot(NEW_SPACE, NE_1)
np.dot(NEW_SPACE, NE_2)

However, this gives me the following:

array([ 0.8660254,  1.       , -0.5      ])

This sort of checks out, because both points have been flattened to the same thing. However, what is the -0.5 in the Z axis? What does it represent?

The existence of a value on the Z axis post transformation makes me think that my method is incorrect. Please tell me if I'm going about this the wrong way.

Upvotes: 5

Views: 1283

Answers (2)

Joseph Sheedy
Joseph Sheedy

Reputation: 6726

You are on the right track. The 3d pipeline to transform your cube vertices is

projection @ camera @ world @ model @ vertices

Your FLAT matrix is a camera matrix with focal_length=1 and cx = cy = 0 (screen offsets).

punyty is a small demonstration engine for rendering 3d models using numpy if you want a reference.

Upvotes: 1

dopatraman
dopatraman

Reputation: 13908

As @PaulPanzer pointed out, I was dotting the new vector from the wrong direction. The solution is

np.dot(NE_1, NEW_SPACE)

Upvotes: 3

Related Questions