muse/book-reading-clip-lamp

A tscircuit package created by muse.

Version
0.4.6
License
unset
Stars
0

catalog-base-hardware.ts

import {box,cyl,move,turn,union,subtract,tint,type Plan,type V3} from "./mechanical-primitives"
/** Source geometry references and purchase list: base-catalog-parts.json.
 * All models are authored from drawings, not manufacturer-certified CAD.
 */
export const segment=(a:V3,b:V3,r:number):Plan=>{const [dx,dy,dz]=b.map((n,i)=>n-a[i]),l=Math.hypot(dx,dy,dz);return move(a.map((n,i)=>(n+b[i])/2) as V3,turn([0,0,Math.atan2(dy,dx)],turn([0,Math.acos(dz/l),0],{type:"cylinder",radius:r,height:l+.03,segments:20})))}
export const stockButton=(x:number,y:number,latching=false):Plan=>move([x,y,-161],union(
  tint([.08,.09,.09],union(cyl(7.4,-18.5,-2),cyl(8,-10,-2),cyl(9,0,2),cyl(8.9,-6,-4))),
  tint(latching?[.65,.02,.015]:[.9,.035,.025],cyl(6.5,2,6.3)),
  ...[-3,3].map(dx=>tint([.65,.65,.60],box([2,.6,5.5],[dx,0,-20.75]))),
  ...(latching?[-3,3].map(dx=>tint([.65,.65,.6],box([2,.6,4.5],[dx,4,-20.25]))):[]),
  // Precrimped 0.110 inch push-on leads, Adafruit 1152; ~18 mm overall
  // socket envelope from the supplier's linked equivalent terminal drawing.
  ...[-3,3].map(dx=>tint([.06,.07,.08],subtract(union(
    box([3.76,2.1,7],[dx,0,-21]),cyl(1.5,-35.8,-24.5,dx,0)),box([2.1,.75,5.7],[dx,0,-20.7])))),
  // Unused lamp terminals are insulated. No LED wiring in the base.
  ...(latching?[-3,3].map(dx=>tint([.06,.07,.08],box([2.5,1.2,5],[dx,4,-20.3]))):[]),
))
const hex=(r:number,h:number):Plan=>({type:"extrudeLinear",options:{height:h},shape:{type:"polygon",points:Array.from({length:6},(_,i)=>[r*Math.cos(i*Math.PI/3),r*Math.sin(i*Math.PI/3)])}})
const axial=(x:number,plan:Plan)=>move([x,-181,-211],turn([0,Math.PI/2,0],plan))
export const hingeBolt=union(
  // M4 x 70 under-head length; threads represented by nominal major diameter.
  axial(-31.5,cyl(2,0,70)),
  axial(-31.5,subtract(cyl(3.5,-4,0),move([0,0,-4.1],hex(3/Math.sqrt(3),2.1)))),
)
export const hingeWashers=union(...[-31.5,30.6].map(x=>axial(x,subtract(cyl(4.5,0,.9),cyl(2.15,-.1,1)))))
export const hingeNut=axial(31.6,union(tint([.6,.63,.64],subtract(hex(7/Math.sqrt(3),4),cyl(2.05,-.1,4.1))),tint([.15,.2,.25],subtract(cyl(3.5,4,5),cyl(2.05,3.9,5.1)))))
// TMR-0304-035 catalog: OD .304, wire .035, 7 coils, solid length .290,
// free arms 180 deg, 1.250 inch tangent legs. Shown with 160 deg preload,
// a reference deformation only: force, fatigue and wound direction need trials.
const wire=.035*25.4, meanR=(.304*25.4-wire)/2, loadedTurns=7+160/360
const springPoints:V3[]=Array.from({length:181},(_,i)=>{const t=i/180,a=(95+t*loadedTurns*360)*Math.PI/180;return [-3.2385+6.477*t,-181+meanR*Math.cos(a),-211+meanR*Math.sin(a)]})
export const springLegEnds:V3[]=[
 [springPoints[0][0],springPoints[0][1]+31.75*Math.cos(5*Math.PI/180),springPoints[0][2]+31.75*Math.sin(5*Math.PI/180)],
 [springPoints[180][0],springPoints[180][1]+31.75*Math.cos(15*Math.PI/180),springPoints[180][2]-31.75*Math.sin(15*Math.PI/180)],
]
export const springPath=[springLegEnds[0],...springPoints,springLegEnds[1]]
export const torsionSpring=union(...springPath.slice(1).map((p,i)=>segment(springPath[i],p,wire/2)))
export const springClearance=union(...springPath.slice(1).map((p,i)=>segment(springPath[i],p,wire/2+.18)))

export const springBushing=union(...[[-4.1,4.1,2.375],[-5,-4.1,3.8],[4.1,5,3.8]].map(([x0,x1,r])=>axial(x0,subtract(cyl(r,0,x1-x0),cyl(2.15,-.1,x1-x0+.1)))))

/** DIN 912 M2 heads; thread-root only inside the printed 1.7 mm pilot.
 * Major-diameter clearance portion shown through the loose lid/cradle.
 */
export const m2Screw=(x:number,y:number,seat:number,length:number,clearanceDepth:number):Plan=>move([x,y,seat],union(
 cyl(.8,-length,0),cyl(.98,-clearanceDepth,0),
 subtract(cyl(1.9,0,2),move([0,0,.9],hex(1.5/Math.sqrt(3),1.2))),
))