Exit Full View
Up

/Bathroom/Knob.foocad

Knob
FooCAD Source Code
import 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 )

}