LocalToScene Transformation (related to Affine Transforms)
Martin Desruisseaux
martin.desruisseaux at geomatys.fr
Thu May 10 08:30:25 PDT 2012
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