164 lines
3 KiB
TypeScript
164 lines
3 KiB
TypeScript
import { Plot } from '../plot/mod.ts'
|
|
import { range } from '../utils/list.ts'
|
|
|
|
const distance = 200 //cm
|
|
const size = 264 //cm
|
|
const gap = 2.6 //cm
|
|
const radius = 1 //cm
|
|
|
|
const markerSize = 2 * radius * 4 //4: px aspect factor
|
|
|
|
function getPoints() {
|
|
const plot = {
|
|
x: [] as number[],
|
|
y: [] as number[],
|
|
mode: 'markers',
|
|
name: 'references',
|
|
marker: { size: markerSize },
|
|
}
|
|
|
|
const step = 20 * gap
|
|
for (const x of range(0, size + 1, step)) {
|
|
for (const y of range(0, size + 1, step)) {
|
|
plot.x.push(x)
|
|
plot.y.push(y)
|
|
}
|
|
}
|
|
|
|
return plot
|
|
}
|
|
|
|
function computePointsActual() {
|
|
const plot = {
|
|
x: [] as number[],
|
|
y: [] as number[],
|
|
mode: 'markers',
|
|
name: 'actual',
|
|
marker: { size: markerSize },
|
|
opacity: 0.5,
|
|
}
|
|
|
|
const step = 20 * gap
|
|
for (const y of range(0, size + 1, step)) {
|
|
for (const z of range(0, 2 * size + 1, step)) {
|
|
//Spheric coordinates
|
|
const x = distance
|
|
const rho = Math.hypot(x, y, z)
|
|
const phi = Math.atan(y / x)
|
|
const theta = Math.asin(z / rho)
|
|
|
|
//Cartesian coordinates
|
|
const x1 = Math.tan(phi) * distance
|
|
const y1 = Math.tan(theta) * distance
|
|
|
|
plot.x.push(x1)
|
|
plot.y.push(y1)
|
|
}
|
|
}
|
|
|
|
return plot
|
|
}
|
|
|
|
function computePointsActualFixedFormula() {
|
|
const plot = {
|
|
x: [] as number[],
|
|
y: [] as number[],
|
|
mode: 'markers',
|
|
name: 'actual fixed formula',
|
|
marker: { size: markerSize },
|
|
opacity: 0.5,
|
|
}
|
|
|
|
const step = 20 * gap
|
|
for (const y of range(0, size + 1, step)) {
|
|
for (const z of range(0, 2 * size + 1, step)) {
|
|
//Spheric coordinates
|
|
const x = distance
|
|
const rho = Math.hypot(x, y, z)
|
|
const phi = Math.atan(y / x)
|
|
const theta = Math.acos(z / rho)
|
|
|
|
//Cartesian coordinates
|
|
const x1 = Math.tan(phi) * distance
|
|
const y1 = Math.tan(theta) * distance
|
|
|
|
plot.x.push(x1)
|
|
plot.y.push(y1)
|
|
}
|
|
}
|
|
|
|
return plot
|
|
}
|
|
|
|
function computePointsFixed() {
|
|
const plot = {
|
|
x: [] as number[],
|
|
y: [] as number[],
|
|
mode: 'markers',
|
|
name: 'fixed',
|
|
marker: { size: markerSize },
|
|
opacity: 0.5,
|
|
}
|
|
|
|
const step = 20 * gap
|
|
for (const x of range(0, size + 1, step)) {
|
|
for (const y of range(0, size + 1, step)) {
|
|
//Projected coordinates
|
|
const phi = Math.atan(x / distance)
|
|
const theta = Math.atan(y / distance)
|
|
|
|
//Cartesian coordinates
|
|
const x1 = Math.tan(phi) * distance
|
|
const y1 = Math.tan(theta) * distance
|
|
|
|
plot.x.push(x1)
|
|
plot.y.push(y1)
|
|
}
|
|
}
|
|
|
|
return plot
|
|
}
|
|
|
|
function getHoles() {
|
|
const plot = {
|
|
x: [] as number[],
|
|
y: [] as number[],
|
|
mode: 'markers',
|
|
marker: {
|
|
size: markerSize,
|
|
color: 'rgba(0, 0, 0, 0)',
|
|
line: {
|
|
color: 'rgba(0, 0, 0, 1)',
|
|
width: 1,
|
|
},
|
|
},
|
|
opacity: 0.3,
|
|
name: 'holes',
|
|
}
|
|
|
|
let shift = false
|
|
|
|
for (const x of range(0, size, gap)) {
|
|
for (const y of range(0, size, gap)) {
|
|
plot.x.push(shift ? x + gap / 2 : x)
|
|
plot.y.push(y)
|
|
shift = !shift
|
|
}
|
|
}
|
|
|
|
return plot
|
|
}
|
|
|
|
const plot = new Plot()
|
|
|
|
plot.plot([
|
|
getPoints(),
|
|
getHoles(),
|
|
computePointsActual(),
|
|
computePointsActualFixedFormula(),
|
|
computePointsFixed(),
|
|
], {
|
|
xaxis: { range: [-10, size + 10] },
|
|
yaxis: { range: [-10, size + 10] },
|
|
})
|