Skip to content

Instantly share code, notes, and snippets.

@t1u1
Created February 9, 2022 13:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t1u1/6d5a1c6f6494f61394ca7735a53aad78 to your computer and use it in GitHub Desktop.
Save t1u1/6d5a1c6f6494f61394ca7735a53aad78 to your computer and use it in GitHub Desktop.
More glitches
const jscad = require('@jscad/modeling')
const { union } = jscad.booleans
const { extrudeLinear } = jscad.extrusions
const { hullChain } = jscad.hulls
const { circle } = jscad.primitives
const { vectorText } = jscad.text
const { translate } = jscad.transforms
// Build text by creating the font strokes (2D), then extruding up (3D).
const text = (message, extrusionHeight, characterLineWidth, segments) => {
const lineRadius = characterLineWidth / 2
const lineCorner = circle({ radius: lineRadius, segments: segments })
const lineSegmentPointArrays = vectorText({ x: 0, y: 0, input: message }) // line segments for each character
const lineSegments = []
lineSegmentPointArrays.forEach((segmentPoints) => { // process the line segment
const corners = segmentPoints.map((point) => translate(point, lineCorner))
lineSegments.push(hullChain(corners))
})
const message2D = union(lineSegments)
repairGeom2(message2D)
const message3D = extrudeLinear({ height: extrusionHeight }, message2D)
return message3D;
}
/**
* Mend gaps in a 2D geometry to make it a closed polygon
*/
const repairGeom2 = (geometry) => {
const vertexMap = {} // string key to vertex map
const edgeCount = {} // count of (in - out) edges
geometry.sides.forEach((edge) => {
const inKey = edge[0].toString()
const outKey = edge[1].toString()
vertexMap[inKey] = edge[0]
vertexMap[outKey] = edge[1]
edgeCount[inKey] = (edgeCount[inKey] || 0) + 1 // in
edgeCount[outKey] = (edgeCount[outKey] || 0) - 1 // out
})
// find vertices which are missing in or out edges
const missingIn = Object.keys(edgeCount).filter((e) => edgeCount[e] < 0)
const missingOut = Object.keys(edgeCount).filter((e) => edgeCount[e] > 0)
// pairwise distance of bad vertices
missingIn.forEach((key1) => {
const v1 = vertexMap[key1]
// find the closest vertex that is missing an out edge
let bestDistance = Infinity
let bestReplacement = undefined
missingOut.forEach((key2) => {
const v2 = vertexMap[key2]
const distance = Math.hypot(v1[0] - v2[0], v1[1] - v2[1])
if (distance < bestDistance) {
bestDistance = distance
bestReplacement = v2
}
})
console.log(`Repair gap ${v1} → ${bestReplacement} dist ${bestDistance}`)
// merge broken vertices
geometry.sides.forEach((edge) => {
if (edge[0].toString() === key1) edge[0] = bestReplacement
if (edge[1].toString() === key1) edge[1] = bestReplacement
})
})
return geometry
}
const main = (params) => {
let objs = [];
objs.push(text("4", 2, 1, 26))
objs.push(translate([-40,0,0], text("B", 2, 2, 27)))
objs.push(translate([-80,0,0], text("R", 2, 2, 27)))
objs.push(translate([-40,-40,0], text("L", 2, 1, 21)))
return objs;
}
module.exports = { main }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment