1
0

Ergogen reorg

This commit is contained in:
Bán Dénes 2020-06-16 22:24:46 +02:00
parent cd1e10293c
commit 0ab5a246e5
14 changed files with 2289 additions and 309 deletions

117
.gitignore vendored
View File

@ -1,3 +1,116 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
*.dxf
*.json
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

View File

@ -497,4 +497,79 @@ case:
After the camfer to the top and/or bottom outside edges, the object is `translate`d/`rotate`d, and combined with what we have so far according to `op`.
If we only want to use an object as a building block for further objects, we can employ the same "start with an underscore" trick we learned at the outlines section.
## A concrete case example
<br />
## PCB
Everything should be ready for a handwire, but if you'd like the design to be more accessible and easily replicable, you probably want a PCB as well.
To help you get started, the necessary footprints and an edge cut can be automatically positioned so that all you need to do manually is the routing.

View File

@ -1,109 +0,0 @@
zones:
matrix:
anchor:
angle: 5
columns:
- name: pinky
rotate: -5
origin: [7, -7]
rows:
- bind_x:
- bind_x: right
- bind_x: right
- name: ring
stagger: 12
rows:
- bind_x: left
- bind_x: right
- bind_x: right
- name: middle
stagger: 5
rows:
- bind_x: both
- bind_x: both
- bind_x:
- name: index
stagger: -6
rows:
- bind_x: right
- bind_x: left
- bind_x: left
- name: inner
stagger: -2
rows:
- bind_x:
- bind_x: left
- bind_x: left
rows:
- name: bottom
bind_y: up
- name: home
bind_y: up
- name: top
thumbfan:
anchor:
ref: inner_bottom
shift: [-7, -19]
columns:
- name: near
column_wire: ring
padding: 21.25
rotate: -28
origin: [9.5, -9]
rows:
- bind_x: right
- name: home
column_wire: middle
padding: 21.25
rotate: -28
origin: [11.75, -9]
rows:
- bind_x: both
- name: far
column_wire: index
rows:
- bind_x: left
rows:
- name: thumb
bind_y: up
angle: -20
mirror:
ref: pinky_home
# The mk1's origin was the bottom left corner of the bottom pinky key.
# But it later got rotated by the bottom *right* corner as the pinky angle
# and then rotated again for the inter-half angle so [0, 0] was nowhere on
# the actual result.
#
# Since the new origin is the center of the pinky home, we have to convert
# the old, round 250 width to this new coordinate system if we want backward
# compatibility. The following snippet was used to arrive at this distance.
#
# old_origin = new Point(7, 7 + 19)
# old_origin.rotate(5, [14, 0])
# old_origin.rotate(-20, [0, 0])
# new_width = 250 - (2 * old_origin.x)
distance: 223.7529778
outline:
footprint: 18
bind: 10
corner: 0.5
glue:
top:
left:
key: inner_top
line: top
right:
key: mirror_inner_top
line: top
bottom:
left:
key: far_thumb
line: right
right:
key: mirror_far_thumb
line: left
waypoints:
- percent: 50
width: 100
- percent: 90
width: 50

View File

@ -1,72 +0,0 @@
zones:
matrix:
anchor:
angle: 5
columns:
- name: pinky
rotate: -5
origin: [7, -10]
- name: ring
stagger: 12
- name: middle
stagger: 5
- name: index
stagger: -6
padding: 16
- name: inner
stagger: -2
rows:
- name: bottom
padding: 16
- name: home
padding: 16
- name: top
thumbfan:
anchor:
ref: inner_bottom
shift: [-4, -22]
columns:
- name: wrong_near
padding: 21.25
rotate: -28
origin: [9.5, -9]
skip: yes
- name: home
column_wire: middle
rotate: -28
origin: [9.5, -9]
- name: far
column_wire: index
rows:
- name: thumb
thumbfan_reverse_pass:
anchor:
ref: home_thumb
reverse: yes
columns:
- name: home_again
rotate: 28
origin: [-9.5, -9]
skip: yes
- name: near
padding: 16
column_wire: ring
rows:
- name: thumb
angle: -20
mirror:
ref: pinky_home
# The mk1's origin was the bottom left corner of the bottom pinky key.
# But it later got rotated by the bottom *right* corner as the pinky angle
# and then rotated again for the inter-half angle so [0, 0] was nowhere on
# the actual result.
#
# Since the new origin is the center of the pinky home, we have to convert
# the old, round 250 width to this new coordinate system if we want backward
# compatibility. The following snippet was used to arrive at this distance.
#
# old_origin = new Point(7, 7 + 19)
# old_origin.rotate(5, [14, 0])
# old_origin.rotate(-20, [0, 0])
# new_width = 250 - (2 * old_origin.x)
distance: 223.7529778

