## Perspective Transformations

In my attempt to master JavaFX I got a lot of help from various sources. First of all the javafx.com website has many great samples that explain how JavaFX could be used. One of the samples intrigued me most and that is the Perspective Transformation. You can find a good sample named: Photo Flip. It rotates a picture over its vertical axis.

function getPT(t:Number):PerspectiveTransform { var width = 200; var height = 200; var radius = width/2; var back = height/10; return PerspectiveTransform { ulx: radius - Math.sin(t)*radius uly: 0 - Math.cos(t)*back urx: radius + Math.sin(t)*radius ury: 0 + Math.cos(t)*back lrx: radius + Math.sin(t)*radius lry: height - Math.cos(t)*back llx: radius - Math.sin(t)*radius lly: height + Math.cos(t)*back } } For My First JavaFX programme that I had in mind, I would need a PerspectiveTransform over its horizontal axis, like a rolodex. Searching the Internet I did not find cut and paste ready code (suggestions?). What I came up with was the following piece:

function getPTHor(t:Number):PerspectiveTransform { var width = 200; var height = 200;; var radius = height/2; var back = width/10; return PerspectiveTransform { ulx: 0 - Math.cos(t)*back uly: radius - Math.sin(t)*radius urx: width + Math.cos(t)*back ury: radius - Math.sin(t)*radius llx: 0 + Math.cos(t)*back lly: radius + Math.sin(t)*radius lrx: width - Math.cos(t)*back lry: radius + Math.sin(t)*radius } } Studying the Photo Flip sample there are couple of changes that I made to rotate it continuously instead flip forward and backward. This would require 2 changes, one is in the create(): Node function and the other is in Timeline. The original create(): Node is like below:

override public function create():Node { return Group { content: [ Group { content: backNode visible: bind (time0) effect: bind getPT(time) }, ] } } The above code shows elegantly how the back side and front side of a Node flips when time changes from negative to positive or vice versa. More general for the outline of a circle yields that it is equal to 2?R. So when between -? and 0 we will see the back side and between 0 and +? the front side. The Math.Sin() function will help us out here, so generalized:

override public function create():Node { return Group { content: [ Group { content: backNode visible: bind (Math.sin(time)0) effect: bind getPT(time) }, ] } } The other change in the Timeline is to accommodate any start and end values for time. In the Photo Flip sample you will find the following Timeline (you need to open the Main.fx file)

public var anim = Timeline { keyFrames: [ at(0s) { time=> Math.PI/2 tween Interpolator.LINEAR }, at(1s) { time=> -Math.PI/2 tween Interpolator.LINEAR }, KeyFrame { time: 1.0s action: function() { flipped = not flipped; } } ] } As you might understand by now is that the above code will now work for any values of time also for less then -? and greater than +?. The only addition we need to make is to calculate end position of the Node, whether we see the front or the back side.

public var anim = Timeline { keyFrames: [ at(0s) { time=> Math.PI/2 tween Interpolator.LINEAR }, at(1s) { time=> Math.PI/8.5 tween Interpolator.LINEAR }, KeyFrame { time: 1.0s action: function() { flipped = (Math.sin(time)