/House/HangerStandoff.foocad

Let's me hang clothes against a wall/cupboard to dry, such that they don't touch the wall.
Can be used for picture rails (forPictureRail=true)
as well as doors (forPictureTail=false).
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
class HangerStandoff : Model {
@Custom( about="Size (not including the hook part)" )
var size = Vector3( 70, 70, 6 )
@Custom( about="Thickness (x&y) of the lines" )
var thickness = 4
@Custom( about="Size of the hook (top left)" )
var hookSize = Vector3(20, 5, 10)
@Custom( about="Should the bottom support be aligned (in x) with the top" )
var forPictureRail = true
@Custom( about="Determines the angle of the part the hanger rests upon" )
var dip = 20
@Custom( about="Radius of the curve at the bottom right" )
var radius = 5
@Custom( about="Chamfer on the top and bottom" )
var chamfer = Vector2(0.6,0.6)
meth shape() : Shape2d {
val main = PolygonBuilder().apply {
moveTo( -hookSize.x,-hookSize.y )
radius(1)
lineBy( 0, hookSize.y )
radius( radius )
lineTo( thickness, 0 )
lineTo( size.x, -size.y - dip )
if (forPictureRail) {
radius(1)
lineTo( -hookSize.x, -size.y )
radius(0)
lineBy( 0, -hookSize.y )
} else {
radius(0)
lineTo( 0, -size.y )
}
}.buildPath().thickness( thickness )
val endCap = Circle( thickness/2 )
.sides(12)
.centerTo( -hookSize.x, -hookSize.y )
val endCaps = if (forPictureRail) {
endCap.translateY( -size.y ).also()
} else {
endCap.translate( hookSize.x, -size.y + hookSize.y ).also()
}
val triangulation = PolygonBuilder().apply {
moveTo( 0, 0 )
if (forPictureRail) {
bezierBy( Vector2(0, -size.y/2), Vector2(-hookSize.x/2, -hookSize.x/2), Vector2(-hookSize.x+thickness,-size.y) )
} else {
lineBy( 0, -size.y )
}
}.buildPath().thickness( thickness )
return main + endCaps + triangulation
}
override fun build() : Shape3d {
val shape = shape()
val thin = shape.smartExtrude(size.z)
.top( Chamfer(chamfer.x) )
.bottom( Chamfer(chamfer.y) )
val left = shape.left
val thick = shape.smartExtrude(hookSize.z)
.top( Chamfer(chamfer.x) )
.bottom( Chamfer(chamfer.y) )
val angle = Math.atan( thick.height / (-thick.left+thickness/2) ) * 180 / Math.PI
val slice = Cube( thick.size ).scaleZ(4)
.rotateY( angle )
.translate(thick.left + thickness, thick.front, thick.top )
println( "Angle = $angle" )
return thin + (thick - slice) //+ slice.previewOnly()
}
}

