Jump to content

View more

Image of the Day

雑魚は多めにして、爽快感重視にしつつ・・・(´・ω・`)
早いとこ、ベースを作って、完成にもっていかないとね。
タイトルもまだ迷ってるだよなぁ。 
#indiedev  #indiegame #screenshotsaturday https://t.co/IwVbswGrhe
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

Detect non-uniform scaling in matrix

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
7 replies to this topic

#1 Ed Welch   Members   

1003
Like
0Likes
Like

Posted 12 January 2013 - 09:45 AM

Does anyone know of a fast way to tell if a matrix has non-uniform scaling?



#2 Buckshag   Members   

899
Like
0Likes
Like

Posted 12 January 2013 - 11:46 AM

You can probably get the length of the basis vectors of the matrix (for example the length of the first, second and third row). This gives you the x, y and z scale. If they are not equal to each other there is non-uniform scaling.

 

Not sure if this is the best/safest or fastest method though, but it is definitely faster than doing full polar/spectral decomposition.


Edited by Buckshag, 12 January 2013 - 11:48 AM.


#3 Álvaro   Members   

20913
Like
0Likes
Like

Posted 12 January 2013 - 01:20 PM

If a matrix is the composition of a rotation and a uniform scaling, its three columns should be orthogonal to each other and have the same length.

#4 Ed Welch   Members   

1003
Like
0Likes
Like

Posted 13 January 2013 - 04:30 AM

Thanks for the answer. This is the formula I came up with finally:

// note: this is opengl type matrix
bool Matrix::IsUnformScaling() const
{
	const float THRESHOLD = 0.01f;
	float xLen = m[0]*m[0] + m[1]*m[1] + m[2]*m[2];
	float yLen = m[4]*m[4] + m[5]*m[5] + m[6]*m[6];
	float zLen = m[8]*m[8] + m[9]*m[9] + m[10]*m[10];
	return fabsf(xLen - yLen) < xLen*THRESHOLD && fabsf(xLen - zLen) < xLen*THRESHOLD;
}

I tested it and it seems to work ;)



#5 Álvaro   Members   

20913
Like
0Likes
Like

Posted 13 January 2013 - 01:01 PM

I can construct a matrix that has non-uniform scaling in it and passes your test, though...

EDIT: More explicitly,
  m[0] = 0.8; m[1] = 0.6; m[2] = 0.0;
  m[4] = 0.6; m[5] = 0.8; m[6] = 0.0;
  m[8] = 0.0; m[9] = 0.0; m[10] = 1.0;


Edited by Álvaro, 13 January 2013 - 01:07 PM.


#6 Ed Welch   Members   

1003
Like
0Likes
Like

Posted 13 January 2013 - 02:24 PM

I can construct a matrix that has non-uniform scaling in it and passes your test, though...

EDIT: More explicitly,

  m[0] = 0.8; m[1] = 0.6; m[2] = 0.0;
  m[4] = 0.6; m[5] = 0.8; m[6] = 0.0;
  m[8] = 0.0; m[9] = 0.0; m[10] = 1.0;

Ok, my bad.

do you have a solution perchance?



#7 Álvaro   Members   

20913
Like
1Likes
Like

Posted 13 January 2013 - 07:57 PM

I posted that already, although perhaps my description was too succinct. You also need to verify that those three vectors are orthogonal to each other (check all three pairs).
bool are_orthogonal(Vector3 v, Vector3 w) {
  static float const tolerance = 1e-6;
  float dp = dot_product(v,w);
  return dp * dp < dot_product(v,v) * dot_product(w,w) * tolerance;
}

EDIT: To be complete, you should also verify that the transformation preserves orientation (its determinant is positive).

Edited by Álvaro, 13 January 2013 - 07:58 PM.


#8 Ed Welch   Members   

1003
Like
0Likes
Like

Posted 14 January 2013 - 12:37 PM

Ok. I tried that out and it seems to work well.

Thanks for your help Alvaro ;)






Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.