How does a projection Matrix work? - opengl

I have to write a paper for my A-Levels about 3D-Programming. But I got a serious problem understanding the perspective projection Matrix and I need to fully explain the Matrix in detail. I've searched a lot of websites and youtube videos on this topic but very little even try to answer the question why the Matrix has these values at that place. Based on this http://www.songho.ca/opengl/gl_projectionmatrix.html I was able to find out how the w-row works, but I don't understand the other three.
I decided to use the "simpler" version for symmetric viewports only (right-handed Coord.):
I am very thankful for every attempt to explain the first three rows to me!

The core reason for the matrix is to map the 3D coordinates to a 2D plane and have more distant objects be smaller.
For just this a much simpler matrix suffices (assuming your camera is at origin and looking at the Z axis):
1 0 0 0
0 1 0 0
0 0 0 0
0 0 1 0
After multiplying with this matrix and then renormalizing the w coordinate you have exactly that. Each x,y,z,1 point becomes x/z,y/z,0,1.
However there is no depth information (Z is 0 for all points) so a depth buffer/filter won't work. For that we can a a parameter to the matrix so the depth information remains available:
1 0 0 0
0 1 0 0
0 0 0 1
0 0 1 0
Now the resulting point contains the inverse depth in the Z coordinate. Each x,y,z,1 point becomes x/z,y/z,1/z,1.
The extra parameters are the result of mapping the coordinates into the (-1,-1,-1) - (1,1,1) device box (the bounding box where if you are outside of it the point won't get drawn) using a scale and a translate.

Related

Unexpected transformationMatrix and offset Matrix with Skeletal Animation

What I use:
Assimp to import .fbx files from blender
OpenGL for rendering
glm lib for handling matrices and vectors
I am trying to make skeletal animation work. I dont read the .fbx file directly into the Program but I convert it to a binary at first. I tried to understand how transformationMatrix and offsetMatrix is supposed to work. This is what I understood: In order to later be able to run an animation, we need to find a way to make a moving Bone affect its vertices but also the bones connected to it. So the idea is to use transformation matrices, which describe the coordinate system of a bone or a node and we multiply along these paths to a bone and then multiply by is offsetMatrix to be back in objectSpace. I think by now I tried every possible combination of multiplying these but I always get something wrong. Then I looked at the values a couple of times and to me it is not obvious at all how this should work. Correct me if I am wrong but my expectation is that when in BindPose and using the offsetMatrices and transformationMatrices from the Assimp import I must result with an identity Matrix, because I want my model in bind pose just as without those Matrices. These are the transformation Matrices from all nodes up to the first bone:
The Root Node is identity
Armature mTransformationMatrix:
100 0 0 0
0 -1.6e-05 100 0
0 -100 -1.629e-05 0
0 0 0 1
Bone mTransformationMatrix:
1 0 0 0
0 1.6e-07 -1 0
0 1 -1.6e-07 0
0 0 0 1
I expect those two to result with something like an identity*100 when multiplied.
mOffsetMatrix of the corresponding Bone:
0.38 0 0 0
0 0 -1 0
0 0.28 0 0
0 0 1.67 1
In my opinion this doesnt help me at all. So either my expectaiton to result with an identity matrix are wrong or the offsetMatrix is.
In case you consider it important what my model looks like:
Edit: I forgot to mention: to read in the aiMatrix4x4 I use
static inline glm::mat4 mat4_cast(const aiMatrix4x4& m) { return glm::transpose(glm::make_mat4(&m.a1)); }
But the transformationMatrices I wrote in this report are directly from the Scene so only the offsetMatrix is transposed. But this doesn't change a thing.
I found the problem. The problem is that I also have to transform from meshSpace back to object space. The offset Matrix is the inverse of the tranformation Matrices multiplied and also multiplied with the inverse of the transformation Matrix to the Mesh which is on a different node.

Given 2d array of 0s and 1s, find all the squares in it using backtracking

in this 2d array 1 represents a point and 0 represents blank area.
for example this array:
1 0 0 0 1
0 0 1 0 0
0 0 0 0 0
0 0 0 0 1
my answer should be 2, because there are 2 squares (or rectangles) in this array like this
all the points should be used, and you can't make another square | rectangle if all its points are already used (like we can't make another square from the point in the middle to the point in the top right) because they are both already used in other squares, you can use any point multiple times just if at least one corner is not used point.
I could solve it as an implementation problem, but I am not understanding how backtracking is related to this problem.
thanks in advance.
Backtracking, lets take a look at another possible answer to your problem, you listed:
{0,0} to (2,1}
{0,0} to {4,0}
As one solution another solution is (With respect to the point can be used multiple times as long as one point is unused):
{4,0} to {2,1} (first time 4,0 and 2,1 is used)
{0,0} to {2,1} (first time 0,0 is used)
{0,0} to {4,4} (first time 4,4 is used)
Which is 3 moves, with backtracking it is designed to show you alternative results using recursion. In this equation if you start the starting location for calculating the squares at different areas of the array you can achieve different results.
for an example iterating starts from 0,0, and going right across each row trying to find all possible rectangles starting with [0,0] will give the solution you provided, iteratings starting from 4,0 and going left across each row trying to find all possible solutions will give my result.