1962
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,34 @@
{
"name": "absolem",
"version": "1.0.0",
"description": "Flat, minimalistic, ergonomic keyboard layout generated from JS.",
"name": "ergogen",
"version": "0.1.0",
"description": "Ergonomic keyboard layout generator",
"author": "Bán Dénes <mr@zealot.hu>",
"license": "MIT",
"homepage": "https://zealot.hu/ergogen",
"repository": "github:mrzealot/ergogen",
"bugs": "https://github.com/mrzealot/ergogen/issues",
"main": "./src/ergogen.js",
"bin": "./src/cli.js",
"scripts": {
"build": "rollup -c",
"test": "nyc mocha -r chai/register-should"
},
"dependencies": {
"fs-extra": "^9.0.0",
"fs-extra": "^9.0.1",
"js-yaml": "^3.14.0",
"makerjs": "github:mrzealot/maker.js-dist",
"yargs": "^15.3.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^13.0.0",
"chai": "^4.2.0",
"mocha": "^8.0.1",
"nyc": "^15.1.0",
"rollup": "^2.16.1"
},
"nyc": {
"all": true,
"include": ["src/*.js"],
"exclude": ["src/cli.js"]
}
}

16
rollup.config.js Normal file
View File

@ -0,0 +1,16 @@
import commonjs from '@rollup/plugin-commonjs'
export default {
input: 'src/ergogen.js',
external: ['makerjs', 'js-yaml'],
output: {
name: 'ergogen',
file: 'dist/bundle.js',
format: 'umd',
globals: {
'makerjs': 'makerjs',
'js-yaml': 'jsyaml'
}
},
plugins: [commonjs()]
}

View File

