diff --git a/Triangles.scad b/Triangles.scad new file mode 100644 index 0000000..2b56f35 --- /dev/null +++ b/Triangles.scad @@ -0,0 +1,215 @@ +/* +Triangles.scad + Author: Tim Koopman + https://github.com/tkoopman/Delta-Diamond/blob/master/OpenSCAD/Triangles.scad + + angleCA + /|\ + a / H \ c + / | \ + angleAB ------- angleBC + b + +Standard Parameters + center: true/false + If true same as centerXYZ = [true, true, true] + + centerXYZ: Vector of 3 true/false values [CenterX, CenterY, CenterZ] + center must be left undef + + height: The 3D height of the Triangle. Ignored if heights defined + + heights: Vector of 3 height values heights @ [angleAB, angleBC, angleCA] + If CenterZ is true each height will be centered individually, this means + the shape will be different depending on CenterZ. Most times you will want + CenterZ to be true to get the shape most people want. +*/ + +/* +Triangle + a: Length of side a + b: Length of side b + angle: angle at point angleAB +*/ +module Triangle( + a, b, angle, height=1, heights=undef, + center=undef, centerXYZ=[false,false,false]) +{ + // Calculate Heights at each point + heightAB = ((heights==undef) ? height : heights[0])/2; + heightBC = ((heights==undef) ? height : heights[1])/2; + heightCA = ((heights==undef) ? height : heights[2])/2; + centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCA); + + // Calculate Offsets for centering + offsetX = (center || (center==undef && centerXYZ[0]))?((cos(angle)*a)+b)/3:0; + offsetY = (center || (center==undef && centerXYZ[1]))?(sin(angle)*a)/3:0; + + pointAB1 = [-offsetX,-offsetY, centerZ-heightAB]; + pointAB2 = [-offsetX,-offsetY, centerZ+heightAB]; + pointBC1 = [b-offsetX,-offsetY, centerZ-heightBC]; + pointBC2 = [b-offsetX,-offsetY, centerZ+heightBC]; + pointCA1 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ-heightCA]; + pointCA2 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ+heightCA]; + + polyhedron( + points=[ pointAB1, pointBC1, pointCA1, + pointAB2, pointBC2, pointCA2 ], + triangles=[ + [0, 1, 2], + [3, 5, 4], + [0, 3, 1], + [1, 3, 4], + [1, 4, 2], + [2, 4, 5], + [2, 5, 0], + [0, 5, 3] ] ); +} + +/* +Isosceles Triangle + Exactly 2 of the following paramaters must be defined. + If all 3 defined H will be ignored. + b: length of side b + angle: angle at points angleAB & angleBC. +*/ +module Isosceles_Triangle( + b, angle, H=undef, height=1, heights=undef, + center=undef, centerXYZ=[true, false, false]) +{ + valid = (angle!=undef)?((angle < 90) && (b!=undef||H!=undef)) : (b!=undef&&H!=undef); + ANGLE = (angle!=undef) ? angle : atan(H / (b/2)); + a = (b==undef)?(H/sin((180-(angle*2))/2)) : + (b / cos(ANGLE))/2; + B = (b==undef)? (cos(angle)*a)*2:b; + if (valid) + { + Triangle(a=a, b=B, angle=ANGLE, height=height, heights=heights, + center=center, centerXYZ=centerXYZ); + } else { + echo("Invalid Isosceles_Triangle. Must specify any 2 of b, angle and H, and if angle used angle must be less than 90"); + } +} + +/* +Right Angled Triangle + Create a Right Angled Triangle where the hypotenuse will be calculated. + + |\ + a| \ + | \ + ---- + b + a: length of side a + b: length of side b +*/ +module Right_Angled_Triangle( + a, b, height=1, heights=undef, + center=undef, centerXYZ=[false, false, false]) +{ + Triangle(a=a, b=b, angle=90, height=height, heights=heights, + center=center, centerXYZ=centerXYZ); +} + +/* +Wedge + Is same as Right Angled Triangle with 2 different heights, and rotated. + Good for creating support structures. +*/ +module Wedge(a, b, w1, w2) +{ + rotate([90,0,0]) + Right_Angled_Triangle(a, b, heights=[w1, w2, w1], centerXYZ=[false, false, true]); +} + +/* +Equilateral Triangle + Create a Equilateral Triangle. + + l: Length of all sides (a, b & c) + H: Triangle size will be based on the this 2D height + When using H, l is ignored. +*/ +module Equilateral_Triangle( + l=10, H=undef, height=1, heights=undef, + center=undef, centerXYZ=[true,false,false]) +{ + L = (H==undef)?l:H/sin(60); + Triangle(a=L,b=L,angle=60,height=height, heights=heights, + center=center, centerXYZ=centerXYZ); +} + +/* +Trapezoid + Create a Basic Trapezoid (Based on Isosceles_Triangle) + + d + /----\ + / | \ + a / H \ c + / | \ + angle ------------ angle + b + + b: Length of side b + angle: Angle at points angleAB & angleBC + H: The 2D height at which the triangle should be cut to create the trapezoid + heights: If vector of size 3 (Standard for triangles) both cd & da will be the same height, if vector have 4 values [ab,bc,cd,da] than each point can have different heights. +*/ +module Trapezoid( + b, angle=60, H, height=1, heights=undef, + center=undef, centerXYZ=[true,false,false]) +{ + validAngle = (angle < 90); + adX = H / tan(angle); + + // Calculate Heights at each point + heightAB = ((heights==undef) ? height : heights[0])/2; + heightBC = ((heights==undef) ? height : heights[1])/2; + heightCD = ((heights==undef) ? height : heights[2])/2; + heightDA = ((heights==undef) ? height : ((len(heights) > 3)?heights[3]:heights[2]))/2; + + // Centers + centerX = (center || (center==undef && centerXYZ[0]))?0:b/2; + centerY = (center || (center==undef && centerXYZ[1]))?0:H/2; + centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCD,heightDA); + + // Points + y = H/2; + bx = b/2; + dx = (b-(adX*2))/2; + + pointAB1 = [centerX-bx, centerY-y, centerZ-heightAB]; + pointAB2 = [centerX-bx, centerY-y, centerZ+heightAB]; + pointBC1 = [centerX+bx, centerY-y, centerZ-heightBC]; + pointBC2 = [centerX+bx, centerY-y, centerZ+heightBC]; + pointCD1 = [centerX+dx, centerY+y, centerZ-heightCD]; + pointCD2 = [centerX+dx, centerY+y, centerZ+heightCD]; + pointDA1 = [centerX-dx, centerY+y, centerZ-heightDA]; + pointDA2 = [centerX-dx, centerY+y, centerZ+heightDA]; + + validH = (adX < b/2); + + if (validAngle && validH) + { + polyhedron( + points=[ pointAB1, pointBC1, pointCD1, pointDA1, + pointAB2, pointBC2, pointCD2, pointDA2 ], + triangles=[ + [0, 1, 2], + [0, 2, 3], + [4, 6, 5], + [4, 7, 6], + [0, 4, 1], + [1, 4, 5], + [1, 5, 2], + [2, 5, 6], + [2, 6, 3], + [3, 6, 7], + [3, 7, 0], + [0, 7, 4] ] ); + } else { + if (!validAngle) echo("Trapezoid invalid, angle must be less than 90"); + else echo("Trapezoid invalid, H is larger than triangle"); + } +} \ No newline at end of file diff --git a/common.scad b/common.scad new file mode 100644 index 0000000..e7f6b19 --- /dev/null +++ b/common.scad @@ -0,0 +1,214 @@ +IN = 25.4; +MM = 1; + +function R(d) = d / 2.0; + +function IN2MM(in) = in * IN; + +function MM2IN(mm) = mm / IN; + +module hex (diag = 10, h = 1) { + cylinder(r = diag / 2, h = h, center = true, $fn = 6); +} + +module tube(o = 1, i = 0, h = 1, center = false, $fn = 12) { + $fn = $fn; + union () { + difference () { + cylinder(r = o, h = h, center = center); + cylinder(r = i, h = h, center = center); + } + } +} + +module m3_nut (H = 5) { + cylinder(r=R(6.6), h=H, center=true, $fn=6); +} + +module rounded_cube (cube_arr = [1, 1, 1], d = 0, center = false) { + off_x = 0; + off_y = 0; + r = d/2; + union () { + cube([cube_arr[0] - d, cube_arr[1], cube_arr[2]], center = center); + cube([cube_arr[0], cube_arr[1] - d, cube_arr[2]], center = center); + translate ([1 * (cube_arr[0] / 2) - r , 1 * (cube_arr[1] / 2)- r, 0]) cylinder(r = r, h = cube_arr[2], center = center); + translate ([-1 * (cube_arr[0] / 2) + r, -1 * (cube_arr[1] / 2) + r, 0]) cylinder(r = r, h = cube_arr[2], center = center); + translate ([1 * (cube_arr[0] / 2) - r, -1 * (cube_arr[1] / 2) + r, 0]) cylinder(r = r, h = cube_arr[2], center = center); + translate ([-1 * (cube_arr[0] / 2) + r, 1 * (cube_arr[1] / 2)- r, 0]) cylinder(r = r, h = cube_arr[2], center = center); + } +} + +module c_battery () { + /* C Cell battery, 26.1 × 50 */ + x = 26.1; + x_fuzz = .3; + y = 50; + y_fuzz = 2; + cylinder(r = (x + x_fuzz) / 2, h = y + y_fuzz, center = true); +} + +module sub_c_battery () { + /* Sub C Cell battery, 22.2 × 42.9 */ + x = 22.2; + x_fuzz = .3; + y = 42.9; + y_fuzz = 2; + cylinder(r = (x + x_fuzz) / 2, h = y + y_fuzz, center = true); +} + +module hex (r = 1, h = 1, center = false) { + cylinder(r = r, h = h, center = center, $fn = 6); +} + +module cone_45 (d = 1, center = false) { + cylinder(r1 = d/2, r2 = 0, h = d, center = center); +} + +module decoys (d = 10, z = 0, number = 4, cube_size = 4, debug = false) { + for (i = [0: number]) { + rotate([0, 0, (360/number) * i]) translate([d, 0, z]) cube([cube_size, cube_size, cube_size], center = true); + if (debug && i == 0) { + rotate([0, 0, (360/number) * i]) translate([d, 0, z]) cube([cube_size * 5, cube_size* 5, cube_size], center = true); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +// Paraboloid module for OpenScad +// +// Copyright (C) 2013 Lochner, Juergen +// http://www.thingiverse.com/Ablapo/designs +// +// This program is free software. It is +// licensed under the Attribution - Creative Commons license. +// http://creativecommons.org/licenses/by/3.0/ +////////////////////////////////////////////////////////////////////////////////////////////// + +module paraboloid (y=10, f=5, rfa=0, fc=1, detail=44){ + // y = height of paraboloid + // f = focus distance + // fc : 1 = center paraboloid in focus point(x=0, y=f); 0 = center paraboloid on top (x=0, y=0) + // rfa = radius of the focus area : 0 = point focus + // detail = $fn of cone + + hi = (y+2*f)/sqrt(2); // height and radius of the cone -> alpha = 45° -> sin(45°)=1/sqrt(2) + x =2*f*sqrt(y/f); // x = half size of parabola + + translate([0,0,-f*fc]) // center on focus + rotate_extrude(convexity = 10,$fn=detail ) // extrude paraboild + translate([rfa,0,0]) // translate for fokus area + difference(){ + union(){ // adding square for focal area + projection(cut = true) // reduce from 3D cone to 2D parabola + translate([0,0,f*2]) rotate([45,0,0]) // rotate cone 45° and translate for cutting + translate([0,0,-hi/2])cylinder(h= hi, r1=hi, r2=0, center=true, $fn=detail); // center cone on tip + translate([-(rfa+x ),0]) square ([rfa+x , y ]); // focal area square + } + translate([-(2*rfa+x ), -1/2]) square ([rfa+x ,y +1] ); // cut of half at rotation center + } +} + +/* +// Height of trapazoid +height = 19; + +// Width of top cube +top_x = 30; +// Length of top cube +top_y = 34; + +// Width of bottom cube +bottom_x = 45; +// Length of bottom cube +bottom_y = 65; + +wall_thickness = 2; +*/ +module trap_cube(height = 19, top_x = 30, top_y = 34, bottom_x = 45, bottom_y = 65, wall_thickness = 2) { + difference(){ + hull(){ + translate([0,0,height]) + cube([top_x, top_y, 0.1], center=true); + cube([bottom_x, bottom_y, 0.1], center=true); + } + + hull(){ + translate([0,0,height]) + cube([top_x - wall_thickness, top_y - wall_thickness, 0.1], center=true); + cube([bottom_x - wall_thickness, bottom_y - wall_thickness, 0.1], center=true); + } + } +} + +module NEMA17_motor_shaft (L = 22.75) { + //shaft + difference () { + cylinder(r = R(5), h = L, center = true, $fn = 30); + translate([0, 4.5, 4.7]) cube([5, 5, L+1], center = true); + } +} + +//NEMA17 Stepper +module NEMA17 ( H = 33 ) { //alt = 47.5 + difference () { + cube([42, 42, H], center = true); + for (i = [0 : 3]) { + rotate([0, 0, (i * 90) + 45]) translate([29.7, 0, 0]) cube([5.5, 5.5, H + 1], center = true); + } + translate([31/2, 31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30); + translate([-31/2, 31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30); + translate([31/2, -31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30); + translate([-31/2, -31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30); + } + //pad + translate([0, 0, (H/2) + (1.9/2)]) { + cylinder(r = R(22), h = 1.9, center = true, $fn = 100); + } + //shaft + translate([0, 0, (H/2) + (22.75/2)]) { + NEMA17_motor_shaft(); + } +} + +module geared_motor_shaft () { + MOTOR_SHAFT_D = 6; + MOTOR_SHAFT_H = 16; + MOTOR_SHAFT_HOBBLE = 1; + difference () { + cylinder(r = R(MOTOR_SHAFT_D), h = MOTOR_SHAFT_H, center = true, $fn = 60); + translate([MOTOR_SHAFT_D - MOTOR_SHAFT_HOBBLE, 0, 0]) cube([MOTOR_SHAFT_D, MOTOR_SHAFT_D, MOTOR_SHAFT_H + 1], center = true); + } +} + +//Geartisan Worm Gear Motor - JSX40-370 +module geared_motor () { + MOTOR_MOUNT_X = 32.5; + MOTOR_MOUNT_Y = 17.5; + + module motor_mount_pad (D, Z) { + difference () { + cylinder(r = R(D), h = Z, center = true, $fn = 40); + //bolt void + cylinder(r = R(2.5), h = Z + 1, center = true, $fn = 40); + } + } + + module motor_mounts () { + Z = 1.5; + D = 7.5; + + translate([MOTOR_MOUNT_X / 2, MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z); + translate([-MOTOR_MOUNT_X / 2, MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z); + translate([MOTOR_MOUNT_X / 2, -MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z); + translate([-MOTOR_MOUNT_X / 2, -MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z); + } + + cube([46, 32, 21], center = true); + translate([(46 / 2) + (30 / 2), 0, 1.5]) rotate([0, 90, 0]) cylinder(r = 24 / 2, h = 30, center = true, $fn = 80); + translate([-(46 / 2) + 14.5, 0, -18.5]) rotate([0, 0, 90]) geared_motor_shaft(); + //pad + translate([-(46 / 2) + 14.5, 0, -(1 / 2) - 10.5]) cylinder(r = 13 / 2, h = 1, center = true, $fn = 60); + //mount pads + translate([-0.5, 0, -(1.5 / 2) - 10.5]) motor_mounts(); +} \ No newline at end of file diff --git a/spiral.scad b/spiral.scad new file mode 100644 index 0000000..b69be95 --- /dev/null +++ b/spiral.scad @@ -0,0 +1,150 @@ +//Spiral Notes +//------------------------------------------------------------------- +//Height = center to center height of the end spheres which form the spirals. Ends will need to be flattened by the user as desired. Actual height of the rendering is Height+2*baseRadius +//Radius = the maximum distance from the axis of the spiral (the z axis) to the center of the sphere(s) forming the spiral +//baseRadius = cross sectional radius of the spiral +//frequency = the number of complete revolutions about the axis made by the spiral, whole numbers will result in spirals whose tops end directly above their bases +//resolution = integer number of spheres, not to be confused with $fn. The greater the number of spheres, the smoother the spiral will be (also longer render times!). Recommended that this number be 8*frequency or greater. +//numSpirals = integer number of spirals used in the spiralMulti modules spaced evenly around the axis (3 spirals are spaced 120 degrees apart, 4 spirals: 90 degrees apart, etc.) + +//Instructions +//------------------------------------------------------------------ +//1. Place spiral.scad in the "libraries" folder of your openscad installation. Find the libraries folder by File -> Show Library Folder... +//2. Then create a new or open one of your existing scad files and include spiral.scad with the following code: +//use; +//3. Then call the modules in your files with code similar to the following: +//spiral(20,20,3,1,25); +//spiralCone(20,20,3,1,25); +//spiralEllipse(20,20,3,1,25); +//spiralMulti(20,20,3,1,25,3); +//spiralMultiCone(20,20,3,1,25,3); +//spiralMultiEllipse(40,60,3,1,32,3); + +//------------------------------------------------------------- +//simple spiral +module spiral (height = 20, Radius = 20, baseRadius = 3, frequency = 1, resolution = 25, $fn=50) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } +} + +//cone spiral +module spiralCone(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25, $fn=50) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius-(i-1)*Radius/resolution,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius-i*Radius/resolution,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } +} + +//ellipse spiral +module spiralEllipse(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25, $fn=50) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius*sqrt(1-(i/(resolution-1)*(i/(resolution-1)))),0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius*sqrt(1-((i+1)/(resolution-1)*((i+1)/(resolution-1)))),0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } +} + +// Multiple spirals arranged radially around the axis +module spiralMulti(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { + shiftAngle=360/numSpirals; + for(total=[0:numSpirals-1]) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } + } +} + +// Multiple spirals arranged radially around the axis tapering in towards the axis +module spiralMultiCone(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { + shiftAngle=360/numSpirals; + for(total=[0:numSpirals-1]) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius-(i-1)*Radius/resolution,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius-i*Radius/resolution,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } + } +} + +//multiple ellipse spiral +module spiralMultiEllipse(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { + shiftAngle=360/numSpirals; + for(total=[0:numSpirals-1]) { + union(){ + translate ([0,0,-(height/2)]) { + for(i=[0:resolution-2]){ + hull(){ + rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius*sqrt(1-(i/(resolution-1)*(i/(resolution-1)))),0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); + rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius*sqrt(1-((i+1)/(resolution-1)*((i+1)/(resolution-1)))),0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); + } + } + } + } + } +} + +//Alternate approach to spiral generation + +module spiral_alt (START_D = 10, SPACING = 5, THICKNESS = 2, H = 10, SPIRALS = 39) { + $fn = 60; + START_R = START_D / 2; + union () { + for (i = [0 : $fn]) { + rotate ([0, 0, i * (360 / $fn)]) { + for (x = [0: (SPIRALS - 1)]) { + spiral_facet(i, x, START_R, SPACING, THICKNESS, H); + } + } + } + } +} + +module spiral_facet (i, x, START_R, SPACING, W, H) { + STEP_SIZE = ((SPACING + W) / $fn); + + STEP_OFFSET = i * STEP_SIZE; + SPIRAL_START_OFFSET = (x * (SPACING + W)); + + ACTUAL_R = START_R + SPIRAL_START_OFFSET + STEP_OFFSET; + L = 2 * (ACTUAL_R * tan((360 / $fn) / 2)); + ANGLE = -atan( STEP_SIZE / (L / 2) ) / 2; + OFFSET = START_R - (W / 2) + SPIRAL_START_OFFSET + STEP_OFFSET; + + translate ([OFFSET, 0, - H / 2]) { + rotate ([0, 0, ANGLE]) { + cube([W, L, H], center=true); + //TODO: cutouts + } + } +} \ No newline at end of file diff --git a/trap_cube.scad b/trap_cube.scad deleted file mode 100644 index 9675b10..0000000 --- a/trap_cube.scad +++ /dev/null @@ -1,31 +0,0 @@ -/* -// Height of trapazoid -height = 19; - -// Width of top cube -top_x = 30; -// Length of top cube -top_y = 34; - -// Width of bottom cube -bottom_x = 45; -// Length of bottom cube -bottom_y = 65; - -wall_thickness = 2; -*/ -module trap_cube(height = 19, top_x = 30, top_y = 34, bottom_x = 45, bottom_y = 65, wall_thickness = 2) { - difference(){ - hull(){ - translate([0,0,height]) - cube([top_x, top_y, 0.1], center=true); - cube([bottom_x, bottom_y, 0.1], center=true); - } - - hull(){ - translate([0,0,height]) - cube([top_x - wall_thickness, top_y - wall_thickness, 0.1], center=true); - cube([bottom_x - wall_thickness, bottom_y - wall_thickness, 0.1], center=true); - } - } -} \ No newline at end of file