Choose rectangles for maximizing the area

I've got a 2D-binary matrix of arbitrary size. I want to find a set of rectangles in this matrix, showing a maximum area. The constraints are:
Rectangles may only cover "0"-fields in the matrix and no "1"-fields.
Each rectangle has to have a given distance from the next rectangle.
So let me illustrate this a bit further by this matrix:
1 0 0 1
0 0 0 0
0 0 1 0
0 0 0 0
0 1 0 0
Let the minimal distance between two rectangles be 1. Consequently, the optimal solution would be by choosing the rectangles with corners (1,0)-(3,1) and (1,3)-(4,3). These rectangles are min. 1 field apart from each other and they do not lie on "1"-fields. Additionally, this solution got the maximum area (6+4=10).
If the minimal distance would be 2, the optimum would be (1,0)-(4,0) and (1,3)-(4,3) with area 4+4=8.
Till now, I achieved to find out rectangles analogous to this post:
Find largest rectangle containing only zeros in an N×N binary matrix
I saved all these rectangles in a list:
list<rectangle> rectangles;
with
struct rectangle {
int i,j; // bottom left corner of rectangle
int width,length; // width=size in neg. i direction, length=size in pos. j direction
};
Till now, I only thought about brute-force-methods but of course, I am not happy with this.
I hope you can give me some hints and tips of how to find the corresponding rectangles in my list and I hope my problem is clear to you.
The following counterexample shows that even a brute-force checking of all combinations of maximal-area rectangles can fail to find the optimum:
110
000
110
In the above example, there are 2 maximal-area rectangles, each of area 3, one vertical and one horizontal. You can't pick both, so if you are restricted to choosing a subset of these rectangles, the best you can do is to pick (either) one for a total area of 3. But if you instead picked the vertical area-3 rectangle, and then also took the non-maximal 1x2 rectangle consisting of just the leftmost two 0s, you could get a better total area of 5. (That's for a minimum separation distance of 0; if the minimum separation distance is 1, as in your own example, then you could instead pick just the leftmost 0 as a 1x1 rectangle for a total area of 4, which is still better than 3.)
For the special case when the separation distance is 0, there's a trivial algorithm: you can simply put a 1x1 rectangle on every single 0 in the matrix. When the separation distance is strictly greater than 0, I don't yet see a fast algorithm, though I'm less sure that the problem is NP-hard now than I was a few minutes ago...

Error control coding for a practical application

