ergogen/src/anchor.js

60 lines
2.2 KiB
JavaScript
Raw Normal View History

2021-01-01 00:50:04 +01:00
const u = require('./utils')
const a = require('./assert')
const Point = require('./point')
const anchor = module.exports = (raw, name, points={}, check_unexpected=true, default_point=new Point()) => units => {
2021-01-01 21:46:01 +01:00
if (a.type(raw)() == 'array') {
2021-01-01 00:50:04 +01:00
// recursive call with incremental default_point mods, according to `affect`s
2021-05-22 17:58:26 +02:00
let current = default_point.clone()
2021-01-01 00:50:04 +01:00
for (const step of raw) {
2021-05-22 17:58:26 +02:00
current = anchor(step, name, points, check_unexpected, current)(units)
2021-01-01 00:50:04 +01:00
}
return current
}
2021-05-22 19:06:57 +02:00
if (check_unexpected) a.unexpected(raw, name, ['ref', 'orient', 'shift', 'rotate', 'affect'])
2021-01-01 00:50:04 +01:00
let point = default_point.clone()
if (raw.ref !== undefined) {
2021-01-01 21:46:01 +01:00
if (a.type(raw.ref)() == 'array') {
2021-01-01 00:50:04 +01:00
// averaging multiple anchors
let x = 0, y = 0, r = 0
const len = raw.ref.length
for (const ref of raw.ref) {
a.assert(points[ref], `Unknown point reference "${ref}" in anchor "${name}"!`)
const resolved = points[ref]
x += resolved.x
y += resolved.y
r += resolved.r
}
point = new Point(x / len, y / len, r / len)
} else {
a.assert(points[raw.ref], `Unknown point reference "${raw.ref}" in anchor "${name}"!`)
point = points[raw.ref].clone()
}
}
if (raw.orient !== undefined) {
2021-05-22 17:58:26 +02:00
point.r += a.sane(raw.orient, `${name}.orient`, 'number')(units)
2021-01-01 00:50:04 +01:00
}
if (raw.shift !== undefined) {
2021-05-22 17:58:26 +02:00
let xyval = a.wh(raw.shift, `${name}.shift`)(units)
2021-01-01 00:50:04 +01:00
if (point.meta.mirrored) {
xyval[0] = -xyval[0]
}
point.shift(xyval, true)
}
if (raw.rotate !== undefined) {
2021-05-22 17:58:26 +02:00
point.r += a.sane(raw.rotate, `${name}.rotate`, 'number')(units)
2021-01-01 00:50:04 +01:00
}
if (raw.affect !== undefined) {
const candidate = point
point = default_point.clone()
2021-05-22 17:58:26 +02:00
let affect = raw.affect
2021-01-01 21:46:01 +01:00
if (a.type(affect)() == 'string') affect = affect.split('')
2021-01-01 00:50:04 +01:00
affect = a.strarr(affect, `${name}.affect`)
let i = 0
2021-05-22 17:58:26 +02:00
for (const aff of affect) {
a.in(aff, `${name}.affect[${++i}]`, ['x', 'y', 'r'])
point[aff] = candidate[aff]
2021-01-01 00:50:04 +01:00
}
}
return point
}