?
Solved

How to calculate (Pan,Tilt) angles by (x,y) screen projection pixel-coordinates for spheric panorama?

Posted on 2006-05-31
5
Medium Priority
?
4,848 Views
2 Endorsements
Last Modified: 2016-04-11
Hello!

I have a spheric panorama rendered by Java applet which is placed onto HTML page. You can see an instance of this applet here: http://www.immervision.com/en/multimedia/index.php?cat=multimedia (look near to right bottom side of page: in order to rotate panorama hold left button and drag it by mouse; in order to zoom use SHIFT and CTRL). I use the event handler for mouse event "OnClick". This handler recieves two arguments: (x,y) coordinates of clicked point inside Java Applet's window. (x,y) are in pixels relatively of the upper left corner of Applet. This is a "screen projection" coordinates. 0 <= x < w,   0 <= y < h.  w - Applet's width, h - height in pixels.

In order to pick an object inside the panorama i should use "model coordinates". Java Applet uses spheric coordinates (Pan, Tilt) angles in degrees as an "model coordinates". Pan - horizontal rotation angle, Tilt - vertical rotation angle. I should calculate model (pan, tilt) coordinates by "screen pixel" (x, y) coordinates. How it can be performed?

Input parameters:
  x, y - screen coordinates - point clicked by mouse (pixels);
  w, h - width and height of Java Applet's window (pixels);
  FOV - field of view angle: Java Applet's settings parameter (degrees);
  PanX, TiltC - model coordinates (angles) of the view's center poin (w/2, h/2)t: direction of the camera placed inside sphere in origin (degree);
 
Shoul be calculated:
  PanX, PanY - model coordinates (angles) matching to clicked (x, y) screen point (degrees).

Any ideas/ways - how to create missing mathematical formulas?

I need to calculate (Pan,Tilt) by (x,y) in order to dynamically generate hotspot object inside panorama. Hotspots can be added into panorama by either ways: statically or dynamically. In both cases i should specify key-points, each is defined by (pan, tilt) angles.

Illustration of model coordinates can be viewed at: http://exchange.activewebservices.ru/hotspotpolygonal.gif.
Panorama instance with static hotspots and illustration of model and screen coordinates can be viewed at: http://exchange.activewebservices.ru/tt/immervision.html.
In order to pan - hold left button and drag by mouse. In order to zoom - use shift and ctrl. You will see screen object (+) over the center of Applet's window. This is an raster image. Also, you can find (rotate back) two static hotspots (green and orange) inside of panorama. They are defined as:
<hotspotRectangle id="hs1" color="0xffffaa00" visible="true" display="true"
                      pan="179.12" tilt="12.78" panSize="8" tiltSize="7">
      <text>Hotspot 1</text>
      <mouseClick>javascript("onClick('h1');");</mouseClick>
    </hotspotRectangle>

   <hotspotRectangle id="hs2" color="0xffaacc00" visible="true" display="true"
                      pan="160.98" tilt="11.91" panSize="8" tiltSize="7">
      <text>Hotspot 2</text>
      <mouseClick>javascript("onClick('h2');");</mouseClick>
    </hotspotRectangle>.

They are seen as unfilled rectangles distorted by perspective transformation. Defined statically by (pan,tilt) of the center and by (panSize, tiltSize) determining width and height.

Still, in my mind comes only equations listed below:
pan = atan2(y, x);
tilt = atan2( z / sqrt(x*x + y*y) );
and  r*r = x*x + y*y + z*z;

But, it is far from applicable results.

Thanks for response!
2
Comment
Question by:Alexey Fedorov
  • 4
5 Comments
 

Author Comment

by:Alexey Fedorov
ID: 16807539
Seems, i had led out formulas which are very close to truth.

(Pan, Tilt) = F(x, y)

Pan = radToGrad( atan( ((w/2.0) - x) / d) );
Tilt = radToGrad( atan( ((h/2.0) - y) / d) );

d = (sqrt(w*w + h*h) / 2.0) / tan( gradToRad(fov/2.0) );

Where:
w, h - width and height of Java Applet (pixels);
Fov - current field of view angle (degrees);
Pan, Tilt - resulting model coordinates (degrees);
x, y - screen clicked point coordinates (pixels).


function radToGrad( rad )
{
return (rad * 180.0) / 3.14159265358979323846264;
}
function gradToRad( grad )
{
return (grad / 180.0) * 3.14159265358979323846264;
}

