viewpoint = {
let v1 = math.column(eigen_basis, 1);
let v2 = math.column(eigen_basis, 2);
let u = normalize(math.cross(v1, v2).toArray().flat());
let look = normalize(u.flat());
let right = normalize(cross(look, [0, 0, 1]));
let up = cross(right, look);
let M = new mlm.Matrix([right, up, look.map((x) => -x)]).transpose();
let eig = new mlm.EigenvalueDecomposition(M);
let tolerance = 10 ** -8;
let b1 = eig.realEigenvalues.map((e) => Math.abs(e - 1) < tolerance);
let b2 = eig.imaginaryEigenvalues.map((e) => Math.abs(e) < tolerance);
let one_position = (b1 && b2).indexOf(true);
let v = eig.eigenvectorMatrix.transpose().to2DArray()[one_position];
let rot_position = eig.imaginaryEigenvalues
.map((y) => y > 10 ** -8)
.indexOf(true);
let rot = Math.atan2(
eig.imaginaryEigenvalues[rot_position],
eig.realEigenvalues[rot_position]
);
v.push(rot);
return {
position: math
.column(
u.map((x) => [-4 * x]),
0
)
.flat(),
orientation: v
};
}