Close



Results 1 to 4 of 4
  1. #1
    Peachy Printer Founder
    Join Date
    Sep 2013
    Posts
    308

    Moving Ball Joint Print

    Im hanging out with my kid right now and well both of us couldn't sleep, I asked him what he was thinking about and he said, "printing a lego halo joint"
    REALLY I said !! I was also up thinking about how to print a ball joint. I said, want to stay up late and work on it? ... well we both lept up and couple hours later ( thankfuly its not a school night )
    here is what we have come up with:

    Started off with some doodling, he explained that it should move all directions, and snap together and come apart,
    I explained what the variables were and that i wanted all the variables to stem from the size so we could easily print big and small ones by changing just one number.
    and that we need variables for the things that he cares about like tightness of the joint, and how easy it is to snap together. ...
    here is our doodles:

    photo(1).jpg

    well with a plan we both liked it was time to start coding
    I cracked open OpenSCAD ( its been months so I wasnt sure how it would go :S )
    After quick study of the cheat sheet things started going quite quickly, here is what I got done in my first go:

    0a-open-ball-Joint.jpg

    I usually code with animation on so that I can see that things are acting parametricaly as expected, its so nice to have your computer
    ripping thru a visualization of most of the values that you would ever throw at a model like this.
    This animation shows the power of openSCAD so well I just had to post a vid so you could see to!
    You can get openSCAD here for free! http://www.openscad.org/


    https://www.youtube.com/watch?v=9Rsp...ature=youtu.be

    and here is the code:

    Code:
     outerJointDi = 10 * $t + 9.5; 
     outerJointThickness = outerJointDi* .1;
     tightness = -.1;
     outerJointHole = outerJointDi* .4 *$t+1;
     outerJointSocketDi = outerJointDi - (outerJointThickness*2);
     
    
     inerJointDi = outerJointDi - (outerJointThickness*2) + tightness;
     
    
     
    
     cutViewThickness = outerJointDi*.1;
     resolution = 50;
     
    
     boneDi = outerJointDi/4;
     boneLength = outerJointDi;
     
    
     inerBoneDi = inerJointDi/4;
     inerBoneLength = outerJointDi;
     
    
     numberOfJointCuts = 10;
     cutThickness = outerJointDi*.05;
     cutDepth = outerJointDi*.8;
     cutTwist= -40 *$t+1;
     
    
     
    
     
    
     module bone()
     {
         cylinder(boneLength,boneDi,boneDi,$fn = resolution);
     }
     
    
     module inerBone()
     {
         cylinder(inerBoneLength,inerBoneDi,inerBoneDi,$fn = resolution);
     }
     
    
     module cuts()
     {
     for (cut = [0:360/numberOfJointCuts:360])
         {
         echo(cut);
         rotate([cutTwist,0,cut])
             translate([0,0,outerJointDi/2-cutDepth])
             cube([10,cutThickness,20]);
         }
     }
     
    
     
    
     module inerJointCuts()
     {
     for (cut = [0:360/numberOfJointCuts:360])
         {
         echo(cut);
         rotate([0,0,cut])
             translate([0,0,inerJointDi/2-cutDepth/1.3])
             cube([10,cutThickness,20]);
         }
     }
     
    
     module inerJoint()
     {
         union()
         {
             difference()
             {
                 sphere(d = inerJointDi,$fn = resolution); 
                 inerJointCuts();
             }
         translate([0,0,-boneLength-inerJointDi/2+outerJointThickness-.1])
             inerBone();
         }
     }
     
    
     module outerJoint()
         {
         union()
             {
             difference()
                 {
                 sphere(d = outerJointDi,$fn = resolution);
                 cylinder(outerJointDi/2 +1,outerJointHole,outerJointHole,$fn = resolution);
                 sphere(outerJointSocketDi/2,$fn = resolution);
                 cuts();
                 }
             translate([0,0,-boneLength-outerJointDi/2+outerJointThickness-.1])
             bone();
             }
         }
     
    
     module drawJoint()
     {
         difference()
         {
             color("green")
             outerJoint();
             rotate([0,0,360*$t])
             cutView();
         }
         
         rotate([180,0,0])
         inerJoint();
         module cutView()
         {
             translate([0,cutViewThickness+outerJointDi/4 +.5,0]) 
                 cube([outerJointDi +1,outerJointDi/2+1 , 100], center= true);
             //translate([0,-1* (cutViewThickness+outerJointDi/4 +.5),0]) 
                 //cube([outerJointDi +1,outerJointDi/2+1 , 100], center= true);
         }
     }
     //cuts();
     //cutView();
     drawJoint();
    Looking forward to printing it.. but better try that bed time thing again first lol
    Last edited by rylangrayston; 12-21-2014 at 11:42 AM.

  2. #2
    Super Moderator curious aardvark's Avatar
    Join Date
    Jul 2014
    Posts
    8,818
    Hmm, love the video.
    But you'll need a larger gap at the top to the push the ball joint into the cup. Unless you're using a flexible resin, there's not going to be as much flex as you think.

  3. #3
    Peachy Printer Founder
    Join Date
    Sep 2013
    Posts
    308
    Quote Originally Posted by curious aardvark View Post
    Hmm, love the video.
    But you'll need a larger gap at the top to the push the ball joint into the cup. Unless you're using a flexible resin, there's not going to be as much flex as you think.
    Right so The hole idea behind paramatrization is that you can have the full range of possibly valuable gaps, hole sizes, tighnesses etc.
    It might be hard to tell in the first video but the hole size in the socket is changing.

    I didn't code this with any specific material in mind, but rather coded it with the fundamental concepts as to how it works and what things would be important to change if one were to print it in a wide range of materials, sizes, and want a wide range of joint behaviours.

    What your looking at isnt really "A" joint its more like a custom joint builder. I think your right, for the resin we print in typically the socket will need a bigger hole to snap apart without breaking, its coded in such a way that you can have a snapping joint or you can also have a stronger joint that would break before coming apart.

    here is a quick video that shows only the sockets hole size animated...( oh actually i animated the resolution to just for fun )
    enjoy!

    https://www.youtube.com/watch?v=h3hf...ature=youtu.be


    Ps there is also a variable called tighness that controls the size of the ball as a percentage of the size of the socket, if the ball is slightly bigger than the socket then the sockets fingers will spring against it creating friction.

    And here is the code( slightly improved and changed to animate just hole size and resolution)

    Code:
     outerJointDi = 10;// * $t + 9.5; 
     outerJointThickness = outerJointDi* .1;
     tightness = -.1;
     outerJointHole = outerJointDi* .4 *$t+1;
     outerJointSocketDi = outerJointDi - (outerJointThickness*2);
     
    
     inerJointDi = outerJointDi - (outerJointThickness*2) + tightness;
     
    
     
    
     cutViewThickness = outerJointDi*.1;
     resolution = 100 *$t+10;
     
    
     boneDi = outerJointDi/4;
     boneLength = outerJointDi;
     
    
     inerBoneDi = inerJointDi/4;
     inerBoneLength = outerJointDi;
     
    
     numberOfJointCuts = 10;
     cutThickness = outerJointDi*.05;
     cutDepth = outerJointDi*.8;
     cutTwist= -20;// *$t+1;
     
    
     
    
     
    
     module bone()
     {
     	cylinder(boneLength,boneDi,boneDi,$fn = resolution);
     }
     
    
     module inerBone()
     {
     	cylinder(inerBoneLength,inerBoneDi,inerBoneDi,$fn = resolution);
     }
     
    
     module cuts()
     {
     for (cut = [0:360/numberOfJointCuts:360])
     	{
     	echo(cut);
     	rotate([cutTwist,0,cut])
     		translate([0,0,outerJointDi/2-cutDepth])
     		cube([10,cutThickness,20]);
     	}
     }
     
    
     
    
     module inerJointCuts()
     {
     for (cut = [0:360/numberOfJointCuts:360])
     	{
     	echo(cut);
     	rotate([0,0,cut])
     		translate([0,0,inerJointDi/2-cutDepth/1.3])
     		cube([10,cutThickness,20]);
     	}
     }
     
    
     module inerJoint()
     {
     	union()
     	{
     		difference()
     		{
     			sphere(d = inerJointDi,$fn = resolution); 
     			inerJointCuts();
     		}
     	translate([0,0,-boneLength-inerJointDi/2+outerJointThickness-.1])
     		inerBone();
     	}
     }
     
    
     module outerJoint()
     	{
     	union()
     		{
     		difference()
     			{
     			sphere(d = outerJointDi,$fn = resolution);
     			cylinder(outerJointDi/2 ,outerJointDi/2-outerJointThickness,outerJointHole,$fn = resolution);
     			sphere(outerJointSocketDi/2,$fn = resolution);
     			cuts();
     			}
     		translate([0,0,-boneLength-outerJointDi/2+outerJointThickness-.1])
     		bone();
     		}
     	}
     
    
     module drawJoint()
     {
     	difference()
     	{
     		color("green")
     		outerJoint();
     		//rotate([0,0,360])
     		//cutView();
     	}
     	
     	rotate([180,0,0])
     	inerJoint();
     	module cutView()
     	{
     		translate([0,cutViewThickness+outerJointDi/4 +.5,0]) 
     			cube([outerJointDi +1,outerJointDi/2+1 , 100], center= true);
     		//translate([0,-1* (cutViewThickness+outerJointDi/4 +.5),0]) 
     			//cube([outerJointDi +1,outerJointDi/2+1 , 100], center= true);
     	}
     }
     //cuts();
     //cutView();
     drawJoint();

  4. #4
    Super Moderator curious aardvark's Avatar
    Join Date
    Jul 2014
    Posts
    8,818
    way out of my current openscad league :-)

    At about 8 seconds is probably right for anything except really flexible resin.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •