LocalToScene Transformation (related to Affine Transforms)

Pavel Safrata pavel.safrata at oracle.com
Fri May 11 02:09:44 PDT 2012

Hello Martin,
your comments make perfect sense. However, I seriously doubt our scene 
graph would ever be able to operate with such general transformations. 
Apart from the fact that we would most probably have a great trouble to 
implement all the existing functionality if such transformations were 
allowed, it would bring a serious performance drop and would create an 
API considerably less handy for the usual cases. Anyway, if we decide 
that the naming issue is serious and/or that we want to leave the door 
open to the generic transforms, we can do following: insert a new class 
(say AffineBase) as a subclass of Transform and superclass of all the 
existing transforms, then go with our proposed solution using AffineBase 
instead of Transform. To me it seems as a good thing to do.

On 10.5.2012 17:30, Martin Desruisseaux wrote:
> Hello all
> Le 09/05/12 17:16, Pavel Safrata a écrit :
>> We considered another option: creating a new class 
>> TransformationMatrix. This class would be immutable and would contain 
>> various methods for work with matrices. All the transforms would have 
>> a getter that would return an instance of this class, the Affine 
>> class would have also a setter. Now the localToSceneTransformation 
>> property could be of type TransformationMatrix. This would spare us 
>> the above problems and provide an independent class for matrix 
>> operations, but on the other hand, converting transformations to the 
>> matrix and back may be an unnecessary burden, also doing some complex 
>> matrix computation with an immutable matrix class would result in 
>> pretty huge garbage production (slowing down the computation).
> If this approach was selected, maybe a plain "Matrix" class name, with 
> 'getNumRows()', 'getNumColumns()' and 'get(i,j)' methods would be 
> sufficient. This would allow usage in two-dimensional cases (as 3×3 
> matrices), three-dimensional cases (as 4×4 matrices), perspective 
> transform (which is not affine, but still represented by 3×3 matrices) 
> or other matrix operations not necessarily related to coordinate 
> transformations.
> For example, when dealing with generic (not necessarily affine) 
> coordinate transformations - for example map projections -, 
> transforming a point is not always sufficient. Some time we need the 
> mathematical derivative of the transform at a given point. In the 
> particular case of affine transforms, the derivative is trivially the 
> same everywhere, which may explain why Java2D has never feel a need 
> for it (note however that java.awt.geom.AffineTransform has something 
> close: the deltaTransform(...) method). But in the general case the 
> transform derivative may vary at any point, and the result of a 
> transform derivative can be express as a matrix. See for example:
> http://www.geoapi.org/snapshot/javadoc/org/opengis/referencing/operation/MathTransform.html#derivative%28org.opengis.geometry.DirectPosition%29
> The derivatives are useful for example because a map projection may 
> change straight lines into curved lines, and the derivative are useful 
> for computing Bézier curves that approximate those curves. They are 
> also useful for helping some iterative algorithms to converge faster. 
> If the matrix class name was "TransformMatrix", we would need a 
> "DerivativeMatrix" for the above case, and likewise for all other 
> matrix usage. I think that a plain "Matrix" class of arbitrary 
> dimension would fit better the need.
>> So we propose yet another approach. In the base Transform class, 
>> introduce getters for all the elements of the transformation matrix 
>> (not observable, just getters). Each transformation would be able to 
>> return the values according to its current state. Our property would 
>> then be of type Transform, allowing only for getting the matrix 
>> values. This would make the property observable as a whole (creating 
>> a new instance each time), unmodifiable, and would leave us with a 
>> nicely open way to introduce the methods for matrix operations on the 
>> Transform class, most of them probably returning the Affine instance 
>> as a result, and the Affine class could then have a bunch of methods 
>> to be modified in place.
> If this approach was selected, the "Transform" class name would become 
> unfortunate, because the class name suggests arbitrary transform, 
> while the above-cited getters would in practice restrict the transform 
> to the affine case. This would be yet more confusing since an Affine 
> class already exist. If we were allowed to rename the classes, it 
> seems to me that the "Transform" class would need to be renamed 
> "Affine" (because "Translate", "Scale", "Shear" and "Rotate" are 
> special cases of affine transforms) and the current "Affine" would 
> have to be renamed into something else, maybe "GeneralAffine".
> I would like to propose a mix of those two approaches: the 
> 'localToSceneTransformation' property would be of kind "Transform" 
> like the second proposal, but instead of individual getter methods for 
> various matrix coefficients, provide the following method in the 
> Transform class:
>     public abstract Matrix getMatrix(Point3D location);
> For every current JavaFX implementations, the Point3D argument would 
> be ignored and can be null. For custom implementations, e.g. map 
> projections (or anything which is non-linear), the result vary for 
> each points. This method would copy the current Transform state in a 
> new Matrix object (i.e. take a snapshot) - so no need for new 
> Transform instance when the state change, and no need for new Matrix 
> instance when performing matrix operations (the operations could be 
> applied in-place in the existing Matrix instance).
>     Martin

More information about the openjfx-dev mailing list