LocalToScene Transformation (related to Affine Transforms)

Pavel Safrata pavel.safrata at oracle.com
Fri May 11 02:33:31 PDT 2012


Hi Alexander,

On 11.5.2012 10:56, Alexander Kouznetsov wrote:
> Hi Pavel,
>
> I like the way you're going. Here is another issue you may want to 
> concern: http://javafx-jira.kenai.com/browse/RT-17942

I know about it. I expect we will provide methods as 
"getInverseTransform()" on the base (unmodifiable) class that would 
return a new transformation, and methods as "inverse()" (and others 
requested by RT-17942) on the Affine class, that would modify it in place.

>
> Having immutable matrix seems to be a reasonable solution and I agree 
> that Affine doesn't fit there. However I agree with Jim that having 
> mutable subclasses fakes the immutability of the base class. Moreover 
> it increases garbage collection overhead.

I believe our proposal keeps the garbage collection overhead low. 
Creating a new instance each time a getter is called makes things worse, 
keeping one object all the time would mean necessity to listen on all 
the members, so I don't see any better solution here. Also I don't see 
the problem the mutable subclasses. We just probably shouldn't call the 
base class "immutable", but rather "unmodifiable".

>
> Can't we just make Affine3D public instead? That way we'll provide 
> matrices calculation layer and all we need is to provide methods to 
> convert Affine3D to Affine and vice versa. Just an idea.

This sounds like a bad idea to me. From user's point of view, Affine3D 
and Affine would be duplicates except that Affine's members are 
observable. What I think we should do is to port some of the Affine3D 
functionality to the Affine class (which sounds close to RT-17942).

Thanks,
Pavel

>
> Best regards,
> Alexander Kouznetsov
>
>
> On 09.05.2012 19:16, Pavel Safrata wrote:
>> Hello,
>> I've been working on the local-to-scene transform 
>> (http://javafx-jira.kenai.com/browse/RT-520). I have a prototype that 
>> makes it an observable (read-only) property, registering for 
>> invalidation notifications to parent only when somebody registers a 
>> listener to it. This is nicer than a simple "compute" method - it 
>> looks like a standard observable lazy property from user's point of 
>> view.
>>
>> The big question now is what the type of the property should be. The 
>> first candidate is javafx.scene.transform.Affine. Unfortunately this 
>> class has each element of the matrix as a property, which makes it 
>> pretty impractical for that purpose. There are two options there:
>> - We can create a new Affine instance each time the transformation 
>> changes (and somebody calls the getter). This way all the elements 
>> would have to be immutable, so all their setters would need to throw 
>> exceptions (ugly) and whole their observability would be just a 
>> useless slowdown.
>> - Or we can keep the single instance and modify its elements. This 
>> way user would have to register twelve listeners to be notified of 
>> transformation changes.
>> None of those options seems good enough.
>>
>> 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).
>>
>> 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.
>>
>> What do you think?
>> Thanks,
>> Pavel


More information about the openjfx-dev mailing list