FooCAD Source Codeimport static uk.co.nickthecoder.foocad.diagram.v1.Diagram.*
@Data
class Knob(
val knobSize : Vector2,
val baseSize : Vector2,
val waist : double,
val holeDiameter : double
) : Lazy3d() {
constructor() : this( Vector2( 40, 25 ) )
constructor( size : double ) : this( Vector2( size, size * 0.6 ) )
constructor( size : Vector2 ) :
this ( size, Vector2(size.x * 0.7, size.y * 0.25), size.x * 0.5, 3.8 )
// 4.5 for M4 inserts
// 3.8 for M3 inserts
override meth build() : Shape3d {
val waistPoint = Vector2( waist/2, baseSize.y )
val midPoint = Vector2( knobSize.x * 0.5, baseSize.y + knobSize.y * 0.5 )
val deltaY = Vector2( 0, knobSize.y * 0.15 )
val tip = Vector2( 0, baseSize.y + knobSize.y )
val baseTop = Vector2(baseSize.x / 2, baseSize.y/3)
val profile = PolygonBuilder().apply {
// The base of the knob (ending at the waist)
moveTo( 0,0 )
lineTo( baseSize.x / 2, 0 )
lineTo( baseTop )
bezierTo( baseTop + Vector2(0, baseSize.y/3), waistPoint + Vector2(0,-baseSize.y/3), waistPoint)
// The main part of the knob
bezierTo( midPoint - deltaY*1.4, midPoint)
bezierTo( midPoint + deltaY, Vector2(knobSize.x * 0.5, tip.y), tip )
}.build()
val screwHole = Cylinder( knobSize.y/2, holeDiameter/2 ).hole().bottomTo( -0.01 )
return profile.revolve().color( "lightGrey") - screwHole
}
}
class CustomisableKnob : AbstractModel() {
@Custom( about="The size of the knob (not including the base's height)" )
var knobSize = Vector2( 40, 25 )
@Custom( about="The size of the base. Y = the height at the waist")
var baseSize = Vector2( 24, 6 )
// This should always be smaller than baseSize.x
@Custom( about="The diameter at the waist (the thinnest part of the knob")
var waist = 20.0
@Custom( about="The diameter for the threaded insert" )
var holeDiameter = 4
@Piece
fun diagram() : Shape3d {
val knob = build()
val knobSizeLabel = apiSize( "knobSize", knobSize )
.rotateX(90)
.backTo( knob.front )
.bottomTo( baseSize.y )
.leftTo(knob.left)
val baseSizeLabel = apiSize( "baseSize", baseSize )
.rotateX(90)
.backTo( -baseSize.x/2 )
.leftTo(-baseSize.x/2)
val waistLabel = apiLength( "waist", waist )
.translateY( -waist / 2 )
.bottomTo( baseSize.y )
.leftTo( waist )
return knob + knobSizeLabel + baseSizeLabel + waistLabel
}
override fun build() = Knob( knobSize, baseSize, waist, holeDiameter )
}