Perspective and Clipping Transforms

Sean E. O'Connor
November 2009-October 2010

Introduction

This notebook displays wireframe models in perspective projection.

First, some simple conversion functions.

In[866]:=

"Orbital_1.gif"

In[867]:=

"Orbital_2.gif"

In[868]:=

"Orbital_3.gif"

Out[868]=

"Orbital_4.gif"

In[869]:=

"Orbital_5.gif"

In[870]:=

"Orbital_6.gif"

In[871]:=

"Orbital_7.gif"

Out[871]=

"Orbital_8.gif"

Euclidean and Homogeneous Coordinates

We'll use a left handed graphics coordinate system.

In[872]:=

"Orbital_9.gif"

Out[872]=

"Orbital_10.gif"

Convert between 3D Euclidean space and 4D homogeneous coordinates.

The 3D Euclidean point (x, y, z) transforms to (x, y, z, 1) in homogeneous coordinates.

In[873]:=

"Orbital_11.gif"

In[874]:=

"Orbital_12.gif"

Out[874]//MatrixForm=

"Orbital_13.gif"

The homogeneous point (x, y, z, w) transforms to ("Orbital_14.gif") in normalized homogeneous coordinates.

In[875]:=

"Orbital_15.gif"

In[876]:=

"Orbital_16.gif"

Out[876]//MatrixForm=

"Orbital_17.gif"

In[877]:=

"Orbital_18.gif"

In[878]:=

"Orbital_19.gif"

Out[878]=

"Orbital_20.gif"

Translation and Rotation

Develop the 4D homogeneous matrices for translations and rotations.  We translate/rotate the coordinate system origin.

In[879]:=

"Orbital_21.gif"

Translate the origin by vector v = (1,2,3).  (1,2,3) should now map to (0,0,0).

In[880]:=

"Orbital_22.gif"

In[881]:=

"Orbital_23.gif"

Out[881]//MatrixForm=

"Orbital_24.gif"

In[882]:=

"Orbital_25.gif"

Out[882]=

"Orbital_26.gif"

In[883]:=

"Orbital_27.gif"

Out[883]=

"Orbital_28.gif"

Rotate the origin by θ counterclockwise about the z axis.

In[884]:=

"Orbital_29.gif"

Out[884]=

"Orbital_30.gif"

In[885]:=

"Orbital_31.gif"

Rotate the origin by "Orbital_32.gif" counterclockwise about the z axis.  The point ("Orbital_33.gif", 0) should map to (1,0,0).

In[886]:=

"Orbital_34.gif"

Out[886]//MatrixForm=

"Orbital_35.gif"

Rotate the origin by θ counterclockwise about the x axis.

In[887]:=

"Orbital_36.gif"

Out[887]=

"Orbital_37.gif"

In[888]:=

"Orbital_38.gif"

Rotate the origin by "Orbital_39.gif" counterclockwise about the x axis.  The point ("Orbital_40.gif") should map to (0,0,1) because "Orbital_41.gif"

In[889]:=

"Orbital_42.gif"

Out[889]//MatrixForm=

"Orbital_43.gif"

Rotate the origin by "Orbital_44.gif" counterclockwise about the x axis.  The point (0,0,1) should map to (0,-1,0)

In[890]:=

"Orbital_45.gif"

Out[890]//MatrixForm=

"Orbital_46.gif"

Rotate the origin by θ counterclockwise about the y axis.

In[891]:=

"Orbital_47.gif"

Out[891]=

"Orbital_48.gif"

In[892]:=

"Orbital_49.gif"

Rotate the origin by "Orbital_50.gif" counterclockwise about the y axis.  The point ("Orbital_51.gif") should map to (1,0,0).

In[893]:=

"Orbital_52.gif"

Out[893]//MatrixForm=

"Orbital_53.gif"

Perspective Projection

The perspective matrix lives in homogeneous coordinate space and maps the viewing frustrum to a unit parallelepiped for simplicity in clipping.
The eye is at the origin of the perspective view which forms a rectilinear cone.
The picture plane has width = wPP, height = hPP.
The distance from the eye to the picture plane is dPP and the distance from the eye to the far plane is dFP.

Try out translation and rotation.  

In[894]:=

"Orbital_54.gif"

In[895]:=

"Orbital_55.gif"

