function plus(A, B) { return [A[0] + B[0], A[1] + B[1], A[2] + B[2]]; } function minus(A, B) { return [A[0] - B[0], A[1] - B[1], A[2] - B[2]]; } function times(A, s) { return [A[0] * s, A[1] * s, A[2] * s]; } function divid(A, s) { return [A[0] / s, A[1] / s, A[2] / s]; } function norm(A) { return Math.sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]); } function dirVec(A, B) { return divid(minus(B, A), norm(minus(B, A))); } function dot(A, B) { return A[0] * B[0] + A[1] * B[1] + A[2] * B[2]; } function project(A, B, d) { var n = dirVec(A, B); var l = dot(n, [0.0, 0.0, -1.0]); var C = times(n, d / l); return [C[0], C[1]]; } function PoincareProjection(A) { return project(A, [0.0, 0.0, -1.0], 1.0); } function KleinProjection(A) { return project(A, [0.0, 0.0, 0.0], 1.0); } function geodesic(A, U, t) { let term1 = times(A, Math.cosh(t)); let term2 = times(U, Math.sinh(t)); return plus(term1, term2); } function calcPoint(x, y) { return [x, y, Math.sqrt(x * x + y * y + 1.0)]; } function inner(A, B) { return +A[0] * B[0] + A[1] * B[1] - A[2] * B[2]; } function calcGeodesic(A, B) { var c = Math.abs(inner(A, B)); //console.log(c); var a = minus(B, times(A, c)); //console.log(a); var U = divid(a, Math.sqrt(c * c - 1)); return { A: A, U: U, t: [0, Math.acosh(c)] }; } function wedge(A, B) { var A_ = Vec2Wedge(A); var B_ = Vec2Wedge(B); var t = MatrixPlus( matrixMul(A_, B_), matrixMulScalar(matrixMul(B_, A_), -1.0) ); return Wedge2Vec(matrixMulScalar(t, 0.5)); } e1 = [ [1.0, 0.0], [0.0, -1.0], ]; e2 = [ [0.0, 1.0], [1.0, 0.0], ]; e3 = [ [0.0, 1.0], [-1.0, 0.0], ]; function matrixMul(A, B) { var C = []; for (let i = 0; i < 2; i++) { var row = []; for (let j = 0; j < 2; j++) { row.push(A[i][0] * B[0][j] + A[i][1] * B[1][j]); } C.push(row); } //console.log(C); return C; } function matrixMulScalar(A, s) { return [ [A[0][0] * s, A[0][1] * s], [A[1][0] * s, A[1][1] * s], ]; } function MatrixPlus(A, B) { return [ [A[0][0] + B[0][0], A[0][1] + B[0][1]], [A[1][0] + B[1][0], A[1][1] + B[1][1]], ]; } function Vec2Wedge(A) { return MatrixPlus( MatrixPlus(matrixMulScalar(e1, A[0]), matrixMulScalar(e2, A[1])), matrixMulScalar(e3, A[2]) ); } function trace(A) { return A[0][0] + A[1][1]; } function WedgeScalar(A, B) { return trace(matrixMul(A, B)) / -2.0; } function Wedge2Vec(A) { //console.log(A); var c0 = -WedgeScalar(A, e1); var c1 = -WedgeScalar(A, e2); var c2 = WedgeScalar(A, e3); //console.log(c0); return [c0, c1, c2]; } function calcU(A, U, beta) { var t1 = times(U, Math.cos(beta)); var t2 = wedge(U, A); var t3 = times(t2, Math.sin(beta)); return times(plus(t1, t3), -1.0); } function calcTang(A0, U0, A1) { var N = wedge(U0, A0); return wedge(A1, N); }