IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #461: rotation.pl

File rotation.pl, 3.0 KB (added by Paul Price, 21 years ago)

Demonstration perl code for rotations ICRS --> Galactic, Ecliptic and simple precession

Line 
1#!/usr/bin/env perl
2
3use Math::Trig;
4use strict;
5use warnings;
6
7use constant DEG_IN_RAD => 57.2957795130823;
8
9my $alpha = 76 / DEG_IN_RAD; # RA of input
10my $delta = 12 / DEG_IN_RAD; # Dec of input
11
12my ($alphaP, $deltaP, $phiP);
13
14# Generate quaternion
15my @p;
16$p[0] = cos($alpha) * cos($delta);# x
17$p[1] = sin($alpha) * cos($delta);# y
18$p[2] = sin($delta); # z
19$p[3] = 0; # Rotation = 0
20
21# l2,b2
22#$alphaP = 180 - 192.85948;
23#$deltaP = 90 - 27.12825;
24#$phiP = 90 + 32.93192;
25
26# Ecliptic
27#my $T = (2000.0 - 1900)/100; # Centuries from 1900
28#$alphaP = 270;
29#$deltaP = ((23+27/60+8.26/3600) - 46.845/3600*$T - 0.0059/3600*$T*$T + 0.00181/3600*$T*$T*$T);
30##$deltaP = 23.4392911111;
31#$phiP = 90;
32
33# Precession
34my $T = 2;
35$alphaP = 180 + (0.6406161*$T + 0.0000839*$T*$T + 0.0000050*$T*$T*$T);
36$deltaP = (0.5567530*$T - 0.0001185*$T*$T - 0.0000116*$T*$T*$T);
37$phiP = 180 + (0.6406161*$T + 0.0003041*$T*$T + 0.0000051*$T*$T*$T);
38
39
40# Correct Euler angles to rotation angles
41#$alphaP = (180 - $alphaP) / DEG_IN_RAD;
42#$deltaP = (90 - $deltaP) / DEG_IN_RAD;
43#$phiP = (90 + $phiP) / DEG_IN_RAD;
44
45$alphaP /= DEG_IN_RAD;
46$deltaP /= DEG_IN_RAD;
47$phiP /= DEG_IN_RAD;
48
49# Calculate quaternion for the rotation
50my @r;
51my ($phi, $theta);
52
53# Rotate about the z axis by alpha_p
54$r[0] = 0 * sin($alphaP/2); # x
55$r[1] = 0 * sin($alphaP/2); # y
56$r[2] = 1 * sin($alphaP/2); # z
57$r[3] = cos($alphaP/2); # Rotation
58@p = rotate(\@p, \@r);
59
60$phi = atan2($p[1], $p[0]) * DEG_IN_RAD; # Longitude
61$theta = asin($p[2]) * DEG_IN_RAD; # Latitude
62print "$phi $theta\n";
63
64# Rotate about the y axis by delta_p
65$r[0] = 0 * sin($deltaP/2); # x
66$r[1] = 1 * sin($deltaP/2); # y
67$r[2] = 0 * sin($deltaP/2); # z
68$r[3] = cos($deltaP/2); # Rotation
69@p = rotate(\@p, \@r);
70
71$phi = atan2($p[1], $p[0]) * DEG_IN_RAD; # Longitude
72$theta = asin($p[2]) * DEG_IN_RAD; # Latitude
73print "$phi $theta\n";
74
75# Rotate about the z axis by phi_p
76$r[0] = 0 * sin($phiP/2); # x
77$r[1] = 0 * sin($phiP/2); # y
78$r[2] = 1 * sin($phiP/2); # z
79$r[3] = cos($phiP/2); # Rotation
80@p = rotate(\@p, \@r);
81
82$phi = atan2($p[1], $p[0]) * DEG_IN_RAD; # Longitude
83$theta = asin($p[2]) * DEG_IN_RAD; # Latitude
84print "$phi $theta\n";
85
86
87# Perform a rotation using quaternions
88sub rotate
89{
90 my ($p_ref, $r_ref) = @_;
91 my @p = @$p_ref; # Point to rotate (quaternion)
92 my @r = @$r_ref; # Rotation (quaternion)
93
94 my @rConj = (- $r[0], - $r[1], - $r[2], $r[3]); # Quaternion conjugate
95
96 my @rp = quaternionMultiply(\@r, \@p);
97 my @rprConj = quaternionMultiply(\@rp, \@rConj);
98
99 return @rprConj;
100}
101
102# Multiply two quaternions: pq
103sub quaternionMultiply
104{
105 my ($p_ref, $q_ref) = @_;
106 my @p = @$p_ref;
107 my @q = @$q_ref;
108 my @r;
109
110 print "p: $p[0] $p[1] $p[2] $p[3]\n";
111 print "q: $q[0] $q[1] $q[2] $q[3]\n";
112
113 $r[0] = $q[3]*$p[0] + $q[2]*$p[1] - $q[1]*$p[2] + $q[0]*$p[3];
114 $r[1] = - $q[2]*$p[0] + $q[3]*$p[1] + $q[0]*$p[2] + $q[1]*$p[3];
115 $r[2] = $q[1]*$p[0] - $q[0]*$p[1] + $q[3]*$p[2] + $q[2]*$p[3];
116 $r[3] = - $q[0]*$p[0] - $q[1]*$p[1] - $q[2]*$p[2] + $q[3]*$p[3];
117
118 print "r: $r[0] $r[1] $r[2] $r[3]\n";
119
120 return @r;
121}
122
123__END__