In[896]:=

"Orbital_56.gif"

Out[896]//MatrixForm=

"Orbital_57.gif"

Helper function to project points (x,y,z) in 3D to (x,y) in 2D.

In[897]:=

"Orbital_58.gif"

In[898]:=

"Orbital_59.gif"

Out[898]=

"Orbital_60.gif"

Points on the near plane corners transform to normalized picture plane corners.

In[899]:=

"Orbital_61.gif"

Out[899]=

"Orbital_62.gif"

Point on the far plane corners transform to normalized picture plane corners.

In[900]:=

"Orbital_63.gif"

Out[900]=

"Orbital_64.gif"

General points (x,y,z) transform to  

In[901]:=

"Orbital_65.gif"

Out[901]=

"Orbital_66.gif"

Points in normalized homogeneous perspective space project down the the 2D picture plane.

In[902]:=

"Orbital_67.gif"

In[903]:=

"Orbital_68.gif"

Out[903]=

"Orbital_69.gif"

2. Clipping

Clip a homogeneous point in perspective projection to the bounds of the viewing frustrum.

In[904]:=

"Orbital_70.gif"

Test it out.  Clipping should be false, then true for this example.

In[905]:=

"Orbital_71.gif"

Out[905]=

"Orbital_72.gif"

In[906]:=

"Orbital_73.gif"

Out[906]=

"Orbital_74.gif"

Wire Frame Components

Circle in yz plane using left handed coordinate system, with variable spacing of points.

In[907]:=

"Orbital_75.gif"

Arrange the graph with +x to the right, +y upwards, and -z into the picture so we model a left handed viewing coordinate system.

In[908]:=

"Orbital_76.gif"

Out[908]=

"Orbital_77.gif"

In[909]:=

"Orbital_78.gif"

In[910]:=

"Orbital_79.gif"

Arrange the graph with +x to the right, +y upwards, and -z into the picture so we model a left handed viewing coordinate system.

In[911]:=

"Orbital_80.gif"

Out[911]=

"Orbital_81.gif"

Models and Views for a Real Table

In[912]:=

"Orbital_82.gif"

Calibrate by doing a simple view of a table top model.

Wire frame model of table top.

In[916]:=

"Orbital_83.gif"

Wire frame model of table top.  Arrange the graph with +x to the right, +y upwards, and -z into the picture so we model a left handed viewing coordinate system.

In[917]:=

"Orbital_84.gif"

In[918]:=

"Orbital_85.gif"

Out[918]=

"Orbital_86.gif"

Perspective view.

In[919]:=

"Orbital_87.gif"

Quick test.  Find a world coordinate point which maps to the center of the view.

In[920]:=

"Orbital_88.gif"

Out[920]=

"Orbital_89.gif"

Perpective view of the table.

In[921]:=

"Orbital_90.gif"

Out[921]=

"Orbital_91.gif"

Orbital Model and View

Our orbital!

In[922]:=

"Orbital_92.gif"

Angular spacing between points on the orbital circle having a radial distance of 100 km.

In[923]:=

"Orbital_93.gif"

Check gravity on the orbital.

In[924]:=

"Orbital_94.gif"

Out[925]=

"Orbital_95.gif"

Picture plane dimensions.  Width and height are of my painting canvas.  Distance to picture plane from eye seems reasonable.

In[926]:=

"Orbital_96.gif"

In[930]:=

"Orbital_97.gif"

Arrange the graph with +x to the right, +y upwards, and -z into the picture so we model a left handed viewing coordinate system.

In[931]:=

"Orbital_98.gif"

Out[931]=

"Orbital_99.gif"

In[932]:=

"Orbital_100.gif"

Plot a few points on the midpoint of the orbital circle to debug the perspectivc clipping.

In[933]:=

"Orbital_101.gif"

Out[934]//MatrixForm=

"Orbital_102.gif"

In[935]:=

"Orbital_103.gif"

Out[935]//MatrixForm=

"Orbital_104.gif"

In[936]:=

"Orbital_105.gif"

"Orbital_106.gif"

"Orbital_107.gif"

View the orbital in perspective from our chosen vantage point.

In[937]:=

"Orbital_108.gif"

Out[937]=

"Orbital_109.gif"

Spikey Created with Wolfram Mathematica 6