I’m doing a project where a device is built to measure the girth of a rubber tree in a rubber plantation.
I need to give an identity to each tree to store the measurements of each tree.
The ID of each tree contains 33bits (in binary). For error detection and correction I’m hoping to encode this 33bit word in to a code word (Using a error control coding technique) and generate a 2D matrix (Color matrix-With red and cyan squares representing 1’s and 0’s). The 2D matrix will represent the coded word. This matrix will be pasted on the trunk of the tree. And a camera (the device) will be used to take the image of the 2D matrix and the code will be decoded then the ID of the tree will be taken.
I’m looking for the best scheme to implement this. I thought of cyclic codes for coding, but since the data word is 33 bits cyclic codes seems to be bit complicated.
Can someone please suggest the best way (at least a good way) to implement this???
Additional info: The image is taken in a forest environment (low light condition), Color matrix is to be used considering the environment.(The bark of the tree is dark so black and white matrix would be not appropriate)
One way to do it is to use 2D-parity check codes. The resulted codeword is a matrix, and it has single error correction (SEC) capability.
Since your information part (tree ID) has 33 bits, you may need to add a few dummy bits to make the codeword a 2D rectangle (say, a 6x6 information part). If a tree's ID is 1010_1010_1010_1010_1010_1010_1010_1010_1, then by adding 3 more 0 we have it as:
1 0 1 0 1 0 | 1
1 0 1 0 1 0 | 1
1 0 1 0 1 0 | 1
1 0 1 0 1 0 | 1
1 0 1 0 1 0 | 1
1 0 1 0 0 0 | 0
—————————————
0 0 0 0 1 0 1
Then you get a (n, k, d) = (49, 36, 3) code, which correct 1 bit errors.

OpenGL glut glTranslate glRotate glScale matrices

i'm looking for an explanation (or an image) of the matrix and how it changes when putting translate, rotate and scale on it... (one cell with sin(angle), and another cell with x coord of translate)
For now, ignore translation, it's a slightly trickier concept than rotation and scale.
The way to think about this is that each matrix defines a change in the basis vectors. Given a standard co-ordinate system, your basis vectors are (1,0,0), (0,1,0) and (0,0,1). For now, I'm just going to assume a 2D system, as the concepts carry through, but it's less work.
I'm also assuming column-major. I can't remember if OpenGL actually uses this though, so check this first, and optionally transpose the matrices if needed.
The basis vectors, as defined before, can be put in matrix form. This simply puts each vector as a column in the matrix. Therefore, to transform from the basis vectors to the basis vectors (i.e. no change), we would use the following matrix. This is also called the "identity matrix", since it doesn't do anything to its input (similar to how *1 is the identity of multiplication).
2D 3D
(1 0) (1 0 0)
(0 1) (0 1 0)
(0 0 1)
I've included the 3D version for completeness sake, but that's as far as I'll be taking 3D.
A scale matrix can be seen as "stretching" the axes. If the axes are twice as large, the intervals on them will be twice as far apart, thus, the contents will be larger. Take this as an example
(2 0)
(0 2)
This will change the basis vectors from (1, 0) and (0, 1) to (2, 0) and (0, 2), thus making the whole shape represented twice as large. Diagrammatically, see below.
Before After
6| 3|
5| |
4| 2|-------|
3| | |
2|--| 1| |
1|__|___________ |_______|______
0 1 2 3 4 5 6 7 0 1 2 3
The same then happens for rotation, although instead, we sue different values, the values for a rotation matrix are as follows:
(cos(x) -sin(x))
(sin(x) cos(x))
This will effectively rotate each axis around the angle x. To really make sense of this, brush up on your trig and assume each column is a new basis vector ;).
Now, translation is a little trickier. For this, we add an extra column at the end of the matrix, which for all other operations just has a 1 on the last row (i.e. it is an identity, of forms). For translation, we fill this in as follows:
(1 0 x)
(0 1 y)
(0 0 1)
This is 3D in a form, but not in the form you will be used to. You can model this as moving the Z basis co-ordinate (and remember, we're working in 2D here!), assuming your model exists at Z=1. This effectively skews the shape, but again, as we're working in 2D, it is flattened so we don't percieve the third dimension. If we were working in 3D here, this would actually be the fourth dimension, as can be seen here:
(1 0 0 x)
(0 1 0 y)
(0 0 1 z)
(0 0 0 1)
Again, the "fourth dimension" isn't seen, but we instead move along it and flatten. It's easier to get your head around it in 2D space first, then try and extrapolate. In 3D space, this fourth dimension vector is called w, so your models implicitly lie at w=1.
Hope this helps!
EDIT: As an aside, this page is what helped me to understand translation matrices. It has some decent diagrams, so hopefully it will be more helpful:
http://www.blancmange.info/notes/maths/vectors/homo/