Calculate angle of rotation?

Software: Away3D 3.x

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

 

 Signature 

http://www-scf.usc.edu/~shopkins

   

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.

 

 Signature 

http://www-scf.usc.edu/~shopkins

   

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.

If you are gonna use the hover camera, your angle can be calculated using spherical coordinates. http://en.wikipedia.org/wiki/Spherical_coordinates#Cartesian_coordinates

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.

 

 Signature 

http://www-scf.usc.edu/~shopkins

   

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.r);
var 
phi:Number Math.atan2(targetVector3D.ytargetVector3D.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.r);
var 
phi:Number Math.atan2(targetVector3D.ytargetVector3D.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.point.z*point.point.y*point.y);
var 
theta:Number Math.acos(point.r);
var 
phi:Number Math.atan2(point.zpoint.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.

r = length = 100
theta = y/r = 100/100 = 0
phi = (0, 0) = 0

Am I missing something here?

 

   

Avatar
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.

 

 Signature 

sorry…i hope my actionscript is better than my english…

   

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.

r = length = 100
theta = y/r = 100/100 = 0
phi = (0, 0) = 0

Am I missing something here?

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:

Orbit Test

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.

Thanks for any help guys!

package
{
 import away3d
.cameras.Camera3D;
 
import away3d.containers.ObjectContainer3D;
 
import away3d.containers.Scene3D;
 
import away3d.containers.View3D;
 
import away3d.primitives.Cube;
 
import away3d.primitives.Sphere;
 
import away3d.test.Button;
 
 
import flash.display.Sprite;
 
import flash.events.Event;
 
import flash.events.MouseEvent;
 
import flash.geom.Vector3D;
 
 
[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 METHODS
  //--------------------------------------
  
private function setupScene () : void
  {
   _view 
= new View3D();
   
_scene _view.scene;
   
_camera _view.camera;
   
   
addChild(_view);
   
   
_view.stage.stageWidth/2;
   
_view.stage.stageHeight/2;
   
   
this.addEventListener(Event.ENTER_FRAMEticHandler);
  
}
  
  
private function createObjects () : void
  {
   _container 
= new ObjectContainer3D();
   
_scene.addChild(_container);
   
   
_sphere = new Sphere({radius:100});
   
_container.addChild(_sphere);
  
}
  
  
private function createUI () : void
  {
   _testButton 
= new Button("Generate Cube!"115);
   
_testButton._testButton.10;
   
_testButton.addEventListener(MouseEvent.CLICK_testButtonClickedHandler);
   
addChild(_testButton);
  
}
  
  
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:10height:10depth: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.r))/(Math.PI/180);
   var 
phi:Number = (Math.atan2(nextPosition.znextPosition.x))/(Math.PI/180);
   
   
_container.rotateTo(-phi, -theta0);
  
}
  
  
//--------------------------------------
  //  HANDLER METHODS
  //--------------------------------------
  
private function ticHandler Event ) : void
  {
   _view
.render();
  
}
  
  
private function _testButtonClickedHandler MouseEvent ) : void
  {
   generateCube
();
  
}
 }

 

 

File Attachments
TestOrbit.as  (File Size: 3KB - Downloads: 356)
   

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:10height:10depth: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.r))/(Math.PI/180);
   var 
phi:Number = (Math.atan2(nextPosition.znextPosition.x))/(Math.PI/180);
   
   
_container.rotate(Vector3D.X_AXIStheta 90);
   
_container.rotate(Vector3D.Y_AXISphi 90);
  

 

   

Avatar
80prozent, Sr. Member
Posted: 08 November 2011 12:49 AM   Total Posts: 430   [ # 14 ]

i couldnt try this code because i have no away3d 3.x right now, but this could eventually work for you…..

package
{
 import away3d
.cameras.Camera3D;
 
import away3d.containers.ObjectContainer3D;
 
import away3d.containers.Scene3D;
 
import away3d.containers.View3D;
 
import away3d.primitives.Cube;
 
import away3d.primitives.Sphere;
 
import away3d.test.Button;
 
 
import flash.display.Sprite;
 
import flash.events.Event;
 
import flash.events.MouseEvent;
 
import flash.geom.Vector3D;
 
 
[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 METHODS
  //--------------------------------------
  
private function setupScene () : void
  {
   _view 
= new View3D();
   
_scene _view.scene;
   
_camera _view.camera;
   
   
addChild(_view);
   
   
_view.stage.stageWidth/2;
   
_view.stage.stageHeight/2;
   
   
this.addEventListener(Event.ENTER_FRAMEticHandler);
  
}
  
  
private function createObjects () : void
  {
   _container 
= new ObjectContainer3D();
   
_scene.addChild(_container);
   
   
_sphere = new Sphere({radius:100});
   
_container.addChild(_sphere);
   
_container.addChild(_camera);

  
}
  
  
private function createUI () : void
  {
   _testButton 
= new Button("Generate Cube!"115);
   
_testButton._testButton.10;
   
_testButton.addEventListener(MouseEvent.CLICK_testButtonClickedHandler);
   
addChild(_testButton);
  
}
  
  
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:10height:10depth: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 Event ) : void
  {
   _view
.render();
  
}
  
  
private function _testButtonClickedHandler MouseEvent ) : void
  {
   generateCube
();
  
}
 }

 

 Signature 

sorry…i hope my actionscript is better than my english…

   

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.

 

   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X