You are not logged in.

Dear visitor, welcome to krpano.com Forum. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Wednesday, January 11th 2023, 10:02pm

Atv to height conversion mismatch for cylindrical panoramas

Hi. I'm having an issue related to converting my hotspots' cylindrical coordinates to width/height coordinates.

Context: I have thousands of hotspots defined throughout hundreds of my cylindrical panoramas.
Now I need to get their width/height pixel location equivalents on the original images.
Converting ath -> x works perfectly fine, however for atv there's a varying vertical offset I'm getting.

I'm using formulas posted by Klaus in a different thread:

Source code

1
2
3
4
5
ath = ((x / width) - 0.5) * hfov
atv = ((y / height) - 0.5) * vfov
where for cylindrical panorama:
hfov = 360
vfov = 360 * arctan(height/width * PI) / PI


Example:
1. I have an image of size: 28133 x 6608.

2. I make a panorama out of it using makepano and following settings:

Source code

1
2
3
4
5
makepano -config=base.config -panotype=cylinder -hfov=360 -vfov=auto -voffset=0 
...
converttocube=true
converttocubelimit=360x30
maxcubesize=2048


Note: makepano generates vlookatmin="-36.424" and vlookatmax="36.424"

3. In the viewer using textfield plugin showing draggable cursor's ath/atv I pick an exact point eg. top of a mountain.
It gives me following coordinates: ath="-74.99364949868569" atv="-19.815171882512473"
What produces aforementioned ath/atv coordinates is a result of an action:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<action name="draghotspot">
<![CDATA[
    if(%1 != dragging,
        spheretoscreen(ath, atv, hotspotcenterx, hotspotcentery);
        sub(drag_adjustx, mouse.stagex, hotspotcenterx);
        sub(drag_adjusty, mouse.stagey, hotspotcentery);
        draghotspot(dragging);
      ,
        if(pressed,
            sub(dx, mouse.stagex, drag_adjustx);
            sub(dy, mouse.stagey, drag_adjusty);
            screentosphere(dx, dy, ath, atv);
            copy(print_ath, ath);
            copy(print_atv, atv);
            txtadd(plugin[hotspotinfo].html, '&lt;hotspot name="', get(name), '"&nbsp;ath="', get(print_ath), '"&nbsp;atv="', get(print_atv), '"/&gt;');
            set(pointer_name, get(name));
            set(pointer_ath, get(ath));
            set(pointer_atv, get(atv));
            delayedcall(0, draghotspot(dragging) );
          );
      );
]]></action>


4. When I store the ath/atv output and render a panorama with this hotspot and its atv/atv layered it points exactly in the place I picked. It's been working for years for hundreds of panoramas.

5. Now the very same point on the source image has following XY px coordinates: 8206, 1690
Calculating manually ath and atv gives following results:

Source code

1
2
3
4
Image: 28133 x 6608
ath = -74.993068638254007748906977570824
vfov = 360 * arctan( 6608/28133 * PI ) / PI = 72.8480327
atv = -17.7930878901


That proves that the ath is correct but in atv -> height conversion there's a difference of -2.022083992412473 degrees (viewer yields -19.815171882512473 as mentioned above, but it should yield -17.7930878901).

Note: looking at different points in height yields good conversion in the middle (ath = 0), but the further the point from the middle of the image horizon the offset is bigger. Given that I feel it's related to cylindrical-cubic projection?

Any help appreciated.

Firstly, why the viewer is yielding incorrect atv or what I've been doing wrong for years?

Secondly, how to convert existing points (ath, atv) to width/height pixel values?

Thanks

2

Friday, February 24th 2023, 10:13am

Hi,

1. the hotspot ath/atv coordinates are always spherical, regardless of the image type.

2 .for converting a point on cylinder surface to a point on spherical surface only the right math need to be used (the image size to hfov/vfov conversion is wrong here).

Here a little helper script for doing that automatically (needs version 1.21):

Source code

1
2
3
4
5
6
7
8
<style name="cylinder_image_xy_pos" onloaded.addevent="calc_cylinder_hs_pos();" />
		
<action name="calc_cylinder_hs_pos">
  callwhen(image.hres GT 0,
    ath = (imgx/image.hres - 0.5) * image.hfov;
    atv = atan(tan(image.vfov/2 * Math.PI/180) * 2 * ((imgy / image.vres) - 0.5)) * 180/Math.PI;
  );
</action>

- the callwhen ensure that the image size information are available before doing the math
- the tan(image.vfov/2 * Math.PI/180) * 2 calcs the vertical range of the cylinder
- the * ((imgy / image.vres) - 0.5) maps the pixel-point linear to that vertical range
- and then that vertical position is converted back to an angle in degrees

To use the script, give your hotspots the "cylinder_image_xy_pos" style and define the pixel-position on the cylinder image as custom imgx/imgy settings:

Source code

1
2
3
<hotspot name="s1" style="cylinder_image_xy_pos" imgx="1256" imgy="1977" />
<hotspot name="s2" style="cylinder_image_xy_pos" imgx="732" imgy="1125" />
...


Best regards,
Klaus