Formulas are working well for "Pan", but "Tilt" is distorted nearby of corners. However, if to set Pan=0, then "Tilt" will be rendered precisely true. It points that "perspective transformation" is applied by something way. Still, i have no ideas - how to take this in account.

Somebody have an ideas?

Thanks for response!
0
 

Author Comment

by:Alexey Fedorov
ID: 16810019
I had led out new formulas.
input: x, y, Fov, PanC, TiltC, w, h
output: PanX, TiltX

d = (sqrt(w*w + h*h) / 2.0) / tan( gradToRad(fov/2.0) );

PanX = PanC + radToGrad( atan( ((w/2.0) - x) / d) );
t = (w/2.0) - x;
TiltX = TiltC + radToGrad( atan(((h/2.0) - y) / sqrt(d*d + t*t)) );


function radToGrad( rad )
{
  return (rad * 180.0) / 3.14159265358979323846264;
}
function gradToRad( grad )
{
  return (grad / 180.0) * 3.14159265358979323846264;
}


Where:
  w, h - width and height of Java Applet (pixels);
  Fov - current field of view angle (degrees);
  PanC, TiltC - camera direction point (degrees).
  PanX, TiltX - model coordinates of clicked (x, y) point (degrees).
  x, y - screen clicked point coordinates (pixels).
  t, d - temporary vars.


Now PanX and TiltX are calculated correctly for any Fov and PanC with TiltC = 0. But if TiltC <> 0 formulas returns incorrect values.
Look to http://exchange.activewebservices.ru/tt/immervision.html - test hotspots can be added by right mouse button.

Somebody have any ideas?

Thanks for response!
0
 

Author Comment

by:Alexey Fedorov
ID: 16844343
Problem is solved! Right formulas are led out. Solution is below.

input: x, y, Fov, pan, tilt, w, h
output: panRes, tiltRes


pan = tofloat( get("camera","pan") );
tilt = tofloat( get("camera","tilt") );
fov = tofloat( get("camera","fov") );

w = tofloat( get( "applet", "width" ) );
h = tofloat( get( "applet", "height" ) );

x = tofloat( x );
y = tofloat( y );


r = (sqrt(w*w + h*h) / 2.0) / tan( gradToRad(fov/2.0) );


vx = r; vy = w/2.0 - x; vz = h/2.0 - y;
pan = gradToRad( pan ); tilt = gradToRad( -tilt );
cosp = cos( pan ); sinp = sin( pan );
cost = cos( tilt ); sint = sin( tilt );

/*My * Mz*/
vx2 = vx*cost*cosp - vy*sinp + vz*cosp*sint;
vy2 = vx*cost*sinp + vy*cosp + vz*sint*sinp;
vz2 = -vx*sint + vz*cost;


sinRes = vy2 / sqrt(vx2*vx2 + vy2*vy2);

panRes = radToGrad( asin(sinRes) );
if( vx2 <= 0 && vy2 > 0 )
panRes = 180 - panRes;
else if( vx2 < 0 && vy2 <= 0 )
panRes = -180 - panRes;

sinRes = vz2 / sqrt(vx2*vx2 + vy2*vy2 + vz2*vz2);
tiltRes = radToGrad( asin(sinRes) );


Where:
w, h - width and height of Java Applet (pixels);
Fov - current field of view angle (degrees);
pan, tilt - camera direction point (degrees).
panRes, tiltRes - model coordinates of clicked (x, y) point (degrees).
x, y - screen clicked point coordinates (pixels);
r - panorama model sphere radius;
vx, vy, vz - coordinates of vector from origin to picked point in projection plane;
vx2, vy2, vz2 - transformed vector of picked point.


Description how the formulas was led is here:
http://exchange.activewebservices.ru/tt/DetectAnglesEng.rtf

Full sources are here:
http://exchange.activewebservices.ru/tt/PanoDemo2.zip

Online demo is here (use right mouse button to place dynamic hotspots):
http://exchange.activewebservices.ru/tt/immervision.html
0
 

Accepted Solution

by:
EE_AutoDeleter earned 0 total points
ID: 16978674
alexf2,
Because you have presented a solution to your own problem which may be helpful to future searches, this question is now PAQed and your points have been refunded.

EE_AutoDeleter
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Artificial Intelligence comes in many forms, and for game developers, Path-Finding is an important ability for making an NPC (Non-Playable Character) maneuver through terrain.  A* is a particularly easy way to approach it.  I’ll start with the algor…
As game developers, we quickly learn that Artificial Intelligence (AI) doesn’t need to be so tough.  To reference Space Ghost: “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer. (http://www.youtu…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question