-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.ts
114 lines (94 loc) · 3.24 KB
/
main.ts
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import * as healpix from '../../../../src'
import { SimpleCanvas } from "./simple_canvas"
const PI = Math.PI
const nside = 64
const radius = Math.PI / 8
window.addEventListener('load', e => {
const gridCanvas = new SimpleCanvas(
setupCanvas(document.getElementById('grid') as HTMLCanvasElement),
-PI, PI, PI, 0, 0.05,
)
const overlayCanvas = new SimpleCanvas(
setupCanvas(document.getElementById('overlay') as HTMLCanvasElement),
-PI, PI, PI, 0, 0.05,
)
drawGrid(gridCanvas, nside)
overlayCanvas.onmousemove((phi, theta) => {
phi = (phi + 2 * PI) % (2 * PI)
overlayCanvas.clear()
const v = healpix.ang2vec(theta, phi)
healpix.query_disc_inclusive_nest(nside, v, radius, ipix => {
fillPixel(overlayCanvas, nside, ipix)
})
})
})
function drawGrid(canvas: SimpleCanvas, nside: number) {
const npix = healpix.nside2npix(nside)
const ctx = canvas.ctx
ctx.strokeStyle = 'rgba(0, 0, 127, 0.25)'
for (let ipix = 0; ipix < npix; ++ipix) {
ctx.beginPath()
pixelPath(canvas, nside, ipix)
canvas.ctx.closePath()
ctx.stroke()
}
}
function fillPixel(canvas: SimpleCanvas, nside: number, ipix: number) {
const ctx = canvas.ctx
ctx.beginPath()
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'
pixelPath(canvas, nside, ipix, 8)
ctx.fill()
}
function pixelPath(canvas: SimpleCanvas, nside: number, ipix: number, nstep = 4) {
const v0 = healpix.pixcoord2vec_nest(nside, ipix, 0, 0)
const phi0 = Math.atan2(v0[1], v0[0])
const lineTo = (x: number, y: number) => {
const [x1, y1] = canvas.world2screen(x, y)
canvas.ctx.lineTo(x1, y1)
}
function clip(x: number, a: number, b: number) {
return x < a ? a : (x > b ? b : x)
}
function safe(x: number) {
return clip(x, 1.e-9, 1 - 1.e-9)
}
for (let i = 0; i < nstep; ++i) {
const ne = i / nstep
const [x, y, z] = rotateZ(healpix.pixcoord2vec_nest(nside, ipix, safe(ne), safe(0)), v0)
const phi = Math.atan2(y, x) + phi0
lineTo(phi, Math.acos(z))
}
for (let i = 0; i < nstep; ++i) {
const nw = i / nstep
const [x, y, z] = rotateZ(healpix.pixcoord2vec_nest(nside, ipix, safe(1), safe(nw)), v0)
const phi = Math.atan2(y, x) + phi0
lineTo(phi, Math.acos(z))
}
for (let i = 0; i < nstep; ++i) {
const ne = 1 - i / nstep
const [x, y, z] = rotateZ(healpix.pixcoord2vec_nest(nside, ipix, safe(ne), safe(1)), v0)
const phi = Math.atan2(y, x) + phi0
lineTo(phi, Math.acos(z))
}
for (let i = 0; i < nstep; ++i) {
const nw = 1 - i / nstep
const [x, y, z] = rotateZ(healpix.pixcoord2vec_nest(nside, ipix, safe(0), safe(nw)), v0)
const phi = Math.atan2(y, x) + phi0
lineTo(phi, Math.acos(z))
}
}
type V3 = [number, number, number]
function rotateZ([x, y, z]: V3, [x0, y0, z0]: V3): V3 {
return [
x * x0 + y * y0,
y * x0 - x * y0,
z,
]
}
function setupCanvas(canvas: HTMLCanvasElement) {
const { width, height } = canvas.getBoundingClientRect()
canvas.width = width * devicePixelRatio
canvas.height = height * devicePixelRatio
return canvas
}