The 3D representation in a svg element can be possible if it makes a projection of points on a plane normal to the direction of view, let name it P. The direction of view is defined by two angles: "azimuth" and "elevation".
In the figure aside you can see the P plane represented in a fix reference system, [Oxyz]. The plane has a local axis system [O_{G} uvw] (w not represented in the figure), coresponding to the graphic coordinate system of canvas html element.
The initial position of the plane P is parallel to [yz] plane of the fixed system, then rotated around a vertical axis with "az" angle, and finally rotated around the local axis "u" with angle "el". The point G of this plane, located by local coordinates u_{G}, v_{G} is superposed to the fix point Q defined in the fixed axis system by coordinates x_{Q} y_{Q} z_{Q}.
This geometrical position's definition of the projection plane P ca be expressed by a matrix transformation between these two coordinate systems. For that, we must express the origin O_{G} and the unit vectors u and v by components, to respect [Oxyz] system:
O_{G} = | x_{Q}+u_{G}·sin(az)-v_{G}·sin(el)·cos(az) | |
y_{Q}-u_{G}·cos(az)-v_{G}·sin(el)·sin(az) | ||
z_{Q}+v_{G}·cos(el) |
u = | -sin(az) | |
+cos(az) | ||
0 |
v = | +sin(el)·cos(az) | |
+sin(el)·sin(az) | ||
-cos(el) |
The transformation matrix is:
T = | u_{x} | v_{x} | w_{x} | OG_{x} | |
u_{y} | v_{y} | w_{y} | OG_{y} | ||
u_{z} | v_{z} | w_{z} | OG_{z} | ||
0 | 0 | 0 | 1 |
And it's inverse:
T^{-1} = | u_{x} | u_{y} | u_{z} | -<u,OG> | |
v_{x} | v_{y} | v_{z} | -<v,OG> | ||
w_{x} | w_{y} | w_{z} | -<w,OG> | ||
0 | 0 | 0 | 1 |
Where the notation <v_{1},v_{2}> represents the scalar product between vectors v_{1} and v_{2}
A point p(x,y,z) in the virtual 3d space has in the local system [O_{G} uvw] the coordinates a, b and c computed with formula:
a | = T^{-1}· | x | ||
b | y | |||
c | z | |||
1 | 1 |
The projection p' of the point on the plane P has coordinates a and b extracted from above matrix formula:
a = | <u,(x,y,z)-O_{G}> |
b = | <v,(x,y,z)-O_{G}> |
A function to compute the projection of points can be write like:
function trans32(Q,G,az,el,p){ var sa, ca, se, ce, OG, u, v, S1, S2; sa = Math.sin(az); ca = Math.cos(az); se = Math.sin(el); ce = Math.cos(el); OG = [ Q[0]+G[0]*sa-G[1]*se*ca, Q[1]-G[0]*ca-G[1]*se*sa, Q[2]+G[1]*ce ]; u = [-sa,ca,0], v = [se*ca,se*sa,-ce]; S1 = -u[0]*OG[0]-u[1]*OG[1]-u[2]*OG[2]; S2 = -v[0]*OG[0]-v[1]*OG[1]-v[2]*OG[2]; return [ S1+u[0]*p[0]+u[1]*p[1]+u[2]*p[2], S2+v[0]*p[0]+v[1]*p[1]+v[2]*p[2] ]; };
The application you see below uses the equations for projection presented above. I have used a svg-element and a lot of javascript functions. All is made as an "object" entity having members and methods.
You can use the mouse to drag G point on the projection plane (four arrows sign), or to continuous change the "azimuth" and "elevation" values (on the black square). Also you can change the 3d coordinates of the Q point using the sliders.
move mouse over image, left-button pressed