Let's say you have your 3D objects in the range of the box

{ xBy a first coordinate transformation shift the box, so that its center is in the origin:_{min}, x_{max}, y_{min}, y_{max}, z_{min}, z_{max}}

xSo you get your objects now in the range of the box_{d}=(x_{min}+x_{max})/2, y_{d}=(y_{min}+y_{max})/2, z_{d}=(z_{min}+z_{max})/2 x'=x-x_{d}, y'=y-y_{d}, z'=z-z_{d}

{ -x'Now its time to introduce our 3D coordinate system:_{m}, x'_{m}, -y'_{m}, y'_{m}, -z'_{m}, z'_{m}}

z | | | |_______ y / / / xLet's say you stand at (1000,0,0) and look at the origin (0,0,0) where you see all your 3D objects which are near to (0,0,0). Now let's turn the objects around the z-axis by an angle of Φ. What will be the new position of a point (x', y' z') after that? As it is easy to see, the z-component doesn't change, so we get z''=z'. But what about x' and y'? When we look from the top of the coordinate system, we see this:

_______________ y |. . | . . | . . | .___/ . | . Φ * (x'', y'') | . | . | * (x', y') | xIt seems to be difficult to find a formula which calculates x'' and y'' from x', y' and Φ, but when we do a separate calculation for x' and y', it get's easier, look at this:

_______________ y * (x'', y'') |. . x''= - y' sin(Φ) | . . y''= y' cos(Φ) | . x'' = x' cos(Φ) |----------*---- y | . y'' = x' sin(Φ) | (0, y') | . | | * (x'', y'') | * (x', 0) | | | x xNow we can add the components for x, y and z and write it down properly:

x'' = x'*cos(Φ) - y'*sin(Φ) + z'*0 y'' = x'*sin(Φ) + y'*cos(Φ) + z'*0 z'' = x'*0 + y'*0 + z'*1It's a fine thing to do this with matrix and vector, so it will look like this:

( | x'' | ) | ( | cosΦ | -sinΦ | 0 | ) | ( | x' | ) | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|

y'' | = | sinΦ | cosΦ | 0 | * | y' | ||||||

z'' | 0 | 0 | 1 | z' |

OK, but how about turning all the stuff additionally around the y-axis by an angle of Θ, so it looks as if you view from a higher position down to the 3D objects (view from a higher position down to the objects - doesn't it sound great?). Also in this way the z-axis will still remain vertically, so this is what you often will need for 3D-representations when the z-axis should always point to the top of the screen. So lets try to apply the same math that we used for the rotation around the z-axis. When we look from the right side, the coordinate system looks like this:

z z | | (x''', z''') | (0, z'') * (x''', z''') * | x'''=x'' cos(Θ) | * . | z'''=x'' sin(Θ) | . x'''= - z'' sin(Θ) . | |. z'''= z'' cos(Θ) x ---*-------| x ------------ (x'', 0)Writing the stuff fine together, we get

x''' = x''*cos(Θ) - y''*0 - z''*sin(Θ) y''' = x''*0 + y''*1 + z''*0 z''' = x''*sin(Θ) + y''*0 + z''*cos(Θ)And in matrix notation:

( | x''' | ) | ( | cosΘ | 0 | -sinΘ | ) | ( | x'' | ) | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|

y''' | = | 0 | 1 | 0 | * | y'' | ||||||

z''' | sinΘ | 0 | cosΘ | z'' |

Now let's do the two rotations in one step whithout calculating the (x'', y'', z'') vector:

( | x''' | ) | ( | cosΘ | 0 | -sinΘ | ) | [ | ( | cosΦ | -sinΦ | 0 | ) | ( | x' | ) | ] | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|

y''' | = | 0 | 1 | 0 | * | sinΦ | cosΦ | 0 | * | y' | ||||||||||

z''' | sinΘ | 0 | cosΘ | 0 | 0 | 1 | z' |

You probably know from your Algebra lessons, that we can use A*(B*C)=(A*B)*C to simplify the matrix multiplication, so we get:

( | x''' | ) | ( | cosΦcosΘ | -sinΦcosΘ | -sinΘ | ) | ( | x' | ) | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|

y''' | = | sinΦ | cosΦ | 0 | * | y' | ||||||

z''' | cosΦsinΘ | -sinΦsinΘ | cosΘ | z' |

Finally, we get the position of a point in the screen coordinate system by

xThe pixel count in y is from top to down, so you will get the appropriate pixel numbers by x^{s}= y''' = sinΦ x' + cosΦ y' y^{s}= z''' = cosΦsinΘ x' - sinΦsinΘ y' + cosΘ z' z^{s}= x''' = cosΦcosΘ x' - sinΦcosΘ y' + sinΘ z'

The current picture will not show any perspective, it looks as if you were standing very far away. If you want to get a more realistic impression, you must change the formula just a little bit. Assume your position is (0,0,d), so d is your distance from the origin. When you look at a point (x

| (x'Then you get by similar triangles^{s},0,0) ---|--------*---------- x | . | . | * (x^{s},0,z^{s}) | . | . | . | . |. o (0,0,d) | z

(x'so the new screen coordinate with perspective is^{s}-x^{s})/z^{s}= x^{s}/(d-z^{s})

x'Note, that now also the drawing order must be changed: Instead of sorting the objects according to their z^{s}= x^{s}* (d /(d-z^{s})) y'^{s}= y^{s}* (d /(d-z^{s}))

O.k. folks, that's enough for the beginning, if you want to see how I implemented this, then have a look at my SVG-CANVAS-3D examples.