-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Matrix3: removed .scale(), .rotate(), and .translate() #24733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Oops. |
I'm not in favor of removing such basic math methods at this point of the library's maturity level. I think we should close this PR and #24731 since these methods were introduced for specific (valid) use cases. |
It appears @yomboprime You appear to understand these methods. Are you able to help suggest proper descriptions for the docs? How do the methods relate to CSS transforms? |
A matrix of 3x3 elements, as used here, is an affine transform in 2D. That is, it is equivalent to a rotation, scale and translation in 2D. The translation is the vector ( elements[ 2 ], elements[ 5 ] ). scale: Multiplies the matrix scale by the parameters, leaving the translation intact. I've not used CSS 2D transforms but I guess they use the matrices this way. |
I think the problem with #24731 is that Matrix3 can be interpreted as an affine transform in 2D (as these 3 methods do), or a scale + rotation in 3D, without translation. Matrix4 is an affine transform in 3D. |
By the way, I initially had my own methods in SVGLoader, and @mrdoob suggested to use Matrix3 instead. |
Thanks @yomboprime. ... Reverse engineering what I did in #11863...
|
Interesting... So I am trying to decide if that is where they belong... Are SVG transform conventions the same as in CSS? The nomenclature sure is CSS-like. Why is the rotation sign flipped, as compared to |
They are not CSS specific, they are general matrix operations. Of course if Matrix3 is not used as a 2D transform anywhere else in the code base, they could be moved to SVGLoader. I can take care of that and test if you wish. Edit: I guess the texture matrices are 2D, so the 3 methods can be used with them.
Probably because it is a premultiplication? I mean, perhaps the sign gets inverted. |
In three.js/examples/jsm/loaders/SVGLoader.js Line 1485 in ecd0bf6
For the use case in the three.js example, the method works correctly.
// These are not general math methods. They are utility methods for a specific use case. |
Take also in consideration that the Y axis in SVG is inverted w.r.t. the Threejs one: three.js/examples/webgl_loader_svg.html Line 168 in ecd0bf6
That could explain why I did negate the angle. |
I've seen that the angle in SVG is clockwise, so that explains the angle negation. Did not remember that. |
Sorry for the delay... I would also like to keep these methods. Seems like the issue in #24731 is with @eXponenta do you have any suggestions on how these methods should behave so they make sense to you? |
@mrdoob So, i think need keep texture-specific implementation as special TextureMatrix, or SCGMatrix for avoid confusing, and change behaviour on to classic matrix operations. For us not make sence anymore how computations is doing now, we use a manual implementation, but counterintuitively for application supporting and we always marks matrix3 usage as unsafe with link to issue. I not know how many peoples use a Matrix3 for regular matrix computation on 2D space, but looks like issue unpopular and our case is statistically insignificant. |
Maybe renaming the 3 methods to adhere and operate as the |
That sounds reasonable to me... @WestLangley @eXponenta what do you think? |
About the angle negation, I think it is rather because the Y axis is inverted in SVG (the model |
There seems to be support for 2D matrix transforms, so I propose adding the following methods which parallel the similarly-named // for 2D Transforms
makeTranslation( x, y ) {
this.set(
1, 0, x,
0, 1, y,
0, 0, 1
);
return this;
}
makeRotation( theta ) {
// clockwise (but I think counter-clockwise is a better convention for three.js)
const c = Math.cos( theta );
const s = Math.sin( theta );
this.set(
c, s, 0,
- s, c, 0,
0, 0, 1
);
return this;
}
makeScale( x, y ) {
this.set(
x, 0, 0,
0, y, 0,
0, 0, 1
);
return this;
} IMO, the above methods are definitely appropriate. /ping @eXponenta . If these methods were added, then then existing methods could be rewritten: scale( sx, sy ) {
this.premultiply( _m3.makeScale( sx, sy ) );
return this;
}
rotate( theta ) {
this.premultiply( _m3.makeRotation( theta ) );
return this;
}
translate( tx, ty ) {
this.premultiply( _m3.makeTranslation( tx, ty ) );
return this;
} But these existing methods do not belong here, IMO. We rotate objects in three.js. We do not rotate matrices. Plus, they are application-specific, and depend on the handedness of the coordinate frame. |
I agree, we should delete the old methods and use the new ones in SVGLoader. |
@WestLangley i prefer gl-matrix implementation, looks like your implementation is same as one. |
According to the inline comments, the gl-matrix function
In three.js, we do not "translate matrices"; we translate objects and geometries. In any event, the gl-matrix translate( tx, ty ) {
this.multiply( _m3.makeTranslation( tx, ty ) ); // post-multiply
return this;
} That is different than pre-multiplying, as is done in the three.js method The gl-matrix method |
See the discussion in #24731.
We rotate objects in three.js -- not matrices.
I added these methods to emulate a CSS-like API. I do not think these methods are used, and I can no longer justify their existence.