[geometry] Replace isIdentity()?

Hi,

During the discussion on dev-platform@lists.mozilla.org[1] some engineers raised concerns to support isIdentity.

To quote Rik:

“"
[…] as matrices get computed, they are going to jump unpredicably
between being exactly identity and not. People using isIdentity() to jump
between code paths are going to get unexpected jumps between code paths
i.e. typically performance cliffs, or worse if they start asserting that a
matrix should or should not be exactly identity. For that reason, I would
remove the isIdentity method. 
“”

So while the following is stable on a matrix that is already identity:

	matrix.translateBy(10).translateBy(-10);

Certain functions are likely to cause not identity matrices:

	matrix.rotateBy(54.4, 20.5, 20.5).rotateBy(-54.4, 20.5, 20.5);

Note that it rotates by 54.4 degrees and then rotates back by -54.4 degrees. While both operations should eliminate themself, it could happen that the matrix is not identity anymore. The strange part: on further transformations it could be identity again. This is because of different computational precision and rounding deviations. This is usually worst if trigonometric functions are involved. All rotate functions use sin() or cos() and are more likely to cause the described behavior.

As a result of this it was proposed to replace isIdentity() with a function that just returns true if the matrix can be guaranteed to be identity, regardless of computational deviations.

The proposed method maybeHasTransform()

1) Returns ‘identity' if DOMMatrix/DOMMatrixReadOnly was constructed with
	DOMMatrix()
	DOMMatrix(1,0,0,1,0,0)
	DOMMatrix(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)
	DOMMatrix(otherMatrix) // Where other matrix is guaranteed to be identity
2) Returns ‘identity' if DOMMatrix was constructed as identity matrix and if and only if methods do not have any effect on the matrix itself:
	matrix.translateBy(0, 0);
	matrix.rotate…By(degree) //where degree is a an multiple of 360
	matrix.scale..By() // Where all scale arguments are 1
	matrix.skewXBy() skewYBy() where the passed angle is a multiple of 360.

It would return 'not identity' for:

	DOMMatrix(2,0,0,2,0,0)
	var matrix = new DOMMatrix();
	matrix.translateBy(20).translateBy(-20) // not identity
	var matrix = new DOMMatrix();
	matrix.scaleBy(2).scaleBy(0.5) // not identity

Furthermore, isIdentity would check all elements for 0 and 1 which could take resources.


Other people and engineers like me believe that this is too restrictive. In favor for isIdentity(), even with the concerns in the introduction:

1) isIdentity() as currently specified must be implemented so that it can guarantee all of the above scenarios that maybeHasTransform() can guarantee as well.
2) isIdentity() is nearly exclusively used to skip complex and costy computational operations entirely that would not cause any visual difference for identity. The worst case: the matrix is close to identity but not exactly identity and the application needs to do all these operations. While it can optimize other times. It could never optimize for maybeHasTransform().
3) All browser implementations, graphic libraries, game engines use or provide isIdentity(). In none of the instances the mentioned problems caused problems beside the one describe in 2).	
5) Authors create DOMMatrix to transform it. In this case maybeHasTransform() is useless because it will then always return ’not identity'.
6) For isIdentity(), the author can do transform operations and check at any time for identity.
7) maybeHasTransform() can only be useful if a system API returns a DOMMatrix object. (There is none today but will be in the future.)
8) isIdentity() can be implemented with the help of SSE and similar functionalities so that it is not significant more complex or decreases performance.


Since the editors can not come to an agreement, we bring this back to the group. Any input is welcome.

Greetings,
Dirk

Received on Saturday, 7 June 2014 06:33:52 UTC