How Is the focalLength Calculated

The focalLength of a custom perspective projection is not what you might think. You create a PerspectiveProjection object, pp = new PerspectiveProjection(), and set pp's properties. When you assign pp to transform.perspectiveProjection of a DisplayObject, focalLength changes. How? Why? We explain in this tutorial. The value of focalLength is crucial for effective 3D depth-sorting.

Download

  • Download the source file corresponding to the example above: ppfl.fla

Surprise, Surprise!

In the movie above, we have a Sprite, 'container', which is a black rectangle. The registration point of 'container is at its center. (In our example, we use Timeline code, but the behavior of PerspectiveProjection is the same if the code resides in external classes.) We assign a custom PerspectiveProjection to 'container' as follows.

var pp:PerspectiveProjection=new PerspectiveProjection();

By default, pp.fieldOfView=55 and pp.projectionCenter is at (0,0). To be sure, we make that explicit:

var fW:Number=55;

pp.fieldOfView=fW;

pp.projectionCenter=new Point(0,0);

..................

var container:Sprite=new Sprite();

this.addChild(container);

var containerWidth:Number=400;

var containerHeight:Number=350;

drawContainer();

container.transform.perspectiveProjection=pp;

container.x=containerWidth/2+15;

container.y=containerHeight/2+45;

The function 'drawContainer' defined later in the script draws the black rectangle.

Now trace the following two values:

trace(pp.focalLength);

You see about  480.25 in the Output panel. Now trace:

trace(container.transform.perspectiveProjection.focalLength);

Here comes a surprise. You see  816.42 in the Output panel. Why the discrepancy and which value gives the real focalLength for the PerspectiveProjection assignment? The question is important as the value for the focalLength determines the angles at which faces of the rotating card should flip. (The card is a child of container.)

The Answer

When you create a PerspectiveProjection object, pp, its focalLength is calculated based on pp.fieldOfView and the DEFAULT width of the Stage, 500. Thus, you obtain:

focalLength = (width-of-Stage/2)/tan((Pi/180)*(fieldOfView/2)) =
                                250/tan((Pi/180)*(55/2)) = 480.25

When you assign the PerspectiveProjection object to container.transform.perspectiveProjection, the focalLength is recalculated based on the width of container's stage object. In our example, the width of the Stage is set to 850. Thus, we obtain:

focalLength = (width-of-Stage/2)/tan((Pi/180)*(fieldOfView/2)) =
                                425/tan((Pi/180)*(55/2)) = 816.42

Here is a picture that explains the formula we used above to calculate focalLength based of on (assumed or actual) width of the Stage:

Setting pp.focalLength instead of pp.fieldOfView will not work much better. After setting pp.focalLength, pp.fiedlOfView is calculated based on stage width eqaul to 500. After assigning pp to container, focalLength is recalculatec based on the pp.fieldOfView and the actual width of the Stage.

Knowing focalLength Is Crucial for Effective Depth-Sorting

focalLength and projectionCenter determine the position of the Observer. The position of the Observer is important for depth-sorting. See our depth-sorting tutorials:

Knowing the angles at which a rotating tile flips is also important when constructing photo galleries. See for example our cylindrical gallery in which we want to know when a thumbnail disappears from view:

Our Experiment Proves the Theory

The value for the focalLength determines the angles at which faces of the rotating card should flip. In our applet the correct values for the angles are obtained if we use the focalLength = 816.42; that is, the focalLength corresponding to the actual width of the Stage. Here are pictures that explain what happens in the applet. Recall that 'container' is the black rectangle to which a custom perspective projection is assigned. The two-sided card, 'card' is a child of 'container'. The set up is depicted by the image below:

The angles at which the sides of the card flip are calculated as follows:

Sorting of the rotating card can be done as in our tutorial: Depth-Sorting of a 3D Card and the Projection Center in Flash CS4. The method presented there is more universal. In this tutorial we wanted to illustrate properties of custom perspective projection.

Back to Flash CS4 Tutorials              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.