Exit Full View
Up

/Games/FloatingSphere2.foocad

FloatingSphere2

Inspired by Maker's Muse : [https://www.youtube.com/watch?v=7G5WpeJ1iG4]

A magic trick. Wind thread around both parts of the pulleys, with the ends exiting opposide poles of the sphere.

Pull to make the sphere rise up, release the tension to allow ot to fall under gravity.

There are several ways you could join the two halves. Magnets, glue, elastic bands. I have a slice of an old bicycle inner tube which works well (but is tricky to get on).

Note. It's funny how much more convoluted Maker's Muse's version is. Using plastic clips to join the halves together caused all kinds of problems, which the magnets of mine bypasses. Also, his has a metal bearing, as did my first version! But playing with the first print convinced me that it wasn't needed. Nor is there any need for an axel for the pulleys. So we end up with 3 basic parts.

I printed this on a budget printer (an Artilery Genius) using 0.2mm layers, and was able to get it running smoothly after a few minutes with a craft knife!

Construction Notes

Test fit the three parts, carefully removing any blobs of plastic which prevent smooth rotation.

Drill 2 small holes in the pulley from each groove into the central hole. The holes must be big enough so that a tied piece of string will fit through.

Poke the thread into one of the holes, and use tweezers to pull it from the central hole. Do the same with the other end of the string for the other pulley. Tie the ends together - the knot should be in the central hole.

Pull the string, so that the knot goes though one of the small holes. Snip the knot off - your thread is now correctly threaded :-) Wind half of thread onto the large pulley. If you wish, you can use a dab of hot glue to prevent the thread for coming undone. Tie each ends to a ring (Use the plastic ones or your own jewelry!

Assemble the three pieces, and keep them together temporarily with elastic bands. Check that the mechanism works

If the pulley is free to move in both halves, but jams when the three pieces are put together, you need a slight gap between the two halves. A piece of paper (or two) cut to shape will do nicely. You could use double sided tape ;-)

Once everything is working, you could replace the elastic bands with a few tiny spots of super glue. Keep well away from the pulley.

FooCAD Source Code
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*

class FloatingSphere2 : Model {
    
    var pulleyA = 20
    var pulleyB = 10

    var pulleyThickness = 9.0

    // The groovy will be pulleyThickness - pulleySide * 2
    var pulleySide = 0.8

    var radius = 27

    var thickness = 1.2

    var slack = 0.3

    // How much bigger in mm each half is, compared to a hemisphere.
    // Hopefully this will mitigate the need for a piece of paper, as a spacer.
    // Experimental!
    var halfSlack = 0.4

    var magnetD = 11.0

    var magnetH = 2.0

    var ringSize = 23

    @Piece
    fun pulley( radius : double ) : Shape3d {
        val inside = pulleyThickness - pulleySide * 2
        val profile = PolygonBuilder().apply {
            moveTo(0, -pulleyThickness/2)
            lineTo(radius, -pulleyThickness/2)
            lineTo(radius, -inside/2)
            lineTo(radius-inside/2, -inside/2) // Assymetric
            lineTo(radius-inside/2, 0)
            lineTo(radius, inside/2)
            lineTo(radius, pulleyThickness/2)
            lineTo(0, pulleyThickness/2)

        }.build()

        return profile.revolve().sides(60)
    }
    
    @Piece
    fun doublePulley() : Shape3d {

        val result = pulley(pulleyA).toOriginZ() +
            pulley( pulleyB ).toOriginZ().translateZ(pulleyThickness - pulleySide)

        // A hole in the middle can be used to tie the ends of the thread,
        // or to pass the thread from one pulley onto the other if you use a single
        // length.
        val hole = Cylinder( pulleyThickness * 5, 4 ).center()
        return result.color("Silver") - hole
    }

    @Piece
    fun half() : Shape3d {
        val sides = 80

        val slotA = Cylinder( pulleyThickness + slack*2, pulleyA + slack*2 )
            .rotateX(90)
            .translateY(pulleyThickness-pulleySide/2+slack)
            .color("Red")
        val slotB = Cylinder( pulleyThickness - pulleySide + slack, pulleyB + slack*2 )
            .rotateX(90)
            .translateY( -pulleySide/2 )
            .color("Red")

        val hemi = Sphere( radius ).sides(sides) /
            Cube( radius * 2 ).centerXY().translateZ(-halfSlack)

        val hole = Cube( 2, 4, radius*2.1 ).center()
           
        // Attemps to make the string for pulleyB easier.
        // However, both strings will cut into the plastic over time.
        val exit =  Square( pulleyB + slack*2 ).rotate(45).center()
                .scale(1,pulleyA/pulleyB)
                .translate(0, (pulleyB+slack*2)/Math.sqrt(2))
                .extrude( pulleyThickness )
                .rotateX(90)

        val magnets = Cylinder.hole( magnetH+0.01, magnetD/2 )
            .translate( radius*0.42, radius*0.57, -0.01 )
            .mirrorX().also().mirrorY().also()

        val result = hemi - slotA - slotB - exit - hole - magnets
        return result.translateZ(halfSlack)
    }

    // Not needed for the device, but may help  perform the trick by making it
    // easier to hold the ends of the string.
    // Hide a thread cutter somewhere, and cut the thread at the end of the trick.
    // (Don't use a blade!). FYI, you can buy thread cutters which are rings!
    @Piece
    fun ring() : Shape3d {
        return Circle(ringSize/2+3).chamferedExtrude( 3, 0.6 ) -
            Circle( ringSize/2 ).internalChamferedExtrude( 3, 0.6 )
    }

    @Piece
    fun inspect() : Shape3d {
        val pieces = half() + doublePulley().center().rotateX(90)
        return pieces // Cube( 1, innerR*2.2, innerR*2.2 ).center().rotateZ(30)
    }

    override fun build() : Shape3d {
        return half().translateY(radius*2+2).also() +
            doublePulley().translateX(radius*2) +
            ring().translateY( -radius - 20 ).tileX(2,2)
    }
}