For 4*4 transform matrix m,if represented internally using 4 vectors x, y, z, w
For translation part, is it
w.x = t.x ; w.y = t.y ; w.z = t.z
or
x.w = t.x; y.w = t.y; z.w = t.z;
I am confused, please help.
It's the first case. the follow picture translate point(x,y,z) to new point(x',y',z').
Matrix in DirctX was stored as row-major, so here
vector x = [1 0 0 0]
vector y = [0 1 0 0]
vector z = [0 0 1 0]
vector w = [tx ty tz 1]
Transform in Direct3D
Related
I try to construct my own View Matrix in OpenGL.
I'm following this link
https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
From the OpenGL doc, I have following.
eye position = eye(xe, ye, ze)
center position = cen(0, 0, 0)
up = up(xu, yu, zu). (e.g. up = (0, 1, 0))
forward vector
f' = cen - eye = (0, 0, 0) - (xe, ye, ze) = (-xe, -ye, -ze)
side vector
s' = f' x up
I don't understand why f' x up, why not up x f'
u' = s' x f'
I do't understand why u' = s' x f', why not u' = f' x s'
we normalize s', u', f'
s = norm(s'), u = norm(u'), f=norm(f')
We construct the rotation matrix with row-major(what we learn in algebra class)
R =
s_x u_x f_x 0
s_y u_y f_y 0
s_z u_z f_z 0
0 0 0 1
translation matrix:
T =
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
we know
M = T*R
View Matrix V = invert(M)
V = invert(T*R) = invert(R)invert(T)
V = transpose(R)invert(T)
transpose(R) =
s_x s_y s_z 0
u_x u_y u_z 0
f_x f_y f_z 0
0 0 0 1
invert(T) =
1 0 0 -x
0 1 0 -y
0 0 1 -z
0 0 0 1
so
View Matrix V = transpose(R)invert(T)
But from the OpenGL doc., f change to -f
The rotation changes to following
R =
s_x u_x -f_x 0
s_y u_y -f_y 0
s_z u_z -f_z 0
0 0 0 1
I Don't understand why we need to change the forward vector to negative.
The cross product order just follows from its definition. It is just like it is. You are setting up a right-handed coordinate system. So if you align the thumb of your right hand with the first factor and the index finger with the second factor, then the middle finger will point in the direction of the cross product (perpendicular to both). There is really not much more to tell about this.
And since you are setting up a right-handed coordinate system, the forward direction of the camera must be mapped to the negative z-direction. That's why the third column of the rotation matrix is inverted. If you don't do this, you end up with a left-handed coordinate system, where the camera looks in the direction of the positive z-axis.
I have a circle centred at 0 with radius 80. How using python do I calculate the coordinates for 8 equidistant points around the circumference of the circle?
r = 80
numPoints = 8.0
points = []
for index in range(numPoints):
points.append([r*math.cos((index*2*math.pi)/numPoints),r*math.sin((index*2*math.pi)/numPoints)])
return points
you can simplify this some if you know you are always going to have only 8 points with something like:
r = 80
numPoints = 8
points = []
x = (r*math.sqrt(2))/2
points = [[0,r],[x,x],[r,0],[-x,x],[-r,0],[-x,-x],[0,-r],[x,-x]]
print points
with x being the x/y of the point 45 degrees and 80 units away from the origin
click this pic for more clarity
in the above picture.
coordinates 1,2,3,4,5,6,7,8 are equidistant points on a circumference of circle Radius R and its centre is at X (0,0)
take the triangle XLZ , its aright angled at L ,
Let LZ = H ,
LY = A
XL + LY = R => XL + A = R => XL = R-A
since XLZ is right angled , XZ square = XL square + LZ square
R square = (R-A) square + h square ————1
since these 8 points makes an octagon theta = 360 deg / 8 = 45 deg
tan 45 deg = h / XL = h / R-A => 1 = h/ R-A => h = R-A —————2
Z coordinates are (R-A, h) = > (h,h)
from the equations 1 and 2
R square = h square + h square => 2 h square = R square => h = R/ sqrt 2
so the coordinates at point 2 (Z) = (R/sqrt2, R/sqrt2)
remaining can be derived easily as they are just oppside
So all coordinates are
1 (0,R)
2 (R/sqrt2,R/sqrt2)
3 (R,0)
4 (-R/sqrt2, R/sqrt2)
5 (-R,0)
6 (-R/sqrt2,-R/sqrt2)
7 (0,-R)
8 (R/sqrt2, -R/sqrt2)
What is the fastes way in C++ to convert an index with such a formation to X, Y and Z coordinates and back ?
EDIT:
I want for example get for the index 15 the numbers X=0, Y=1, Z=2, for the index 17 the numbers X=2, Y=1, Z=2, and for the index 22 the numbers X=1, Y=2, Z=1.
I need this to emulate a multidimensional array.
To:
x = index % 3;
y = index / 3 % 3;
z = index / 9;
Back:
index = ((z) * 3 + y) * 3 + x;
I have recently been trying to render a 3D sphere in OpenGL using triangles. I have been testing and modifying code from various websites and have finally found a winning combination. The only problem is that there are visible gaps in the sphere. Any thoughts on what would be causing this?
Code to render sphere
float Slices = 30;
float Stacks = 60;
float Radius = 20.0;
for (int i = 0; i <= Stacks; ++i){
float V = i / (float) Stacks;
float phi = V * glm::pi <float> ();
for (int j = 0; j <= Slices; ++j){
float U = j / (float) Slices;
float theta = U * (glm::pi <float> () * 4);
float x = cosf (theta) * sinf (phi);
float y = cosf (phi);
float z = sinf (theta) * sinf (phi);
x *= Radius;
y *= Radius;
z *= Radius;
Vertex *v = new Vertex {{x,y,z}, //Position
{255,0,0}}; //Color
screenToBuffer(v, 1);
delete []v;
}
}
Problem
Try and set it to GL_TRIANGLE_STRIP
What might be the problem is that it considers each group of three vertices to be only one triangle.
Like so
Indices: 0 1 2 3 4 5 ...
Triangles: {0 1 2} {3 4 5}
The GL_TRIAGLE_STRIP will do this.
Indices: 0 1 2 3 4 5 ...
Triangles: {0 1 2}
{1 2 3} drawing order is (2 1 3) to maintain proper winding
{2 3 4}
{3 4 5}
See this answer for a proper way to do it.
https://stackoverflow.com/a/7958376/1943599
I am implementing perspective from scratch for an academic project. I am using "Computer Graphics: principles and practices", by Foley, van Dam, Feiner and Hughes (second edition in C).
I just followed the book by implementing all the matrices transformations needed to traslate, rotate, shear, scale, project, transform from perspective to parallel canonical view volumes and for clipping. The book apparently uses a right-handed coordinate system. However, I ended up with primitives appearing in a left-handed coordinate system and I cannot explain why.
Here are the matrices that I used:
Translation:
1, 0, 0, dx
0, 1, 0, dy
0, 0, 1, dz
0, 0, 0, 1
Rotation (to align a coordinate system (rx, ry, rz) to XYZ):
rx1, rx2, rx3, 0
ry1, ry2, ry3, 0
rz1, rz2, rz3, 0
0 , 0 , 0 , 1
Scale:
sx, 0 , 0 , 0
0 , sy, 0 , 0
0 , 0 , sz, 0
0 , 0 , 0 , 1
Shear XY:
1, 0, shx, 0
0, 1, shy, 0
0, 0, 1 , 0
0, 0, 0 , 1
Projecting onto a plane at z = d, with PRP at origin, looking in the positive z direction:
1, 0, 0 , 0
0, 1, 0 , 0
0, 0, 1 , 0
0, 0, 1/d, 0
Then given VRP, VPN, PRP, VUP, f and b (and the direction of projection dop), reduce the space to the canonical viewing volume for perspective using P:
rz = VPN / |VPN|
rx = (VUP x rz) / |VUP x rz|
ry = rz x rx
P = ScaleUniform(-1 / (vrp1Z + b)) *
Scale(-2 * vrp1Z / deltaU, -2 * vrp1Z / deltaV, 1) *
Shear(-dopX / dopZ, -dopY / dopZ) *
T(PRP) *
R(rx, ry, rz) *
T(-VRP)
Where vrp1 is ShearXY * T(-PRP) * (0, 0, 0, 1), deltaU and deltaV the width and height of the viewing window. dop is computed as CW - PRP, where CW is the center of the viewing window.
Then Projection(d) * P gives me the projection matrix.
I projected simple lines representing the unit vectors on x, y and z, but the representation that I obtained drawn on the screen was clearly a left handed coordinate system... Now I need to work in a right handed coordinate system, so is there a way to know where I did wrong?
Here is the code I used:
As you can see, the Z component of the scale matrix is of opposite sign, since clipping wasn't working properly because something was right-handed and something left-handed, but I couldn't discern what exactly, so I swapped the sign of the scale because it wasn't needed in a left-hand system.
Vector rz = vpn.toUnitVector();
Vector rx = vup.cross(rz).toUnitVector();
Vector ry = rz.cross(rx).toUnitVector();
Vector cw = viewWindow.getCenter();
Vector dop = cw - prp;
Matrix t1 = Matrix::traslation(-vrp[X], -vrp[Y], -vrp[Z]);
Matrix r = Matrix::rotation(rx, ry, rz);
Matrix t2 = Matrix::traslation(-prp[X], -prp[Y], -prp[Z]);
Matrix partial = t2 * r * t1;
Matrix shear = Matrix::shearXY(-dop[X] / dop[Z], -dop[Y] / dop[Z]);
Matrix inverseShear = Matrix::shearXY(dop[X] / dop[Z], dop[Y] / dop[Z]);
Vector vrp1 = shear * t2 * Vector(0, 0, 0, 1);
Matrix scale = Matrix::scale(
2 * vrp1[Z] / ((viewWindow.xMax - viewWindow.xMin) * (vrp1[Z] + b)),
2 * vrp1[Z] / ((viewWindow.yMax - viewWindow.yMin) * (vrp1[Z] + b)),
1 / (vrp1[Z] + b)); // HERE <--- WAS NEGATIVE
Matrix inverseScale = Matrix::scale(
((viewWindow.xMax - viewWindow.xMin) * (vrp1[Z] + b)) / (2 * vrp1[Z]),
((viewWindow.yMax - viewWindow.yMin) * (vrp1[Z] + b)) / (2 * vrp1[Z]),
(vrp1[Z] + b));
float zMin = -(vrp1[Z] + f) / (vrp1[Z] + b);
Matrix parallel = Perspective::toParallelCvv(zMin);
Matrix inverseParallel = Perspective::inverseToParallelCvv(zMin);
Matrix perspective = Perspective::copAtOrigin(-vrp1[Z]);
projection = perspective * shear * partial;
canonicalView = parallel * scale * shear * partial;
canonicalToProjection = perspective * inverseScale * inverseParallel;