From 9583e8138ec15375774e25471a2944a2d9a99a53 Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Tue, 2 Apr 2024 17:16:51 -0400 Subject: [PATCH] Initial commit --- planter.scad | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 planter.scad diff --git a/planter.scad b/planter.scad new file mode 100644 index 0000000..772940c --- /dev/null +++ b/planter.scad @@ -0,0 +1,109 @@ +// Diameter of the inside cylinder +diameter = 62; +// Height of the inside cyliner +height = 40; +// Number of cuts / ridges around the planter +cuts = 20; +// Depth of the cuts / ridges around the planter +cut_depth = 3; +// Thickness of the wall of the planter +thickness = 3; +// Roundness of the bottom, where 0 is a straight flat bottom, and 100 is a sphere bottom +bottom_roundness_percent = 85; +// Optional wall mount plate, 0 is no plate and 100 makes the planter a half-circle +wall_mount_percent = 30; + +module _end_of_customizer() {} + +$fn = $preview ? 20 : 60; + +// The bottom half of a sphere +module half_sphere(d) { + difference() { + sphere(d = d); + + translate([-d/2 - 1, -d/2 - 1, 0]) + cube([d + 2, d + 2, d + 1]); + } +} + +// The body, a full cylinder with ridges +// +// Its diameter is calculated from `diameter` (for the hollow inside), `thickness`, and `cut_depth`. +module body(h, fn = 20) { + outer_diameter = diameter + thickness * 2; + + function diam(x) = 1 + cut_depth / outer_diameter * 2 * sin(x * 180) ^ 3; + + for(cut = [0:cuts - 1]) { + for(i = [0:fn - 1]) { + angle1 = 360 / cuts / fn * (cut * fn + i); + angle2 = 360 / cuts / fn * (cut * fn + i + 1); + + vary1 = diam(i / fn); + vary2 = diam((i + 1) / fn); + + linear_extrude(h) + polygon([ + [0, 0], + [vary1 * outer_diameter / 2 * cos(angle1), + vary1 * outer_diameter / 2 * sin(angle1)], + [vary2 * outer_diameter / 2 * cos(angle2), + vary2 * outer_diameter / 2 * sin(angle2)], + ]); + } + } +} + +// The bottom part of the vase, which is sphere-like with ridges and a flat bottom +// +// The bottom is controlled by `bottom_roundness_percent` (0 = no roundness at all, 100 = no flat bottom at all) +module bottom() { + full_diameter = (diameter + thickness * 2) + cut_depth * 2; + + intersection() { + translate([0, 0, -full_diameter / 2 * bottom_roundness_percent / 100]) + body(full_diameter / 2 * bottom_roundness_percent / 100); + + half_sphere(d = full_diameter); + } +} + +// The planter +// +// body with cylinder cut out (`diameter`) and bottom part +module planter() { + difference() { + body(height); + + translate([0, 0, -1]) + cylinder(d = diameter, h = height + 2); + + scale([1, 1, 0.2]) + half_sphere(d = diameter); + } + + bottom(); +} + +// Planter with optional wall mount plate +// +// If `wall_mount_percent` is 0, no plate, if 100, the planter is a half circle +if(wall_mount_percent > 0) { + full_diameter = (diameter + thickness * 2) + cut_depth * 2; + + wall_x = full_diameter / 2 * (1 - wall_mount_percent / 100); + + wall_depth = full_diameter * sqrt(1 - (1 - wall_mount_percent / 100)^2); + + difference() { + planter(); + translate([-wall_x - full_diameter, -wall_depth / 2, -full_diameter - 1]) + cube([full_diameter, wall_depth, height + full_diameter + 2]); + } + + translate([-wall_x, -wall_depth / 2, 0]) + cube([thickness, wall_depth, height]); +} else { + planter(); +}