@ -3,8 +3,8 @@ const path = require('path')
const yaml = require('js-yaml')
const yargs = require('yargs')
const points_lib = require('./helpers/points')
const outline_lib = require('./helpers/outline')
const points_lib = require('../helpers/points')
const outline_lib = require('./outline')
const args = yargs
.option('config', {
@ -59,3 +59,13 @@ if (args.outline) {
}
console.log('Done.')
// exports.dump_model = (model, file='model', json=false) => {
// const assembly = m.model.originate({
// models: deepcopy(model),
// units: 'mm'
// })
// if (json) fs.writeFileSync(`${file}.json`, JSON.stringify(assembly, null, ' '))
// fs.writeFileSync(`${file}.dxf`, m.exporter.toDXF(assembly))
// }

3
src/ergogen.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
points: require('./points')
}

71
src/point.js Normal file
View File

@ -0,0 +1,71 @@
const m = require('makerjs')
const u = require('./utils')
class Point {
constructor(x=0, y=0, r=0, meta={}) {
if (Array.isArray(x)) {
this.x = x[0]
this.y = x[1]
this.r = 0
this.meta = {}
} else {
this.x = x
this.y = y
this.r = r
this.meta = meta
}
}
get p() {
return [this.x, this.y]
}
set p(val) {
[this.x, this.y] = val
}
add(a) {
const res = this.clone()
res.x += a[0]
res.y += a[1]
return res
}
shift(s) {
this.x += s[0]
this.y += s[1]
return this
}
rotate(angle, origin=[0, 0]) {
this.p = m.point.rotate(this.p, angle, origin)
this.r += angle
return this
}
mirror(x) {
this.x = 2 * x - this.x
this.r = -this.r
return this
}
clone() {
return new Point(
this.x,
this.y,
this.r,
u.deepcopy(this.meta)
)
}
position(model) {
return m.model.moveRelative(m.model.rotate(model, this.r), this.p)
}
rect(size=14) {
let rect = u.rect(size, size, [-size/2, -size/2], this.meta.mirrored)
return this.position(rect)
}
}
module.exports = Point

View File

@ -1,100 +1,6 @@
const m = require('makerjs')
const fs = require('fs-extra')
const u = require('./utils')
const Point = exports.Point = class Point {
constructor(x=0, y=0, r=0, meta={}) {
if (Array.isArray(x)) {
this.x = x[0]
this.y = x[1]
this.r = 0
this.meta = {}
} else {
this.x = x
this.y = y
this.r = r
this.meta = meta
}
}
get p() {
return [this.x, this.y]
}
set p(val) {
[this.x, this.y] = val
}
add(a) {
const res = this.clone()
res.x += a[0]
res.y += a[1]
return res
}
shift(s) {
this.x += s[0]
this.y += s[1]
return this
}
rotate(angle, origin=[0, 0]) {
this.p = m.point.rotate(this.p, angle, origin)
this.r += angle
return this
}
mirror(x) {
this.x = 2 * x - this.x
this.r = -this.r
return this
}
clone() {
return new Point(
this.x,
this.y,
this.r,
u.deepcopy(this.meta)
)
}
rect(size=14) {
let rect = u.rect(size, size, [-size/2, -size/2], this.meta.mirrored)
return m.model.moveRelative(m.model.rotate(rect, this.r), this.p)
}
position(model) {
return m.model.moveRelative(m.model.rotate(model, this.r), this.p)
}
}
const dump = exports.dump = (points, opts={}) => {
const s = (opts.side || 14) / 2
const models = {}
for (const [key, point] of Object.entries(points)) {
const paths = {
l: u.line([-s, -s], [-s, s]),
t: u.line([-s, s], [ s, s]),
r: u.line([ s, s], [ s, -s]),
b: u.line([ s, -s], [-s, -s])
}
models[key] = m.model.moveRelative(m.model.rotate({paths}, point.r), point.p)
}
const assembly = m.model.originate({
models,
units: 'mm'
})
fs.writeFileSync(`${opts.file || 'dump'}_points.json`, JSON.stringify(points, null, ' '))
fs.writeFileSync(`${opts.file || 'dump'}_assembly.json`, JSON.stringify(assembly, null, ' '))
fs.writeFileSync(`${opts.file || 'dump'}.dxf`, m.exporter.toDXF(assembly))
}
const push_rotation = (list, angle, origin) => {
let candidate = origin
for (const r of list) {

View File

@ -1,16 +1,9 @@
const m = require('makerjs')
const fs = require('fs-extra')
const deepcopy = exports.deepcopy = (value) => JSON.parse(JSON.stringify(value))
exports.deepcopy = (value) => JSON.parse(JSON.stringify(value))
exports.dump_model = (model, file='model', json=false) => {
const assembly = m.model.originate({
models: deepcopy(model),
units: 'mm'
})
if (json) fs.writeFileSync(`${file}.json`, JSON.stringify(assembly, null, ' '))
fs.writeFileSync(`${file}.dxf`, m.exporter.toDXF(assembly))
const eq = exports.eq = (a=[], b=[]) => {
return a[0] === b[0] && a[1] === b[1]
}
const line = exports.line = (a, b) => {
@ -29,19 +22,13 @@ exports.rect = (w, h, o=[0, 0], mirrored=false) => {
left: line([0, 0], [0, h])
}
if (mirrored) {
for (const [key, val] of Object.entries(res)) {
const tmp = val.origin
val.origin = val.end
val.end = tmp
for (const segment of Object.values(res)) {
[segment.origin, segment.end] = [segment.end, segment.origin]
}
}
return m.model.move({paths: res}, o)
}
const eq = exports.eq = (a=[], b=[]) => {
return a[0] === b[0] && a[1] === b[1]
}
exports.poly = (arr) => {
let counter = 0
let prev = arr[arr.length - 1]
@ -55,4 +42,3 @@ exports.poly = (arr) => {
}
return res
}

8
test/point.js Normal file
View File

@ -0,0 +1,8 @@
const Point = require('../src/point')
describe('Point', function() {
it('#constructor', function() {
const point = new Point(1, 2, 45)
point.p.should.deep.equal([1, 2])
})
})