forked from: Bounding ellipse of sphere in 2D - what's wrong?
Thought it was imprecise .asin/.acos but no :(
// Thought it was imprecise .asin/.acos but no :(
package
{
import caurina.transitions.Tweener;
import flash.display.Sprite;
import flash.events.Event;
import sandy.core.Scene3D;
import sandy.core.scenegraph.Camera3D;
import sandy.core.scenegraph.Group;
import sandy.core.scenegraph.Shape3D;
import sandy.primitive.GeodesicSphere;
import sandy.primitive.Sphere;
[SWF(width=465, height=465, frameRate=30, backgroundColor=0xFFFFFF)]
/**
* Bounding ellipse of sphere in 2D - what's wrong?
* @author makc
*/
public class CircleTest extends Sprite {
private var container:Sprite;
private var scene:Scene3D;
private var sphere:Shape3D;
private var R:Number = 100;
public function CircleTest () {
container = Sprite (addChild (new Sprite));
scene = new Scene3D ("scene", container, new Camera3D (2000, 465), new Group ("root"));
sphere = new GeodesicSphere ("sphere", R, 3); // new Sphere ("sphere", R);
sphere.z = 400; scene.root.addChild (sphere);
toLeft ();
addEventListener (Event.ENTER_FRAME, onEnterFrame);
}
private function toLeft ():void {
Tweener.addTween (sphere, { x: -1500, time: 4, transition:"linear", onComplete:toRight });
}
private function toRight ():void {
Tweener.addTween (sphere, { x: +1500, time: 4, transition:"linear", onComplete:toLeft });
}
private function onEnterFrame (e:Event):void {
// sphere camera coords
var sz:Number = (sphere.z - scene.camera.z);
var sx:Number = sphere.x;
// screen coords
var sx_screen:Number = sx * scene.camera.focalLength / sz;
var R_screen:Number = R * scene.camera.focalLength / sz;
// distance to sphere
var sd:Number = Math.sqrt (sx*sx + sz*sz);
// angles
var sina:Number = R / sd, cosa:Number = Math.sqrt (1 - sina * sina);
var sinb:Number = sx / sd, cosb:Number = Math.sqrt (1 - sinb * sinb);
var tana:Number = sina / cosa;
var cosbma:Number = cosa * cosb + sina * sinb;
var cosbpa:Number = cosa * cosb - sina * sinb;
// apsides
var dm:Number = R_screen / cosbma;
var dp:Number = R_screen / cosbpa;
// semiaxes
var A:Number = 0.5 * (dm + dp);
var B:Number = sd * tana * scene.camera.focalLength / sz;
// show stuff
scene.render ();
x = 462/2 -1000 -sx_screen;
container.graphics.clear ();
container.graphics.beginFill (0xFF00);
container.graphics.drawRect (1000 +sx_screen -4, 465/2 -4, 8, 8);
container.graphics.endFill ();
container.graphics.lineStyle (1, 0xFF0000);
container.graphics.moveTo (1000 +sx_screen -dm, 465/2 -40);
container.graphics.lineTo (1000 +sx_screen -dm, 465/2 +40);
container.graphics.moveTo (1000 +sx_screen +dp, 465/2 -40);
container.graphics.lineTo (1000 +sx_screen +dp, 465/2 +40);
container.graphics.drawEllipse (1000 +sx_screen -dm, 465/2 - B, 2*A, 2*B);
// randomize
sphere.rotateX += Math.random ();
sphere.rotateY += Math.random ();
sphere.rotateZ += Math.random ();
}
}
}