diff --git a/config/regular.yaml b/config/regular.yaml index 41b3f10..feb94bc 100644 --- a/config/regular.yaml +++ b/config/regular.yaml @@ -1,3 +1,5 @@ +anchor: + angle: -5 columns: - name: pinky rotate: 5 @@ -18,7 +20,7 @@ thumbfan: - name: palmward anchor: ref: inner_bottom - shift: [-12, -19] + shift: [-7, -19] column: ring padding: 21.25 rotate: 28 diff --git a/helpers/points.js b/helpers/points.js index cffc27b..e8cc15c 100644 --- a/helpers/points.js +++ b/helpers/points.js @@ -6,157 +6,285 @@ const fs = require('fs-extra') // TODO: refactor this to use the new config format -const column = (func, col) => ({ - models: { - bottom: up(func(col, 'bottom'), 0 * (side + padding)), - middle: up(func(col, 'middle'), 1 * (side + padding)), - top: up(func(col, 'top'), 2 * (side + padding)) - } -}) +// const column = (func, col) => ({ +// models: { +// bottom: up(func(col, 'bottom'), 0 * (side + padding)), +// middle: up(func(col, 'middle'), 1 * (side + padding)), +// top: up(func(col, 'top'), 2 * (side + padding)) +// } +// }) -const matrix = (func) => { - const models = {} - let i = 0 - let sum = 0 - for (const {name, shift} of columns) { - let col = column(func, name) - sum += shift - if (name == 'pinky') { - col = rotate(col, pinky_angle, [side, 0]) - } - col = up(col, sum) - col = right(col, i * (side + padding)) - models[name] = col - i++ +// const matrix = (func) => { +// const models = {} +// let i = 0 +// let sum = 0 +// for (const {name, shift} of columns) { +// let col = column(func, name) +// sum += shift +// if (name == 'pinky') { +// col = rotate(col, pinky_angle, [side, 0]) +// } +// col = up(col, sum) +// col = right(col, i * (side + padding)) +// models[name] = col +// i++ +// } +// return {models} +// } + +// const thumbfan = (func) => ({ +// models: { +// inner: func('thumb', 'inner'), +// home: rotate( +// right( +// func('thumb', 'home'), +// side + padding + kc_diff +// ), +// thumb_angle, +// [side + padding / 2, -overhang] +// ), +// outer: rotate( +// right( +// rotate( +// right( +// func('thumb', 'outer'), +// side + padding + kc_diff +// ), +// thumb_angle, +// [side + padding / 2 + kc_diff, -overhang] +// ), +// side + padding + kc_diff +// ), +// thumb_angle, +// [side + padding / 2, -overhang] +// ) +// } +// }) + +// const half = (func) => { +// const result = { +// models: { +// matrix: matrix(func), +// thumbfan: move( +// thumbfan(func), +// [ +// 3 * (side + padding) + thumb_start, +// -(side + padding) + staggers_sum +// ] +// ) +// } +// } +// return m.model.rotate(result, half_angle) +// } + + +// TODO temp +let _debug_key = 0 +const _debug = {} +const debug = (xy) => { + _debug[_debug_key++] = { + type: 'circle', + origin: [xy[0], xy[1]], + radius: 1 } - return {models} } -const thumbfan = (func) => ({ - models: { - inner: func('thumb', 'inner'), - home: rotate( - right( - func('thumb', 'home'), - side + padding + kc_diff - ), - thumb_angle, - [side + padding / 2, -overhang] - ), - outer: rotate( - right( - rotate( - right( - func('thumb', 'outer'), - side + padding + kc_diff - ), - thumb_angle, - [side + padding / 2 + kc_diff, -overhang] - ), - side + padding + kc_diff - ), - thumb_angle, - [side + padding / 2, -overhang] - ) - } -}) - -const half = (func) => { - const result = { - models: { - matrix: matrix(func), - thumbfan: move( - thumbfan(func), - [ - 3 * (side + padding) + thumb_start, - -(side + padding) + staggers_sum - ] - ) - } - } - return m.model.rotate(result, half_angle) -} - - - - - -const dump = (points) => { +const dump = exports.dump = (points, opts={}) => { const line = (a, b) => ({ type: 'line', origin: a, end: b }) + const s = (opts.side || 14) / 2 const models = {} for (const [key, point] of Object.entries(points)) { - const s = 7 const paths = { l: line([-s, -s], [-s, s]), t: line([-s, s], [ s, s]), r: line([ s, s], [ s, -s]), b: line([ s, -s], [-s, -s]) } - models[key] = m.model.moveRelative(m.model.rotate({paths}, point.r), point.xy) + models[key] = m.model.moveRelative(m.model.rotate({paths}, point.r), point.p) } + // TODO + models['debug'] = {paths: _debug} + const assembly = m.model.originate({ models, units: 'mm' }) - fs.writeFileSync(`dump.dxf`, m.exporter.toDXF(assembly)) + fs.writeFileSync(`${opts.file || 'dump'}.dxf`, m.exporter.toDXF(assembly)) } + + +const Point = exports.Point = class Point { + constructor(x, y, r, col={}, row={}) { + this.x = x + this.y = y + this.r = r + this.col = col + this.row = row + } + + get p() { + return [this.x, this.y] + } + + set p(val) { + [this.x, this.y] = val + } +} + + +const push_rotation = (list, angle, origin) => { + let candidate = origin + for (const r of list) { + candidate = m.point.rotate(candidate, r.angle, r.origin) + } + list.push({ + angle: angle, + origin: candidate + }) +} + + +const matrix = (cols, rows, anchor=new Point(0, 0, 0), reverse=false) => { + + console.log('matrix', cols, rows, anchor, reverse) + + + const sign = reverse ? -1 : 1 + const points = {} + let x = anchor.x + let stagger_sum = anchor.y + let rotation_sum = anchor.r + const rotations = [{ + angle: anchor.r, + origin: [0, 0] + }] + for (const col of cols) { + + + // TODO rotation origin reversal is not this easy + // and probably the whole reversal idea is not even necessary + // sleep on it, and possibly remove to simplify + + + if (reverse) { + x -= col.padding || 19 + if (col.rotate) { + let ox = 0, oy = 0 + if (col.origin) { + ox = -col.origin[0] + oy = col.origin[1] + } + push_rotation( + rotations, + col.rotate, + m.point.add([ox, oy], [x, stagger_sum]) + ) + rotation_sum += col.rotate + } + } + + stagger_sum += sign * col.stagger || 0 + let y = stagger_sum + + + for (const row of (col.rows || rows || [{name: 'default'}])) { + let point = [x, y] + debug(point) + for (const r of rotations) { + point = m.point.rotate(point, r.angle, r.origin) + debug(point) + } + points[col.name + '_' + row.name] = new Point( + point[0], + point[1], + rotation_sum + (row.angle || 0), + col, + row + ) + console.log('new Point', points[col.name + '_' + row.name]) + y += row.padding || 19 + } + + + + + if (!reverse) { + if (col.rotate) { + push_rotation( + rotations, + -col.rotate, + m.point.add(col.origin || [0, 0], [x, stagger_sum]) + ) + + a = rotations.pop() + debug(a.origin) + rotations.push(a) + + rotation_sum += -col.rotate + } + x += col.padding || 19 + } + + + + } + return points +} + + + + + + + + exports.parse = (config) => { - const points = {} - - // matrix - let x = 0 - let stagger_sum = 0 - let rotation_sum = 0 - const rotations = [] - for (const col of config.columns) { - stagger_sum += col.stagger || 0 - let y = stagger_sum - for (const row of (col.rows || config.rows)) { - let point = [x, y] - for (const r of rotations) { - point = m.point.rotate(point, r.angle, r.origin) - } - points[col.name + '_' + row.name] = { - xy: point, - r: rotation_sum - } - y += row.padding || 19 + // basic matrix + let matrix_anchor + if (config.anchor) { + let x = 0 + let y = 0 + if (config.anchor.shift) { + x = config.anchor.shift[0] + y = config.anchor.shift[1] } - if (col.rotate) { - rotations.push({ - angle: -col.rotate, - origin: m.point.add(col.origin || [0, 0], [x, stagger_sum]) - }) - rotation_sum += -col.rotate - } - x += col.padding || 19 + const r = -config.anchor.angle || 0 + matrix_anchor = new Point(x, y, r) } + let points = matrix(config.columns, config.rows, matrix_anchor) // thumbfan - let anchor_index = -1 - let anchor_point = false + let thumb_anchor = new Point(0, 0, 0) + let thumb_anchor_index = -1 for (const key of config.thumbfan) { - if (!anchor_point) { - anchor_index++ - if (key.anchor) { - const ref = points[key.anchor.ref] - anchor_point = m.point.add(ref, key.anchor.shift) - } else continue - } - + thumb_anchor_index++ + if (key.anchor) { + const ref = points[key.anchor.ref] || thumb_anchor + thumb_anchor.p = m.point.add(ref.p, key.anchor.shift) + thumb_anchor.r += key.anchor.angle || 0 + break + } else continue } + const forward = config.thumbfan.slice(thumb_anchor_index) + const rewind = config.thumbfan.slice(0, thumb_anchor_index) + const thumb_rows = config.thumb_rows || [{name: 'thumb'}] + + points = Object.assign(points, matrix(forward, thumb_rows, thumb_anchor)) + points = Object.assign(points, matrix(rewind, thumb_rows, thumb_anchor, true)) + + dump(points) throw 2