Calculating the Projected Bounds using Utils3D.projectVector()
If you are playing with objects in 3D and want their projected bounds, there’s a neat flash functionality for that – Utils3D.projectVector(). However it may not be that apparent how to use it. Here I’m showing a small helper function that does the trick.
The projectVector() method actually takes a Matrix3D for a parameter. Note that here you should pass in the Matrix3D of the object in question combined with the perspective projection of its parent. This is not as trivial as it seems, as you’d need to also translate by the projectionCenter and the focalLength:
16 17 18 19 20 | // Setup the matrix var centerX:Number = projection.projectionCenter.x; var centerY:Number = projection.projectionCenter.y; matrix.appendTranslation(-centerX, -centerY, projection.focalLength); matrix.append(projection.toMatrix3D()); |
After that just pass in the matrix and the point to be projected to Utils3D.projectVector(). Then translate the result by centerX and centerY.
Here’s the helper function source, it takes in bounds, the matrix of the object and the perspective projection and returns the projected 2D bounds:
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public static function projectBounds(bounds:Rectangle, matrix:Matrix3D, projection:PerspectiveProjection):Rectangle { // Setup the matrix var centerX:Number = projection.projectionCenter.x; var centerY:Number = projection.projectionCenter.y; matrix.appendTranslation(-centerX, -centerY, projection.focalLength); matrix.append(projection.toMatrix3D()); // Project the corner points var pt1:Vector3D = new Vector3D(bounds.left, bounds.top, 0); var pt2:Vector3D = new Vector3D(bounds.right, bounds.top, 0) var pt3:Vector3D = new Vector3D(bounds.left, bounds.bottom, 0); var pt4:Vector3D = new Vector3D(bounds.right, bounds.bottom, 0); pt1 = Utils3D.projectVector(matrix, pt1); pt2 = Utils3D.projectVector(matrix, pt2); pt3 = Utils3D.projectVector(matrix, pt3); pt4 = Utils3D.projectVector(matrix, pt4); // Find the bounding box in 2D var maxX:Number = Math.max(Math.max(pt1.x, pt2.x), Math.max(pt3.x, pt4.x)); var minX:Number = Math.min(Math.min(pt1.x, pt2.x), Math.min(pt3.x, pt4.x)); var maxY:Number = Math.max(Math.max(pt1.y, pt2.y), Math.max(pt3.y, pt4.y)); var minY:Number = Math.min(Math.min(pt1.y, pt2.y), Math.min(pt3.y, pt4.y)); // Add back the projection center bounds.x = minX + centerX; bounds.y = minY + centerY; bounds.width = maxX - minX; bounds.height = maxY - minY; return bounds; } |
The full source is here projectedbounds.mxml.
