Tuesday, July 31, 2012

Day 5 - Corner connector

Branching out from my kid's toybox, I ventured out into the garage to find interestingly shaped objects. Here is something my wife pulled off of an old TV stand (that she subsequently made into a toy kitchen for our kid - she's cool like that). Forget the name of these, but lets you screw two things together at a 90 degree angle.
So, pretty straight forward. I slice a cube at 45 degrees, and I subtract a scaled copy from itself. Two cylinders and a cube are subtracted to make the slits.
  
module corner_part() {
  difference() {
    cube(25);
    translate([25,0,0]) rotate([0, -45, 0]) cube(50);  
  }  
}

module corner() {
  difference() {
    corner_part();
    translate([2, (25-(25*0.8))/2, 2]) scale([1, 0.8, 1]) corner_part();
  }
}

difference() {
  corner();
  translate([10, 12.5, 0]) slot();
  rotate([0, -90, 0]) translate([10, 12.5, -3]) slot();
}

module slot() {
  linear_extrude(height = 20) {
    union() {
      circle(2.5, $fn = 50);
      translate([5, 0, 0]) circle(2.5, $fn = 50);
      translate([0, 0-2.5, 0]) scale([1, 1, 1]) square(5);    
    }
  }
}
  

Monday, July 30, 2012

Day 4 - Toy Wrench

Continuing on the trend of "what is laying around", I modeled a toy wrench.
This is definitely a step up in complexity from the first few objects. The hardest part for me was the toolhead. My first thought was that I could create the outside shape as a cylinder with a hexagon taken out, then scale that and subtract it to end up with the raised rim. However, I couldn't get that to work. Then I decided to take a different tack and use a minkowski sum to trace a cylinder around the cylinder/hexagon part to build up the wall. Much better.

The problem I had with the minkowski sum is that I forgot it adds the one object all over the other, so my tool head was twice as tall. I probably could have doen this in 2d and extruded, but instead I just wanted to move ahead and compensated. (This is one of those cases that a ruler on the screen would have helped, as I would have realized sooner that this is what was going on.) As an aside - don't try to scale by '0' - it doesn't like that and crashes.

I rounded one of the edges by rotating a circle to get a torus. I also created the little grip bars by joining a cylinder and a sphere (and then I rotated that in a for loop to place it around the handle). I didn't bother hollowing out the handle.

It seems to me that if you up the value of $fn just a little, the CGAL render time goes up a *lot*. Bumping it to 50 (just for the handle) made the time go from nothing to almost five minutes.

Here is the end result:
And the code
  
include <MCAD/shapes.scad>

TOOL_HEIGHT = 14;
FLAT_PART_THICKNESS = 1;

module wrench_head_part() {
  difference() {
    cylinder(h = TOOL_HEIGHT, r = 22.5);
    translate([7.5, 0, TOOL_HEIGHT/2]) hexagon(25, TOOL_HEIGHT);
    translate([14, -12.5, 0]) cube([25, 25, TOOL_HEIGHT]);
  }
}

module outer_hull() {
  scale([1, 1, 0.5])
  minkowski() {
    wrench_head_part();
    cylinder(h = TOOL_HEIGHT , r = 1);
  }  
}
  
module full_wrench_head() {
  difference() {
    outer_hull();
    translate([0, 0, (TOOL_HEIGHT/2) + FLAT_PART_THICKNESS]) wrench_head_part();    
    translate([0, 0, -(TOOL_HEIGHT/2) - FLAT_PART_THICKNESS]) wrench_head_part();    
  }
}

module stem() {
  difference() {
    rotate([0, 90, 0]) cylinder(h = 37, r=8);
    translate([-.5, -7,  FLAT_PART_THICKNESS]) cube([38, 14, 10]);
    translate([-.5, -7, -10 - FLAT_PART_THICKNESS]) cube([38, 14, 10]);    
  }
}

module grip_bar() {
  $fn = 50;
  rotate([0, 90, 0]) linear_extrude(height = 59) circle(1);
  translate([59, 0, 0]) sphere(1);
}

module handle() {
  $fn = 50;
  translate([-75, 0, 0]) rotate([0, 90, 0]) cylinder(h = 60, r=14);
  translate([-15, 0, 0]) rotate([0, 90, 0]) cylinder(h = 15, r=13);
  rotate([0, 90, 0]) cylinder(h = 5, r1 = 13, r2 = 8);
  translate([-75, 0, 0]) rotate([0, 90, 0]) cylinder(h = 3, r=15);
  for (i=[0:7]) {
    rotate(i*45, v=[1, 0, 0]) translate([-75, 14, 0]) grip_bar();
  }
  translate([-15, 0, 0]) rotate([0, 90, 0]) rotate_extrude(convexity = 10) translate([13, 0, 0]) circle(r = 1);
}

module wrench() {
  union() {
    translate([0, 0, -TOOL_HEIGHT/2]) rotate([0, 0, -14]) full_wrench_head();
    difference() {
      translate([-37 - 20, 0, 0]) stem();  
      translate([0, 0, -TOOL_HEIGHT/2]) rotate([0, 0, -14]) outer_hull();    
    }
    translate([-42 - 20, 0, 0]) handle();
  }
}

