Skip to content

Instantly share code, notes, and snippets.

@Hermann-SW
Last active September 21, 2024 22:51
Show Gist options
  • Save Hermann-SW/89c71c881506cc76db191f47d5d65d16 to your computer and use it in GitHub Desktop.
Save Hermann-SW/89c71c881506cc76db191f47d5d65d16 to your computer and use it in GitHub Desktop.
Last line black edge() should be between lowest two vertices and not at z=0 plane ?!?!?
"use strict"
const jscad = require('@jscad/modeling')
const { intersect, subtract, union } = jscad.booleans
const { colorize } = jscad.colors
const { plane, vec3 } = jscad.maths
const { cube, sphere, cylinder } = jscad.primitives
const { rotate, translate } = jscad.transforms
const sc = 18
const er = sc/200
const N = [0,0,sc]
const p = [2,16,8]
const q = [12,12,6]
function _() { return vec3.create() }
function ang(x,y,d) { return (vec3.dot(y, d) < 0 ? -1 : 1) * vec3.angle(x, d) }
function map3D(x, y) {
const a = Math.atan2(y, x)
const L = sca*vec2.length([x, y])
const X = L -L*(L*L/(4+L*L))
const Y = 2*(L*L/(4+L*L))- 1
return [sc * Math.cos(a) * X, sc * Math.sin(a) * X, sc * Y]
}
function cart2pol(p, f=sc) {
return [Math.atan2(p[1],p[0]), Math.acos(p[2]/f)]
}
let cachedSphere = sphere({radius:3*er})
function vertex(_v, plan=false) {
const v = plan ? _v : map3D(coords[_v][0],coords[_v][1])
const s = translate(v, cachedSphere)
return colorize([0, 0.7, 0], s)
}
let edgeCylinder = cylinder({radius:er, height:1})
function edge(_v, _w, plan=false) {
var v
var w
if (plan) {
v = _v
w = _w
} else {
v = map3D(coords[_v][0], coords[_v][1])
w = map3D(coords[_w][0], coords[_w][1])
}
var d = [0, 0, 0]
var x = [0, 0, 0]
jscad.maths.vec3.subtract(d, w, v)
vec3.add(x, v, w)
vec3.scale(x, x, 0.5)
return colorize([0, 0, 1, 1],
translate(x,
rotate([0, Math.acos(d[2]/vec3.length(d)), Math.atan2(d[1], d[0])],
jscad.transforms.scale([1, 1, vec3.length(d)], edgeCylinder)
)
)
)
}
function edge3(_p1, _p2) {
const v = _p1
const w = _p2
const pla = plane.fromPoints(plane.create(), N, v, w)
const c = vec3.scale(_(), pla, pla[3])
if (pla[3] == 0) {
return edge2(_p1, _p2)
}
const p = cart2pol(c, Math.abs(pla[3]))
const vmc = vec3.subtract(_(), v, c)
const wmc = vec3.subtract(_(), w, c)
const r = vec3.length(vmc)
const x = vec3.rotateZ(_(), vec3.rotateY(_(), [1,0,0], [0,0,0], p[1]), [0,0,0], p[0])
const y = vec3.rotateZ(_(), vec3.rotateY(_(), [0,1,0], [0,0,0], p[1]), [0,0,0], p[0])
return [
translate(c,
rotate([0,p[1],p[0]],
rotate([0,0,ang(x,y,vmc)],
makeArc2(r, ang(x,y,wmc)-ang(x,y,vmc), 64)
)
)
)
]
}
// cool "makeArc2()" replaces "extrudeRotate()", from [email protected]
//
let cachedCylinder = rotate([-Math.PI/2,0,0],cylinder({radius:er, height:1, center:[0,0,0.5]}))
function makeArc2(radius, angle, segments=64) {
let correction = 0
if(angle < 0){
correction = angle
angle *= -1
}
// match how jscad calculates segments
let stepA = Math.PI/(segments)*2
let steps = Math.ceil(angle / stepA)
stepA = angle / steps
let offset = 0, next=0
let out = []
while(offset < angle){
next += stepA
if(next > angle) next=angle
let len = (next-offset) * radius
let x = Math.cos(offset) * radius
let y = Math.sin(offset) * radius
let part = colorize([0,0,1],translate([x,y,0],rotate([0,0,(next-(next-offset)/2)],
jscad.transforms.scale([1,len,1], cachedCylinder)
)))
out.push( correction ? rotate([0,0,correction], part):part)
offset = next
}
if(!out.length) { throw("makeArc2(",radius,",",angle,",",segments,") problem") }
return out
}
function main() {
const pla = plane.fromPoints(plane.create(), N, p, q)
const c = vec3.scale(_(), pla, pla[3])
const pol = cart2pol(c, Math.abs(pla[3]))
const D = vec3.subtract(_(), [0,0,sc], p)
const P = vec3.subtract(_(), [0,0,sc], vec3.scale(_(), D, (2*sc)/D[2]))
const E = vec3.subtract(_(), [0,0,sc], q)
const Q = vec3.subtract(_(), [0,0,sc], vec3.scale(_(), E, (2*sc)/E[2]))
return [
colorize([0.7,0.7,0.7],
subtract(
sphere({ radius: sc, segments: 60 }),
translate([0,0,0],
rotate([0,pol[1],pol[0]],
cube({size: 2*sc, center: [0,0,-pla[3]+sc]})
)
)
)),
colorize([1,1,0], vertex(N,true)),
colorize([0,1,0], vertex(p,true)),
colorize([0,1,0], vertex(q,true)),
edge3(p,q),
edge(p,q,true),
colorize([1,0,0], vertex(P, true)),
colorize([1,0,0], vertex(Q, true)),
colorize([1,1,0], edge(N,Q,true)),
colorize([1,1,0], edge(N,P,true)),
colorize([0,0,0], edge(P,Q,true)),
]
}
module.exports = { main }
@Hermann-SW
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment