/Hardware/HookS.foocad

A general purpose S-shaped hook.
First used to hang a portable DVD drive on the back of my laptop screen.
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
class HookS : Model {
@Custom
var size = Vector2( 90, 150 )
@Custom
var hook1 = Vector2( 20, 25 )
@Custom
var radius1 = 12
@Custom
var hook2 = Vector2( 8, 10 )
@Custom
var radius2 = 5
@Custom
var thickness = 1.2
@Custom
var edge = Vector2(4, 5)
@Custom
var chamfer = 0.8
@Custom
var diamondCutouts = true
@Custom
var diamondSize = 20
@Custom
var gap = 5
@Custom
var margin = Vector2( 10, 10 )
meth hook() : Shape3d {
val s = PolygonBuilder().apply {
moveTo( 0, 0 )
radius( radius1 )
lineBy( 0, -hook1.y )
lineBy( hook1.x + edge.x, 0 )
radius( radius2 )
lineBy( 0, size.y + edge.x/2 )
lineBy( hook2.x + edge.x, 0 )
radius(0)
lineBy( 0, -hook2.y )
}.buildPath()
val thin = s.thickness(thickness).smartExtrude(size.x)
val end = Circle( edge.x/2 ) hull Circle( edge.x/2 ).translateY( edge.y - edge.x )
val ends = (
end.translate( s[0] ).translateY( - edge.y + edge.x ) +
end.translate( s[-1] )
).smartExtrude( thin.top ).edges( Chamfer(chamfer) )
val edges = s.thickness(edge.x)
.smartExtrude( edge.y )
.bottom( Chamfer(chamfer) )
.top( Chamfer(0.5) )
.mirrorZ().topTo( thin.top ).also(2)
if ( diamondCutouts ) {
val diamonds = Square( diamondSize )
.tileX( 5, gap ).tileY( 5, gap )
.center().rotate(45)
val envelope = Square( size.x - margin.x*2, size.y - margin.y*2 ).center()
val cutouts = diamonds.intersection( envelope )
.smartExtrude( thickness + 0.02 )
.edges(Chamfer(thickness/3).reverse())
.rotateY(90)
.centerZTo( size.x/2 )
.centerYTo( thin.middle.y )
.translateX( hook1.x - 0.01 - thickness*0.5 + edge.x )
return thin + ends + edges - cutouts
} else {
return thin + ends + edges
}
}
@Piece( print="hook" )
override fun build() : Shape3d {
val hook = hook()
.rotateX(90).centerY().rotateZ(-90)
val drive = Cube( 145, 20, 145 ).centerX()
.backTo( hook.back - edge.x )
.translateZ(-15)
.previewOnly()
return hook + drive
}
}
