Last active
May 15, 2021 17:23
-
-
Save lukem512/a7fe4c16c7fa0c7a6c53cb2d94ead663 to your computer and use it in GitHub Desktop.
Calculator for yurt component dimensions and count. Specify a diameter and a wall height (or use the defaults) and you'll be shown how many poles, and of what lengths, are needed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const defaults = { | |
units: 'ft', // units to use, could be 'ft' or 'm' | |
diameter: 14, // units | |
wallHeight: 6, // units, at outer edge | |
khanaHoleSpacing: 1, // units, spacing between crossing rods | |
roofAngle: 25, // degrees from horizontal | |
tonoDiameter: 1, // units | |
} | |
function deg2rad(deg) { | |
return deg * (Math.PI / 180); | |
} | |
function calculateCircumference({diameter}) { | |
return Math.PI * diameter; | |
} | |
function calculateUniRadius({diameter, tonoDiameter}) { | |
return (diameter - tonoDiameter) / 2; | |
} | |
function calculateUniLength({roofAngle, ...options}) { | |
return calculateUniRadius(options) / Math.cos(deg2rad(roofAngle)); | |
} | |
function calculateRoofHeight({roofAngle, ...options}) { | |
return Math.sin(deg2rad(roofAngle)) * calculateUniLength({roofAngle, ...options}); | |
} | |
function calculateKhanaRodLength({wallHeight}) { | |
// Assuming 45 degrees, length is the hypotenuse | |
// of a right-angled triangle with sides of the desired wall height. | |
return Math.sqrt((wallHeight*wallHeight) * 2); | |
} | |
function calculateKhanaRodCount({khanaHoleSpacing, wallHeight, ...options}) { | |
// A minimal lattice has just two holes - one at either end | |
// Thus, for each length of the khana rod around the circumference, there are 2 rods | |
const wholeRodsInCircumference = calculateCircumference(options) / wallHeight; | |
// A denser (thus stronger) lattice has more holes and one rod per hole. | |
// The rod length divided by the hole spacing gives the number of holes. | |
const holesPerKhanaRod = calculateKhanaRodLength({wallHeight}) / khanaHoleSpacing; | |
return wholeRodsInCircumference * holesPerKhanaRod; | |
} | |
function buildYurt(options = {}) { | |
// Find any missing options and their default values | |
const missingOpts = Object.keys(defaults) | |
.filter(key => !(key in options)) | |
.reduce((obj, key) => { | |
obj[key] = defaults[key]; | |
return obj; | |
}, {}); | |
// Then mutate the options object to include defaults | |
options = Object.assign(options, missingOpts); | |
// Compute some re-usable values | |
const roofHeight = calculateRoofHeight(options); | |
const khanaRodCount = Math.ceil(calculateKhanaRodCount(options)); | |
const uniRodCount = Math.ceil(khanaRodCount / 2); | |
// Build up an object specifying the yurt | |
return { | |
units: options.units, | |
diameter: options.diameter, | |
height: options.wallHeight + roofHeight, | |
roof: { | |
height: roofHeight, | |
angle: options.roofAngle, | |
uni: { | |
length: calculateUniLength(options), | |
count: uniRodCount, | |
}, | |
tono: { | |
diameter: options.tonoDiameter, | |
holeSpacing: options.tonoDiameter / uniRodCount, | |
} | |
}, | |
walls: { | |
circumference: calculateCircumference(options), | |
height: options.wallHeight, | |
khana: { | |
length: calculateKhanaRodLength(options), | |
holeSpacing: options.khanaHoleSpacing, | |
count: khanaRodCount, | |
} | |
} | |
}; | |
} | |
const yurt = buildYurt(); | |
console.log(yurt); | |
console.log(); | |
console.log(`YURT`); | |
console.log(`----`); | |
console.log(); | |
console.log(`Diameter: ${yurt.diameter.toFixed(2)} ${yurt.units}`); | |
console.log(`Height: ${yurt.height.toFixed(2)} ${yurt.units}`); | |
console.log(); | |
console.log(`To build this yurt you will need:`); | |
console.log(); | |
console.log(`- ${yurt.walls.khana.count}x ${yurt.walls.khana.length.toFixed(2)} ${yurt.units} khana (lattice) poles`); | |
console.log(`- ${yurt.roof.uni.count}x ${yurt.roof.uni.length.toFixed(2)} ${yurt.units} uni (roof) poles`); | |
console.log(`- 1x ${yurt.roof.tono.diameter.toFixed(2)} ${yurt.units} diameter tono (crown) with ${yurt.roof.uni.count} holes spaced every ${yurt.roof.tono.holeSpacing.toFixed(2)} ${yurt.units}`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment