/Bike/FladBedAttachments.foocad
See FlatBed.foocad.
I have a heavy-duty plastic box, that I want to attach to the back of my bike.
boltKnob
The box is attached attached to the plywood with 4 bolts. This piece makes the bolt head much bigger, and easy to screw/unscrew by hand. The bolt is glued to this piece.
boltKnob2
The bolts the hold the flat bed to the pannier rack.
boxCorner
Helps locate the box on the plywood. They just make it easier to screw the bolts in
import static uk.co.nickthecoder.foocad.diagram.v1.Diagram.* import static uk.co.nickthecoder.foocad.arrange.v1.Arrange.* import static uk.co.nickthecoder.foocad.screws.v3.Screws.* import uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* import static uk.co.nickthecoder.foocad.extras.v1.Extras.* class FlatBedAttachments : Model { @Custom( about="Radius, thickness and height of the corner" ) var size = Vector3( 57, 10, 8 ) @Custom var angle = 48 val headD = 12 val holeD = 6.6 @Piece fun boltKnob() = boltKnob( Vector2(24,4), 10 ) @Piece fun boltKnob2() = boltKnob( Vector2(45,2), 10 ) fun boltKnob( size : Vector2, knobSpacer : double ) : Shape3d { val knobDiameter = 18 val recessDepth = 8 val height = knobSpacer + recessDepth val hex = Circle( knobDiameter/2 ).sides(6).roundAllCorners( 3 ) val flat = Circle( size.x/2 ) .smartExtrude( size.y ).filletTop(size.y / 2) val knob = hex.smartExtrude( height ) .filletTop( 2 ) .chamferBottom( 1 ) val throughHole = Cylinder( 100, holeD / 2 ).center() val recess = Circle( headD/2 ).sides( 6 ).extrude( recessDepth + 0.1 ) .topTo( knob.top + 0.1 ) return flat + knob - recess - throughHole } // Print using TPU. @Piece fun cap() : Shape3d { val capHeight = 4 return Circle( headD / 2 - 0.3 ).sides(6).roundAllCorners(1, 1).extrude( capHeight ) } @Piece fun washer() : Shape3d { return (Circle( boltKnob().size.x/2 ) - Circle( 4 ) ) .extrude( 2 ) } @Piece fun washer2() : Shape3d { return (Circle( 45 / 2 ) - Circle( 4 ) ) .extrude( 1.2 ) // Was 2.0 } @Piece fun boxCorner() : Shape3d { val countersink = commonCountersink("small", 16) val holeAngle = angle/2 * 0.8 val sector = Sector( size.x + size.y, -angle/2, angle/2 ) - Sector( size.x, -angle/2 -1, angle/2 + 1 ) val roundedEnds = Circle( size.y / 2 ).sides(30) .translateX( size.x + size.y / 2 ) .rotate( angle/2 ) .mirrorY().also() val screwBulges = Circle( size.z, 6 ).sides(40) .translateX( size.x + size.y ) .rotate( holeAngle ) .rotate( -holeAngle * 2 ).also() val midBulge = Circle( 10 ).scaleY(1.2) .translateX( size.x + size.y - 2 ) val profile = sector + roundedEnds + screwBulges + midBulge val screwHoles = countersink .translateX( size.x + size.y ) .rotateZ( holeAngle ) .rotateZ( -holeAngle * 2 ).also() .topTo( size.z ) val main = profile.smartExtrude( size.z ) .offsetTop( -1 ) .smartFilletTop( 2 ) .chamferBottom(0.4) val postHole = Cylinder( 100, 8 ) .translateX( size.x ).translateZ(-0.1) val slot = Triangle( size.y, size.y ) .extrude( 4 ) .rotateX(90).centerY() .mirrorZ().topTo( main.top + 0.1 ) .leftTo( postHole.right - 0.2 ) return main - slot - postHole - screwHoles } override fun build() : Shape3d { return arrangeX( 20, boxCorner().labelFront( "boxCorner" ), boltKnob().labelFront( "boltKnob" ), washer().labelFront( "washer" ), cap().labelFront( "cap" ), boltKnob2().labelFront( "boltKnob2" ), washer2().labelFront( "washer2" ) ).centerX() } }