wrench();

Sunday, July 29, 2012

Day 3 - Big Block

Here is a squishy block that was on my work at desk


Basically, a block with little nubs (cylinders) on top and bottom. I use a little for loops and some modules so I don't have to repeat myself. I don't know if this would print on 3d printer - I feel like the holes on the bottom would be an issue without some kind of scaffolding, but haven't gotten that far in my readings to know for sure yet.

  
$fn = 200;

difference() {
  union() {
    cube([81, 41, 23]);
    translate([0, 0, 25.5]) nub_array();
  }
  translate([0, 0, 2.5]) nub_array();
}

module nub_array() {
  for (x=[0:3]) {
    for (y=[0:1]) {
      translate([x*20 + 4 + 6.5, y*20 + 4 + 6.5, 0]) nub();
    } 
  }  
}

module nub() {
  cylinder(r=6.5, h=5, center=true);
}

Saturday, July 28, 2012

Day 2 - Toy Train

Second model - a toy train. I get the feeling I'm going to end up modeling a lot of my kid's toys, as they have interesting, simple shapes. And I can easily take them on the train.


This is basically a rectangular prism with some bits shaved off with a cylinder. For the nose part, I put the cylinder with another rectangular prism first so I could union with the main one without shaving the rest of the original off.

One thing I found hard with this was getting the nose at the right angle. I must have done my calc wrong, because when I first did it, just didn't look right. As far as I can tell, there aren't rulers in OpenSCAD yet. So it was hard to just measure where things ought to be. So I did a poor-man's ruler and just put some colored cubes on the screen for my measurements.

So, with my cubes in place and eyeballing everything, I managed to get the nose pretty close to my measurements. Here is the result (sans wheels - will get to those later):


and here is the code
  
//Dimensions in mm
$fn = 200;
intersection() {
  cube([70, 20, 28]);
  translate([0, 10, 8]) rotate([0, 90, 0])  cylinder(h = 70, r = 20);
  union() {
    cube([40, 20, 28]);
    translate([30, 10, 11]) rotate([0, 114, 0])  cylinder(h =70, r = 20);
  }
}
//These are what I used for measurements
//color("red") translate([70, 10, 0]) cube(15);
//color("blue") cube([40, 20, 28]); 

Friday, July 27, 2012

First object - train tracks

As a start, I tried modeling a piece of toy train track.

The approach I took was to make 2d objects and then extrude them. It is made up of a rectangle for the main part. I then add a circle and a rectangle for the connector stem. I use the same connector to remove the hole at the other end. I extrude all of this to get the basic shape. I then extrude another set of rectangles and subtract them to make the grooves.

I tried to parameterize everything. The train track module takes a parameter to adjust the length of the track, and then all the other measurements of the object are variables at the top of the file.
Here is the result

and here is the code that produced it
  
//Units in mm
TRACK_WIDTH = 40;
TRACK_HEIGHT = 12;
GROOVE_WIDTH = 6;
GROVE_DISTANCE_IN = 4;
GROOVE_DEPTH = 3;

CONNECTOR_RADIUS = 6;
CONNECTOR_STEM_LENGTH = 4;
CONNECTOR_STEM_WIDTH = 3;

$fn=100;

module train_track(length = 250) {
 difference() {
  linear_extrude(height = TRACK_HEIGHT) {
 difference() {
  union(){
   translate([CONNECTOR_RADIUS + CONNECTOR_STEM_LENGTH, -TRACK_WIDTH/2, 0]) square([length, TRACK_WIDTH]);
   connector();
  }
  translate([length, 0, 0]) connector();
 }
  }
  translate([CONNECTOR_RADIUS + CONNECTOR_STEM_LENGTH + length/2, 0, TRACK_HEIGHT - GROOVE_DEPTH])
  linear_extrude(height = GROOVE_DEPTH) {
   translate([0, (-TRACK_WIDTH/2) + GROVE_DISTANCE_IN + (GROOVE_WIDTH/2), 0]) square([length, GROOVE_WIDTH], true);
   translate([0, (TRACK_WIDTH/2) - GROVE_DISTANCE_IN - (GROOVE_WIDTH/2), 0]) square([length, GROOVE_WIDTH], true);
  }
 }
}

module connector() {
 union(){
 translate([CONNECTOR_RADIUS, 0, 0]) square([CONNECTOR_STEM_LENGTH + CONNECTOR_RADIUS, CONNECTOR_STEM_WIDTH], true);
    circle(CONNECTOR_RADIUS);
 }
}
train_track(); 

You can also find it on Thingverse here.

Any comments as to style or how I could do it better would be much appreciated.
Also, I uploaded it to Shapeways to see how much it would cost to make - $93 for plastic? Pretty sure I did it right, but that seems like an amazing amount.

The Big Idea

I am trying to learn OpenSCAD. I have been inspired by this tutorial to try to model real objects. In order to keep my motivation up, I am going to set the goal of modeling one object per day. I doubt I will be able to do it *every* day, but am going to see how close I can get.