Can I always assume that an mvp matrix with corner value !=1 is performing scaling? - algorithm

Assume I have a modelview projection matrix, mvp and I know that mvp[3][3] !=1 and mvp[3][3] > 0
Can I assume that the model matrix performed the scaling or since the projection matrix itself performs scaling this number is not useful without the original matrices?

No, this value alone does not tell you much. Consider a diagonal matrix like the following:
d 0 0 0
0 d 0 0
0 0 d 0
0 0 0 d
d is an arbitrary number.
This matrix is essentially the homogeneous equivalent of the identity matrix and does not perform any transformation at all. The uniform scaling part in the upper left 3x3 block is cancelled out by the perspective divide. You can always multiply the matrix by the inverse of the m33 entry to somewhat normalize it (this will preserve the transformation). For the above matrix, you would then get:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
And in this form, you can easily see that it is the identity. Moreover, you can examine the upper left 3x3 block to find out if there is a scaling (depending on your definition of scaling, calculating the determinant of the 3x3 block and checking for 1 is one option as Robert mentioned in the comments).

Related

Transformed Primitives - Compute the inverse of a matrix without using any function

Let's say if I need to transform a cylinder, first I need to use a scaling matrix (sx, sy, sz) and multiply it with a translation matrix (tx, ty, tz) to form a new matrix that combined by these two matrix. => M = T*S.
Then I want to compute the inverse of a matrix M^-1 without using any function, I know that the inverse of a scaling matrix has a scale factors (1/sx, 1/sy, 1/sz) and a inverse of a translation matrix has (-tx, -ty, -tz), but how can I get M^-1 without any function in C++ ?
Suppose you want to scale a vector by some factors Sx, Sy, and Sz. The transformation matrix for this looks like:
Sx 0 0 0
0 Sy 0 0
0 0 Sz 0
0 0 0 1
Then, you want to translate the vector by some factors Tx, Ty, and Tz. The transformation matrix for this now looks like:
Sx 0 0 Tx
0 Sy 0 Ty
0 0 Sz Tz
0 0 0 1
The inverse of this matrix specifically is
1/Sx 0 0 -Tx/Sx
0 1/Sy 0 -Ty/Sy
0 0 1/Sz -Tz/Sz
0 0 0 1
.. as long as Sx, Sy, and Sz are all != 0.
Depending on your application, you may be better off writing a general purpose matrix inversion method. Note that there are cases in which a transformation (or any) matrix is not invertible... like if your scaling factor in one or more of the dimensions is 0. More generally, a matrix is invertible if and only if its determinant is nonzero.

Converting points into another coordinate system

There are 3 points in 3D space. There are 2 orthogonal coordinate systems with the same origin. I know coordinates of those 3 points in both coordinate systems. Given a new point with its coordinates in the first coordinate system, how can I find its coordinates in the second coordinate system?
I think it's possible to get a rotation matrix using given points which does this, but I did not succeed doing this.
You can do it using matrix inverses. Three matrix-vector multiplications (e.g. transforming three 3D vectors by a 3x3 matrix) is equivalent to multiplying two 3x3 matrices together.
So, you can put your first set of points in one matrix, call it A:
0 0 1 < vector 1
0 1 0 < vector 2
2 0 0 < vector 3
Then put your second set of points in a second matrix, call it C. As an example, imagine a transform that scales by a factor of 2 around the origin and flips the Y and Z axes:
0 2 0 < vector 1
0 0 2 < vector 2
4 0 0 < vector 3
So, if A x B = C, we need to find the matrix B, which we can find by finding the A-1:
Inverse of A:
0 0 0.5
0 1 0
1 0 0
The multiply A-1 x C (in that order):
2 0 0
0 0 2
0 2 0
This is a transform matrix B that you can apply to new points. Dot-product multiply the vector by the first column to get the transformed X, second column to get the transformed Y, etc.

how do I apply a wieght to a bone?

If I were to assign every vertex to a bone/matrix, how would I edit the transformation matrix so some of the vertexes are transformed less?
For example, if I have the matrix
cos sin 0 0
-sin cos 0 2
0 0 1 0
0 0 0 1
What do i do to it to make the vertex rotate less?
Quoting paddy
"Those sin and cos terms are all supposed to be supplied with an angle. eg sin(theta). So, since you are most likely in control of that, just reduce the angle."
So change the angle by multiplying by a value -1 to 1 and that will change the direction/amount it changes.

General matrix definition for image filtering or trasnformation

I am looking for matrices I can generate to transform other matrices, but I am not talking about regular matrices like:
From this question: The canonical examples you'll find everywhere are non-gaussian box blur:
1 1 1
1 1 1
1 1 1
Image sharpening:
0 -1 0
-1 5 -1
0 -1 0
Edge detection:
0 1 0
1 -4 1
0 1 0
and emboss:
-2 -1 0
-1 1 1
0 1 2
Those are for applying to each region of an image, I just want a big matrix. Is that possible?
For example: A 2560*2560 matrix that I can multiply directly with an image of 2560*2560 pixels.
Yes it's possible, but maybe not in the way you would think. Take a look at the Gaussian blur example at http://scipy-lectures.github.io/intro/scipy.html#fast-fourier-transforms-scipy-fftpack
The thing is that convolution in the image is equivalent to multiplication in the frequency domain. This is the Convolution Theorem from Fourier Transforms (https://en.wikipedia.org/wiki/Fourier_transform#Convolution_theorem). So, it is possible -- and in fact for huge images like you're talking about it should be faster. But the matrices are no longer simple ones like the examples you posted above.

3d Hill generating algorithm?

Supposing you have a 3d box of cubes, with each cube having 3 indices: (x,y,z), and 1 additional attribute to specify if it represents land or air.
Let's say that we have a 3d array to represent this box of cubes, with each cube being an element in the 3d array.
The following array, for example, would represent a bowl shaped piece of land:
y=0:
0 0 0 0 0
0 0 0 0 0
1 1 1 1 1
1 1 1 1 1
y=1:
0 0 0 0 0
0 0 0 0 0
1 0 0 0 1
1 1 1 1 1
y=2:
0 0 0 0 0
0 0 0 0 0
1 0 0 0 1
1 1 1 1 1
y=3:
0 0 0 0 0
0 0 0 0 0
1 1 1 1 1
1 1 1 1 1
What is an algorithm such that given a selection box it would generate hills with f frequency and with average height of h, with v average variation in height?
We can assume that the lowest level of the bonding box is the "baseline", or "sea-level".
function makeTrees(double frequency, int height, double variation)
{
//return 3d array.
}
I'm writing a minecraft MCEdit filter plugin :P
Simplest way is to decompose the problem into three parts:
Write a routine to generate the cubes for a single hill of height h. Start off by making this a simple cone (play with apex angles till you find something that looks pleasing)
Generate a set of n heights between h-v and h+v, using the random number generator of your choice
Place n mountains randomly on your cube. It doesn't matter if they intersect - indeed, it will lead to a better-looking range.
However, I'd also suggest abandoning this approach, and simply generate a fractal terrain within your bounding cube, then discretize it. You can play with the paramaters to your fractal generator to bound the height and variance.
Assuming you would like sinusoidal hills of frequency f (or rather, wavenumber f, since "frequency" is usually used for temporal quantities) as a function of radius r = sqrt(x^2+y^2) from the center:
Define a threshold function like this:
Any element (x,y,z) with z < z_m will be land, and the rest will be air.

Resources