Sie sind nicht angemeldet.

1

Mittwoch, 30. Oktober 2019, 08:44

Flying arrow pointing towards hotspot

I'm creating an arrow (hotspot[arrow]) that points to a hotspot (hotspot[cross]). Right now, using the code below, it looks like this:



The arrow should always be pointing to the center of the cross, but it doesn't. I guess I'm over complicating things in my code. So, do you have any suggestions how to approach this?

Thanks!

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<hotspot name="cross" ath="102.017" atv="13.112" url="cross.png" distorted="true" scale="0.3" />

<hotspot name="arrow" edge="left" ath="0" atv="0" url="arrow.png>" distorted="true" scale="0.1" alpha="0.7" />

<events onviewchange="arrow()" />

<action name="arrow">

	if(view.hlookat != last_view_hlookat OR view.vlookat != last_view_vlookat,
		
		copy(last_view_hlookat, view.hlookat);
		copy(last_view_vlookat, view.vlookat);


		mod(cross_ath,hotspot[cross].ath,360);
		add(cross_ath,360);
		mod(cross_ath,360);

		mod(hlookat,view.hlookat,360);
		add(hlookat,360);
		mod(hlookat,360);

		sub(residue,hlookat,cross_ath);

		copy(cross_atv,hotspot[cross].atv);
		copy(vlookat,view.vlookat);
		sub(vdiff,cross_atv,vlookat);
		div(vdiff,90);

		if((hlookat GT cross_ath) AND residue LT 180,
			
			set(rot,0);
			Math.abs(residue);
			sub(residue,180,residue);
			div(residue,2);
			mul(vdiff,residue);

			sub(rot,vdiff);
			,

			if(residue GT 180,
				sub(residue,360);
			);

			set(rot,180);
			Math.abs(residue);
			sub(residue,180,residue);
			div(residue,2);
			mul(vdiff,residue);

			add(rot,vdiff);
		);

		set(hotspot[arrow].rotate,get(rot));

		set(hotspot[arrow].ath,get(hlookat));
		set(hotspot[arrow].atv,get(vlookat));

	);

</action>

2

Mittwoch, 30. Oktober 2019, 16:59

I found a approach: There's a excellent tutorial on how to calculate bearing and distance from one point to another on the globe. Using longitues and latitudes. I'll take those scripts as inspiration *thumbup*

https://www.movable-type.co.uk/scripts/latlong.html

light_line

Fortgeschrittener

Beiträge: 169

Beruf: krpano freelancer || creating ideas & coding them || krpano developer

  • Nachricht senden

3

Donnerstag, 31. Oktober 2019, 10:06

Hi,
can you share the final code with us?

4

Donnerstag, 21. November 2019, 13:51

Hi,
can you share the final code with us?

Sure!

I added this JS function to the page krpano is embedded on:

Quellcode

1
2
3
4
5
6
7
8
9
10
function bearing(hlookat,vlookat,ath,atv) {
	const phi_1 = vlookat * ( Math.PI / 180 );
	const phi_2 = atv * ( Math.PI / 180 );
	const delta_lambda = (ath - hlookat) * ( Math.PI / 180 );
	const x = Math.cos(phi_1) * Math.sin(phi_2) - Math.sin(phi_1) * Math.cos(phi_2) * Math.cos(delta_lambda);
	const y = Math.sin(delta_lambda) * Math.cos(phi_2);
	const theta = Math.atan2(y, x);
	const bearing = theta * (180/Math.PI);
	return -bearing;
}


... and accessed the function in krpano this way:

Quellcode

1
2
3
4
5
6
7
8
9
<events onviewchange="arrow()" keep="true" />

<action name="arrow">

	txtadd(jsget_bearing,'bearing(',get(view.hlookat),',',get(view.vlookat),',',get(hotspot[get(global.point_to)].ath),',',get(hotspot[get(global.point_to)].atv),')');
	jsget(bearing, get(jsget_bearing) );
	set(hotspot[arrow].rotate,get(bearing));

</action>


Cheers

5

Freitag, 22. November 2019, 07:09

thanks *thumbsup*
This code I made in krpano without JS:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<events onviewchange="arrow_rotate(target, arrow)" keep="true" />

<action name="arrow_rotate" scope="local" args="target, arrow"> 
	calc(phi_1,global.view.vlookat * ( Math.PI / 180 ) ); 
	calc(phi_2, global.hotspot[get(target)].atv * ( Math.PI / 180 ));
	calc(delta_lambda, (global.hotspot[get(target)].ath - global.view.hlookat) * ( Math.PI / 180 ));
	Math.cos(cos1,get(phi_1));  
	Math.sin(sin,get(phi_2));
	Math.sin(sin2,get(phi_1));
	Math.cos(cos2,get(phi_2));
	Math.cos(cos3,get(delta_lambda));
	Math.sin(sin3,get(delta_lambda));
	calc(x, cos1 * sin - sin2 * cos2 * cos3 );  
	calc(y, sin3 * cos2); 
	Math.atan2(theta,y, x);
	calc(bearing, -1 * theta * (180/Math.PI) + 180);  
	set(global.hotspot[get(arrow)].rotate,get(bearing));
</action>
	

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »San7« (22. November 2019, 09:59)


light_line

Fortgeschrittener

Beiträge: 169

Beruf: krpano freelancer || creating ideas & coding them || krpano developer

  • Nachricht senden

7

Montag, 31. Januar 2022, 00:29

Hello San7!!! How your code works? because I tried it but nothing.

I tried with two hotspots called target and arrow.

Many thanks
Laura
Test it

8

Montag, 31. Januar 2022, 07:30

Hello San7!!! How your code works? because I tried it but nothing.
Hi, this is working

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<layer name="arrow"  url="arrov.png"  align="center"  edge="top" scale="0.5"   /> 
 
<hotspot  name="target1"  url="pit.png"  ath="20" atv="-20" ondown="set(target, get(name)); arrow_rotate(get(target));" />				  
	
<events onviewchange="arrow_rotate(get(target))" keep="true" />

<action name="arrow_rotate" scope="local" args="target"> 
	calc(phi_1,global.view.vlookat * ( Math.PI / 180 ) ); 					
	calc(phi_2, global.hotspot[get(target)].atv * ( Math.PI / 180 ));		
	calc(delta_lambda, (global.hotspot[get(target)].ath - global.view.hlookat) * ( Math.PI / 180 ));
	Math.cos(cos1,get(phi_1));  
	Math.sin(sin,get(phi_2));
	Math.sin(sin2,get(phi_1));
	Math.cos(cos2,get(phi_2));
	Math.cos(cos3,get(delta_lambda));
	Math.sin(sin3,get(delta_lambda));
	calc(x, cos1 * sin - sin2 * cos2 * cos3 );  								
	calc(y, sin3 * cos2); 
	Math.atan2(theta,y, x);													
	calc(bearing, -1 * theta * (180/Math.PI) + 180);  						
	if(bearing,
		set(global.layer[arrow].rotate, get(bearing));
	);
</action>

9

Donnerstag, 3. Februar 2022, 10:28

Didnt work!

Hello San7! How I make work your code, I tried but nothing, there is something special on the hotspots code?

Regards,
Laura.
Test it