Published unlisted
Edited
Jan 19, 2020
Importers
1 star
Insert cell
Insert cell
J2000 = [
[-0.054876, -0.873437, -0.483835],
[0.494109, -0.444830, 0.746982],
[-0.867666, -0.198076, 0.455984]
]
Insert cell
j2000_e = EulerAnglesFromRotationMatrix(J2000) // equatorial to galactic
Insert cell
j2000_ei = EulerAnglesFromRotationMatrix(d3.transpose(J2000)) // galactic to equatorial
Insert cell
J1950 = [
[-0.066989, -0.872756, -0.483539],
[0.492728, -0.450347, 0.744585],
[-0.867601, -0.188375, 0.460200]
]
Insert cell
j1950_e = EulerAnglesFromRotationMatrix(J1950)
Insert cell
j1950_ei = EulerAnglesFromRotationMatrix(d3.transpose(J1950))
Insert cell
// https://www.astro.rug.nl/software/kapteyn-beta/celestialbackground.html
galactic2super = [
[-7.357425748044e-01, 6.772612964139e-01, -6.085819597056e-17],
[-7.455377836523e-02, -8.099147130698e-02, 9.939225903998e-01],
[6.731453021092e-01, 7.312711658170e-01, 1.100812622248e-01]
]
Insert cell
supergalactic = matrix_multiply(galactic2super,J2000)
Insert cell
supergalactic_ei = EulerAnglesFromRotationMatrix(
// mlMatrix.inverse(supergalactic)
// the inverse of a rotation matrix is its transpose
// (transpose is faster and more accurate)
d3.transpose(supergalactic)
)
Insert cell
// https://www.gregslabaugh.net/publications/euler.pdf
function EulerAnglesFromRotationMatrix(R) {
const theta = asin(R[2][0]),
ooct = 1 / cos(theta),
psi = atan2(R[2][1] * ooct, R[2][2] * ooct),
phi = atan2(R[1][0] * ooct, R[0][0] * ooct);
return [phi, theta, psi].map(d => -d * (180 / Math.PI));
}
Insert cell
d3.geoRotation(j2000_ei).invert([0, 90]) // 12 days 49 minutes RA, Dec = 27°24′ = [192.25, 27.4] // [-167.75, 27.4]
Insert cell
Insert cell
// Axis-angle representation of a rotation given as Euler angles
// https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Recovering_the_axis-angle_representation
// https://www.astro.rug.nl/software/kapteyn-beta/_downloads/attitude.pdf
function AxisAngleFromEulerAngles(rotate) {
// the vector part of the quaternion (q1:3) should give the cartesian coordinates of the pole
const q = versor(rotate),
h0 = Math.hypot(q[1], q[2], q[3]),
r0 = 1 / h0;
// see [z, -y, x] https://github.com/Fil/versor/blob/master/src/index.js#L14
const axis = spherical([q[3], -q[2], q[1]].map(d => d * r0)).map(
d => d * degrees
);
const angle = 2 * atan2(h0, q[0]) * degrees;
return { axis, angle };
}
Insert cell
AxisAngleFromEulerAngles([360.1, 0, 0]) // [0, 90] // lambda
Insert cell
AxisAngleFromEulerAngles([0, 1, 0]) // [-90, 0] // phi
Insert cell
AxisAngleFromEulerAngles([0, 0, 1]) // [0, 0] // gamma
Insert cell
AxisAngleFromEulerAngles([0, 90, 0])
Insert cell
AxisAngleFromEulerAngles([0, 90, 0])
Insert cell
AxisAngleFromEulerAngles(j2000_ei)
Insert cell
(12 + 49 / 60) * (360 / 24)
Insert cell
27 + 24 / 60
Insert cell
versor = require("versor@0.1")
Insert cell
import { spherical } from "@fil/cartesian"
Insert cell
import { asin, atan2, cos, degrees } from "@fil/math"
Insert cell
matrix_multiply = (A, B) => {
function dot(v, w) {
return v.map((a, i) => a * w[i]).reduce((a, b) => a + b, 0);
}

const M = Array(A.length),
Bt = d3.transpose(B);
for (let i = 0; i < A.length; i++) {
const line = Array(Bt.length);
for (let j = 0; j < Bt.length; j++) {
line[j] = dot(A[i], Bt[j]);
}
M[i] = line;
}
return M;
}
Insert cell
matrix_multiply(J1950, d3.transpose(J2000))
Insert cell
d3 = require("d3@5")
Insert cell
versor([181, 0, 0])
Insert cell
attitude = require("attitude")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more