Exit Full View
Up

/Bike/FladBedAttachments.foocad

FladBedAttachments

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

FooCAD Source Code
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()
    }
}