// Flexi-spiral v1 © 2024 by Simon Hanin is licensed under CC BY-SA 4.0. To view a copy of this license, // visit https://creativecommons.org/licenses/by-sa/4.0/ $fn=100; //global resolution // Variable to modify the parameters of the object // Variables defining size and shape of the spiral diam = 30; // diameter of the spiral, in centimeter inter_spir = 10; // distance between two spires of one spiral rb_width = 0.6; //ruban width rb_height = 20; //ruban height res = 100; // resolution of the spiral in a range to 100 very good resolution // Variables defining size and shape of the supports double_supp = false; // boolean, if true : support with two holes supp_height=20; // height of the supports r_hole=2.55; // radius of holes for lego insertion inter_r=8; // inter radius for lego r_supp_end=3.6; // radius of the support at the ends of the spiral r_supp_center=5; // radius of the support ain the center of the spiral n_width = 0; // Variables defining the length of the transition region (thickening in the center and in the edges) thick_c = false; // if true : center of the spiral will be thicker thick_e = false; // if true : edges of the spiral will be thicker l_trans = 1.5; // length of trans region (aribtrary units, not mm) k_trans = 1/5; //trans factor // General variable bool_contour = true; bool_center = false; // to determine if object are centred around the axes or not s_trim = 1.1; // adjust to put edges supports "a fleur" du ruban // Variables used for calculation circles = floor(diam/inter_spir); // number of circles made by spiral ( floor is used to have an integer) angle_max = 2*PI*circles; // angle_max in radian angle_max_square = angle_max*angle_max; // the same squared b = inter_spir / 2 / PI; // variable used for tracing the spiral (distance between to rounds of one spiral) step = 100/res; // steps for spiral PI = 3.14159; n_trans = l_trans*res/4; // number of segment of spiral in trans module line(point1, point2, width = 1, cap_round = true) { // trace line of a defined width between two points // if cap_round = true, the angle will be smoothed with a circle angle = 90 - atan((point2[1] - point1[1]) / (point2[0] - point1[0])); offset_x = 0.5 * width * cos(angle); offset_y = 0.5 * width * sin(angle); offset1 = [-offset_x, offset_y]; offset2 = [offset_x, -offset_y]; if(cap_round) { translate(point1) circle(d = width, $fn = 24); translate(point2) circle(d = width, $fn = 24); } polygon(points=[ point1 + offset1, point2 + offset1, point2 + offset2, point1 + offset2 ]); } module polyline(points, width = 1) { // trace a serie of lines of a defined width between a serie of points module polyline_inner(points, index) { n_width = width; if(index < len(points)) { if(index < n_trans && thick_c) { // thicker zone of the spiral on the center n_width=width+(n_trans-index)*k_trans; line(points[index - 1], points[index], n_width); } if(index > len(points)-n_trans && thick_e ) { // thicker zone of the spiral on the edges n_width=width+(n_trans-len(points)+index)*k_trans; line(points[index - 1], points[index], n_width); } else { n_width = width; line(points[index - 1], points[index], n_width); } polyline_inner(points, index + 1); } } polyline_inner(points, 1); } points = [for(theta_carre = [0:step:angle_max_square]) // generating a serie of point in the shape of the spiral [b * sqrt(theta_carre) * cos(sqrt(theta_carre) * 57.2958), b * sqrt(theta_carre) * sin(sqrt(theta_carre) * 57.2958)] ]; difference() // difference between the first "union" that is all the solid parts and the second "union" that is the holes in the supports { union(){ // union of the spirals and the supports linear_extrude (rb_height, center=bool_center) { // extrudaction of the the three spirals polyline(points, rb_width); // tracing of the first spiral rotate([0,0,120]) polyline(points, rb_width); // second spiral rotated rotate([0,0,-120]) polyline(points, rb_width); // third spiral rotated } if(bool_contour){ // trace an outside ring difference() { cylinder(h = supp_height, r = diam, center = bool_center); cylinder(h = supp_height*4, r = diam-(1.2/20)*diam, center = true); } } cylinder(h = supp_height, r = r_supp_center, center = bool_center); // center support hull(){ // first edge support (can be simple or double) translate([b*angle_max+r_supp_end-s_trim,0,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); } } rotate([0,0,120]) { // second edge support (can be simple or double), rotated hull(){ translate([b*angle_max+r_supp_end-s_trim,0,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); } } } rotate([0,0,-120]) { // third edge support (can be simple or double), rotated hull(){ translate([b*angle_max+r_supp_end-s_trim,0,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height, r = r_supp_end, center = bool_center); } } }; } union() { // union of the holes cylinder(h = rb_height*4, r = r_hole, center = true); // hole of the center translate([b*angle_max+r_supp_end-s_trim,0,0]) // first edge hole cylinder(h = supp_height*4, r = r_hole, center = true); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height*4, r = r_hole, center = true); } rotate([0,0,120]) { // second edge hole translate([b*angle_max+r_supp_end-s_trim,0,0]) cylinder(h = supp_height*4, r = r_hole, center = true); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height*4, r = r_hole, center = true); } } rotate([0,0,-120]) { // third edge hole translate([b*angle_max+r_supp_end-s_trim,0,0]) cylinder(h = supp_height*4, r = r_hole, center = true); if(double_supp){ translate([b*angle_max+r_supp_end-s_trim,inter_r,0]) cylinder(h = supp_height*4, r = r_hole, center = true); } } } }