wesleysnipes, Newbie Posted: 05 November 2011 10:52 PM Total Posts: 20
Hi,
I have a sphere and on the surface I have points plotted. I want to rotate the sphere to face the camera. I have the xyz of the points but I don’t know how to calculate the correct rotation of the sphere.
Any help on this would be greatly appreciated.
Thanks
Stephen Hopkins, Sr. Member Posted: 06 November 2011 01:41 AM Total Posts: 110
[ # 1 ]
have you tried using lookAt?, or do you need the actual angle
wesleysnipes, Newbie Posted: 06 November 2011 10:26 PM Total Posts: 20
[ # 2 ]
Thanks for the reply. I have a partial solution. I just normalize the point I’m trying to point at and then scale it to the current camera length, then I just move the actual camera rather then spin the object.
All this works perfectly, but when I move to a point that is on the opposite side of the sphere, the camera flys through rather than around. I need it to act as a hover camera. I tried using tween max bezier, but I can’t get it to work with a vector3d.
Any thoughts?
Stephen Hopkins, Sr. Member Posted: 06 November 2011 10:49 PM Total Posts: 110
[ # 3 ]
I think i understand your problem/program now. Maybe you can convert your points to spherical coordinates. Your camera will stay fixed looking directly at the center of the sphere. I think from the spherical coordinates/rotations, you just plug them into rotateX and rotateY to lineup the point with your camera, although I may be wrong.
edit: you may also want to remultiply/re-rotate everything every time your rotate the sphere, as I am not sure of away3d’s rotation order. You set the rotations to 0 first, then use either quaternions, or the rotate properties/functions to rotate the object to the angles you need.
wesleysnipes, Newbie Posted: 06 November 2011 11:36 PM Total Posts: 20
[ # 4 ]
Hmm, I’m lost now. I have gone back to using the hovercam but I don’t see how to calculate the pan and tilt.
To simplify this, here’s the example:
1) Single sphere radius 100
2) Single cube placed at y:100
3) Camera needs to now face the cube dead on
4) Set panAngle to 90
The question is, how to I calculate the pan and tilt? I know it needs to go to 90 cause I’m placing the cube at an easy spot. How would I calculate the pan and tilt of a cube somewhere random on the face of the sphere
The only reason I want to move the camera around and not the sphere is so I can zoom in and out and not worry about move the sphere around.
Hope this makes sense.
Stephen Hopkins, Sr. Member Posted: 07 November 2011 12:08 AM Total Posts: 110
[ # 5 ]
You should draw a picture, with your sphere at the origin, and points on the sphere.
you want to convert x,y,z to phi for pan. theta is tilt. r is the distance of the point from the center of the sphere.
wesleysnipes, Newbie Posted: 07 November 2011 05:44 PM Total Posts: 20
[ # 6 ]
Thanks for the reply. Really struggling with this. I’ve been digging around all night and this morning.
I cannot seem to get this thing to spin correctly. Any ideas? I’ve also tried to move the hover cam, same thing. It always goes to the wrong spot. I also found a different post on this forum with a slightly different spherical formula, the one here is using whats on the wiki.
private var _container : ObjectContainer3D; private var _sphere : Sphere;
...(Not showing, but I add this sphere to an ObjectContainer3D and setup the scene)...
var targetVector3D : Vector3D = _sphere.vertices[0].position; var r:Number = targetVector3D.length; var theta:Number = Math.acos(targetVector3D.z / r); var phi:Number = Math.atan2(targetVector3D.y, targetVector3D.x);
...(I also create a test cube and place it at the vert just to visually confirm I have the correct location)...
//Spin it _container.rotationY = theta/(Math.PI/180); _container.rotationX = phi/(Math.PI/180);
Somokon, Member Posted: 07 November 2011 08:41 PM Total Posts: 75
[ # 7 ]
wesleysnipes - 07 November 2011 05:44 PM
var targetVector3D : Vector3D = _sphere.vertices[0].position; var r:Number = targetVector3D.length; var theta:Number = Math.acos(targetVector3D.z / r); var phi:Number = Math.atan2(targetVector3D.y, targetVector3D.x);
You should swap y and z in the conversion formula, because away3d y and z axes are swapped from what they are on wikipedia.
Haven’t tested it, but then try this:
Use the container.rotate method to rotate the sphere about the y axis by -theta (maybe +theta, but I think -theta should work), and then about the z axis by -phi (again, possibly +phi).
wesleysnipes, Newbie Posted: 07 November 2011 10:13 PM Total Posts: 20
[ # 8 ]
Ya, I’m really having a hard time with this. I have tried every possible combination I can think of. I can’t seem to get this to work.
Also, I don’t think rotate will work for me, since it’s additive. Instead I am trying to use rotateTo().
Not sure what I should use for which one. I have tried all types of combinations in rotateTo.
I’ve updated the conversion to:
var r:Number = Math.sqrt(point.x*point.x + point.z*point.z + point.y*point.y); var theta:Number = Math.acos(point.y / r); var phi:Number = Math.atan2(point.z, point.x);
Any thoughts? A code snippet would be such a big help if you have one.
wesleysnipes, Newbie Posted: 07 November 2011 10:26 PM Total Posts: 20
[ # 9 ]
Also, one quick observation, if I swap y and z, and I have something with only a y property (ie cube at (0, 100, 0)) then theta and phi will both be 0 with the above formula.
80prozent, Sr. Member Posted: 07 November 2011 10:50 PM Total Posts: 430
[ # 10 ]
hi
maybe this could be a solution for your problem without to much math.
make sphere with radius 100.
make a objectcontainer3D
make the objectcontainer3D child of the sphere. placed at 0,0,0
make a cube child of the objectcontainer3D. move it to 100,0,0
make a camera child of the objectcontainer3D. move it to 200,0,0
make it look at cube.
now you can rotate your objectcontainer3d. the cube will move on sphere-surface, the camera will always hover over cube.
[edit:]
you have the x,y,z coordinates on the surface of the sphere?
are they lokal coordinates (relative to the sphere) or global coordinates?
if you allready have the lokal coordinates, make your camera child of the sphere too.
apply the x,y,z coordinates to your camera, multiply them with a distance (positive Number) and make it look at 0,0,0.
Somokon, Member Posted: 07 November 2011 11:05 PM Total Posts: 75
[ # 11 ]
wesleysnipes - 07 November 2011 10:26 PM
Also, one quick observation, if I swap y and z, and I have something with only a y property (ie cube at (0, 100, 0)) then theta and phi will both be 0 with the above formula.
That’s correct. Using this formula, theta measures the angle (in radians) from the positive y direction. phi measures the angle from the negative z direction (out of the screen) going counterclockwise.
Yeah this stuff can be kind of confusing. Maybe someone with better knowledge of the away3d API can come up with a better approach.
wesleysnipes, Newbie Posted: 08 November 2011 12:17 AM Total Posts: 20
[ # 12 ]
Thanks for the help guys, I’m still really stuck. I’m going to paste a simple version below so you can see what I’m trying to do:
In this sample, with each click of the button, it generates a cube and adds it to the next point on the sphere. I need the container to then rotate to face the camera. Hope this makes sense. In this code, you will see that does not work.
Please check the generateCube method. This is where the actual calculation is happening.
[SWF(width='600', height='800', backgroundColor='#e3e3e3', frameRate='30')] public class TestOrbit extends Sprite {
//-------------------------------------- // PROPS //-------------------------------------- private var _view : View3D; private var _scene : Scene3D; private var _camera : Camera3D;
private var _container : ObjectContainer3D; private var _sphere : Sphere;
private var _testButton : Button; private var _lastVerticeIndex : int = 0;
//-------------------------------------- // PUBLIC METHODS //-------------------------------------- public function TestOrbit() { setupScene(); createObjects(); createUI(); }
private function generateCube () : void { //Get a point on the spehere var nextPosition : Vector3D = _sphere.vertices[_lastVerticeIndex].position;
//Generate new cube and add it var cube : Cube = new Cube({width:10, height:10, depth:10}); cube.position = nextPosition; _container.addChild(cube); _lastVerticeIndex++;
//Rotate the sphere so the new point is facing the camera! This part DOES NOT work! var r:Number = nextPosition.length; var theta:Number = (Math.acos(nextPosition.y / r))/(Math.PI/180); var phi:Number = (Math.atan2(nextPosition.z, nextPosition.x))/(Math.PI/180);
_container.rotateTo(-phi, -theta, 0); }
//-------------------------------------- // HANDLER METHODS //-------------------------------------- private function ticHandler ( e : Event ) : void { _view.render(); }
private function _testButtonClickedHandler ( e : MouseEvent ) : void { generateCube(); } } }
Somokon, Member Posted: 08 November 2011 12:44 AM Total Posts: 75
[ # 13 ]
Hey, I just tested and this works:
private function generateCube () : void {
_container.transform = new Matrix3D(); //Get a point on the spehere var nextPosition : Vector3D = _sphere.vertices[_lastVerticeIndex].position;
//Generate new cube and add it var cube : Cube = new Cube({width:10, height:10, depth:10}); cube.position = nextPosition; _container.addChild(cube); _lastVerticeIndex++;
//Rotate the sphere so the new point is facing the camera! This part DOES NOT work! var r:Number = nextPosition.length; var theta:Number = (Math.acos(nextPosition.y / r))/(Math.PI/180); var phi:Number = (Math.atan2(nextPosition.z, nextPosition.x))/(Math.PI/180);
[SWF(width='600', height='800', backgroundColor='#e3e3e3', frameRate='30')] public class TestOrbit extends Sprite {
//-------------------------------------- // PROPS //-------------------------------------- private var _view : View3D; private var _scene : Scene3D; private var _camera : Camera3D;
private var _container : ObjectContainer3D; private var _sphere : Sphere;
private var _testButton : Button; private var _lastVerticeIndex : int = 0;
//-------------------------------------- // PUBLIC METHODS //-------------------------------------- public function TestOrbit() { setupScene(); createObjects(); createUI(); }
private function generateCube () : void { //Get a point on the spehere var nextPosition : Vector3D = _sphere.vertices[_lastVerticeIndex].position;
//Generate new cube and add it var cube : Cube = new Cube({width:10, height:10, depth:10}); cube.position = nextPosition; _container.addChild(cube); _camera.position=nextPosition; _camera.position.scaleBy(s:Number) _lastVerticeIndex++;
_camera.lookAt(0,0,0); }
//-------------------------------------- // HANDLER METHODS //-------------------------------------- private function ticHandler ( e : Event ) : void { _view.render(); }
private function _testButtonClickedHandler ( e : MouseEvent ) : void { generateCube(); } } }
wesleysnipes, Newbie Posted: 08 November 2011 02:21 AM Total Posts: 20
[ # 15 ]
Thanks for the reply. That does work to get me to the destination, the trouble is I need to orbit.
If I use this solution, it will fly straight through the globe if the point happens to be on the other side.
I need a smooth orbit around to the point at a consistent distance from the sphere.