// LEGO-like parametric tire... // (c) Vitaliy Filippov 2014, license: CC-BY-SA 4.0 $fn=60; // 81.6x50: // rim offset is (SPOKE_THICKNESS+(R_I-SPACING-RIM_THICKNESS-CUT_BASE)/2), // so offset=4mm if SPOKE_THICKNESS=12.85 R=40.8; // outer radius R_I=26.5; // innermost radius BEVEL=1; BEVEL_OUTER=1.4; THICKNESS=1.6; BORDER_THICKNESS=1.2; PROT_DEPTH=0.5; PROT_L_WIDTH=2; PROT_A_WIDTH=2; FIX_WIDTH=2; B=2.5; // width of edge for the rim B_W=1.6; // thickness of edge for the rim B_P=4; // position of edge for the rim W=50; // tire width N_L=4; // number of lateral protectors N_A=10; // number of angular protectors SPOKE_THICKNESS=12.85; // thickness of solid spoke part RIM_THICKNESS=2; N_SPOKE=9; // number of spokes CUT_BASE=8; CUT_ANGLE=12; CUT_I_R=1.5; CUT_O_R=2; SPACING=0.6; HOLE_RADIUS=2.4; // my Wanhao Duplicator 4 makes no errors with Slic3r, 2.4mm is ideal lego hole N_A=0; // 6-spoke variant N_SPOKE=6; CUT_ANGLE=21; CUT_I_R=2.5; CUT_O_R=2; // small R=22; BEVEL=0.6; BEVEL_OUTER=0.8; THICKNESS=1.2; BORDER_THICKNESS=0.8; PROT_DEPTH=0.4; SPOKE_THICKNESS=8; FIX_WIDTH=1.2; PROT_A_WIDTH=1; PROT_L_WIDTH=1; B_P=3; B_W=1; B=1.6; R_I=15; CUT_O_R=1; CUT_BASE=5; N_L=2; N_A=0; W=16; difference() { union() { rim(); difference() { tire(); // first layer usually becomes slightly bigger... difference() { cylinder(r=R, h=0.3); translate([0, 0, -0.1]) cylinder(r=R-BEVEL_OUTER-0.2, h=1); } } /* // "Manual support material" needed to print tire difference() { hull() { cylinder(r=R_I+B-0.2, h=B_P-0.2-(BEVEL-0.2*(2-sqrt(2)))); cylinder(r=R_I+B-0.2-(BEVEL-0.2*(2-sqrt(2))), h=B_P-0.2); } translate([0, 0, -0.1]) cylinder(r=R_I+B-0.2-2, h=B_P); } translate([0, 0, B_P+B_W+0.3]) difference() { cylinder(r=R_I+B+THICKNESS, h=W-2*(B_P+B_W+0.3)); cylinder(r=R_I, h=W); }*/ } // to cut and look inside :) translate([0, 0, -0.5]) cube(size=[R+10, R+10, W+1]); } module rim() { V_SPACING=0.2; color([0.5, 0.5, 1]) { difference() { union() { cylinder(r=R_I-SPACING, h=W); // outer fixing edges cylinder(r=R_I+B-SPACING, h=FIX_WIDTH+(B_P-FIX_WIDTH-V_SPACING)); translate([0, 0, W-(B_P-FIX_WIDTH-V_SPACING)-FIX_WIDTH]) cylinder(r=R_I+B-SPACING, h=FIX_WIDTH+(B_P-FIX_WIDTH-V_SPACING)); } // make spokes by cutting space between them for (i = [1 : N_SPOKE]) rotate([0, 0, i*360/N_SPOKE]) rim_cut(); // cut spokes toroidally inside the rim translate([0, 0, W-SPOKE_THICKNESS-(R_I-SPACING-RIM_THICKNESS-CUT_BASE)/2]) rotate_extrude(convexity = 10) translate([(R_I-SPACING-RIM_THICKNESS-CUT_BASE)/2+CUT_BASE, 0, 0]) circle(r = (R_I-SPACING-RIM_THICKNESS-CUT_BASE)/2); // remove the rest of spokes cylinder(r=R_I-SPACING-RIM_THICKNESS, h=W-SPOKE_THICKNESS-(R_I-SPACING-RIM_THICKNESS-CUT_BASE)/2); // add axle hole at the center translate([0, 0, -0.5]) linear_extrude(height=W+1) axle(); // add center cut around axle hole translate([0, 0, W-(B_P-FIX_WIDTH-SPACING)-4]) cylinder(r=CUT_BASE-2, h=5); // make spokes convex using another toroidal cut difference() { translate([0, 0, W-(B_P-FIX_WIDTH-V_SPACING)]) cylinder(r=1+R_I+B-0.5/*R_I-2*/, h=1+(B_P-FIX_WIDTH-V_SPACING)); translate([0, 0, W-(B_P-FIX_WIDTH-V_SPACING)]) scale([1, 1, (B_P-FIX_WIDTH-V_SPACING)/((R_I-SPACING-RIM_THICKNESS-CUT_BASE+2)/2)]) rotate_extrude(convexity = 10) translate([(R_I-SPACING-CUT_BASE)/2+CUT_BASE-RIM_THICKNESS, 0, 0]) circle(r = (R_I-SPACING-CUT_BASE)/2); } // remove the rest symmetrically translate([0, 0, -1]) cylinder(r=1+R_I+B-0.5, h=1+(B_P-FIX_WIDTH-V_SPACING)); } } } module rim_cut() { in_angle = atan((R_I-SPACING-RIM_THICKNESS)*sin(CUT_ANGLE)/((R_I-SPACING-RIM_THICKNESS)*cos(CUT_ANGLE)-CUT_BASE-CUT_I_R)); translate([0, 0, -0.5]) linear_extrude(height=W+1) { hull() { translate([CUT_BASE+CUT_I_R, 0]) circle(r=CUT_I_R); rotate([0, 0, CUT_ANGLE]) translate([R_I-SPACING-RIM_THICKNESS-CUT_O_R, 0, 0]) circle(r=CUT_O_R); rotate([0, 0, -CUT_ANGLE]) translate([R_I-SPACING-RIM_THICKNESS-CUT_O_R, 0, 0]) circle(r=CUT_O_R); } difference() { circle(r=R_I-SPACING-RIM_THICKNESS); translate([CUT_BASE+CUT_I_R, 0]) rotate([0, 0, in_angle]) translate([-50, 0]) square(size=[100, 100]); translate([CUT_BASE+CUT_I_R, 0]) rotate([0, 0, -in_angle]) translate([-50, -100]) square(size=[100, 100]); } } } module tire() { b_i = BEVEL; bo_i = max(BEVEL, BEVEL_OUTER-THICKNESS*(2-sqrt(2))); difference() { hull() { translate([0, 0, BEVEL_OUTER]) cylinder(r=R, h=W-BEVEL_OUTER*2); cylinder(r=R-BEVEL_OUTER, h=W); } // center hole through all piece translate([0, 0, -0.5]) cylinder(r=R_I, h=W+1); // top hole hull() { translate([0, 0, W-B_P+BEVEL]) cylinder(r=R_I+B, h=B_P+1); translate([0, 0, W-B_P]) cylinder(r=R_I+B-BEVEL, h=B_P+1); } hull() { translate([0, 0, W-BEVEL]) cylinder(r=R_I+B, h=BEVEL); translate([0, 0, W]) cylinder(r=R_I+B+BEVEL, h=1); } // bottom hole hull() { translate([0, 0, -1]) cylinder(r=R_I+B-BEVEL, h=B_P+1); translate([0, 0, -1]) cylinder(r=R_I+B, h=B_P+1-BEVEL); } hull() { translate([0, 0, 0]) cylinder(r=R_I+B, h=BEVEL); translate([0, 0, -1]) cylinder(r=R_I+B+BEVEL, h=1); } // inside cut translate([0, 0, B_P+B_W]) cylinder(r=R-THICKNESS, h=W-(B_P+B_W)*2); difference() { hull() { translate([0, 0, BORDER_THICKNESS]) cylinder(r=R-THICKNESS-bo_i, h=W-BORDER_THICKNESS*2); translate([0, 0, BORDER_THICKNESS+bo_i]) cylinder(r=R-THICKNESS, h=W-BORDER_THICKNESS*2-bo_i*2); } cylinder(r=R_I+B+THICKNESS, h=W); translate([0, 0, W-BORDER_THICKNESS-b_i]) linear_extrude(height=b_i, scale=(R_I+B+THICKNESS+b_i)/(R_I+B+THICKNESS)) circle(r=R_I+B+THICKNESS); translate([0, 0, BORDER_THICKNESS]) linear_extrude(height=b_i, scale=(R_I+B+THICKNESS)/(R_I+B+THICKNESS+b_i)) circle(r=R_I+B+THICKNESS+b_i); } // lateral protector if (N_L > 0) for (i = [1 : N_L]) translate([0, 0, -PROT_L_WIDTH/2+i*W/(N_L+1)]) difference() { cylinder(r=R+1, h=PROT_L_WIDTH); translate([0, 0, -0.01]) linear_extrude(height=PROT_L_WIDTH/2+0.01, scale=(R-PROT_DEPTH)/(R+0.01)) circle(r=R+0.01); translate([0, 0, PROT_L_WIDTH]) rotate([180, 0, 0]) translate([0, 0, -0.01]) linear_extrude(height=PROT_L_WIDTH/2+0.01, scale=(R-PROT_DEPTH)/(R+0.01)) circle(r=R+0.01); translate([0, 0, -0.1]) cylinder(r=R-PROT_DEPTH, h=PROT_L_WIDTH+0.2); } // angular protector if (N_A > 0) for (i = [1 : N_A]) rotate([0, 0, 360/N_A*i]) protector_angular(); } } module protector_angular() { difference() { union() { translate([(W/2)/2, 0, W/2]) rotate([0, -45, 0]) cube(size=[PROT_A_WIDTH, R+4, sqrt((W/2)*(W/2)*2)]); translate([-(W/2)/2, 0, 0]) rotate([0, 45, 0]) cube(size=[PROT_A_WIDTH, R+4, PROT_A_WIDTH+sqrt((W/2)*(W/2)*2)]); } translate([0, 0, -0.5]) cylinder(r=R-PROT_DEPTH, h=W+1); } } module axle() { axle_gap = 1.95; union() { translate([-HOLE_RADIUS, -axle_gap/2, 0]) roundedRect(HOLE_RADIUS * 2, axle_gap, .2); translate([-axle_gap/2, -HOLE_RADIUS, 0]) roundedRect(axle_gap, HOLE_RADIUS * 2, .2); } } module roundedRect(x, y, radius) { hull() { translate([radius, radius, 0]) circle(r=radius); translate([x - radius, radius, 0]) circle(r=radius); translate([x - radius, y - radius, 0]) circle(r=radius); translate([radius, y - radius, 0]) circle(r=radius); } }