Assign
OpenSCAD's assign() statement will change the value of a variable for a sub-tree.a = 5; assign (a=20) { echo(a); }; echo(a);
for (i = [10:2:50]){ assign (angle = i*360/20, distance = i*10, r = i*2){ rotate(angle, [1, 0, 0]) translate([0, distance, 0]) sphere(r = r); echo (angle); } } echo (angle);
Functions
OpenSCAD also supports user-defined functions for code readability and for re-use. You can define a function that will return a value based on the parameters you specify.Syntax:
// Declaration of a function function name_of_my_func(param1,param2,...,paramn) =exp in function of myparameters;
my_d=20; //Declaration of function r_from_dia function r_from_dia(my_d) = my_d / 2; echo("Diameter ", my_d, " is radius ", r_from_dia(my_d)); //Declaration of function f function f(x)=3*x; cube([f(2),f(2),f(2)],center=true);
//Code derived from clothbot sphere_radius=10; pts_on_sphere=4; mySphere(); module mySphere(){ color(.1,.1,0.1) sphere(r=sphere_radius); map2PointsOnSphere(radius=sphere_radius,N=pts_on_sphere)sphere(.5,$fn=64); } function pi()=3.14159265358979323846; module map2PointsOnSphere(radius=1.0, N=3)assign(inc=pi()*(3-sqrt(5)),offset=2/N){ for(k=[0:N-1]){ assign(y=k*offset-1+(offset/2),r=sqrt(1-(k*offset-1+(offset/2))*(k*offset-1+(offset/2))),phi=k*inc){ translate([radius*cos(360*phi/(2*pi()))*r,radius*y,radius*sin(360*phi/(2*pi()))*r]) child(0); } } }
Add a render() statement in the mySphere() module and then you can quickly render multiple spheres:
//Code derived from clothbot sphere_radius=10; pts_on_sphere=4; for(i=[0:10]){ translate([i*20,0,0]) mySphere(); } mySphere(); module mySphere(){ render(){ color(.1,.1,0.1) sphere(r=sphere_radius); map2PointsOnSphere(radius=sphere_radius,N=pts_on_sphere)sphere(.5,$fn=64); } } function pi()=3.14159265358979323846; module map2PointsOnSphere(radius=1.0, N=3)assign(inc=pi()*(3-sqrt(5)),offset=2/N){ for(k=[0:N-1]){ assign(y=k*offset-1+(offset/2),r=sqrt(1-(k*offset-1+(offset/2))*(k*offset-1+(offset/2))),phi=k*inc){ translate([radius*cos(360*phi/(2*pi()))*r,radius*y,radius*sin(360*phi/(2*pi()))*r]) child(0); } } }
Here is another example:
//Code derived from William A Adam's OpenSCAD Revolids version 0.5 //======================================= // Constants //======================================= // The golden mean Cphi = 1.61803399; torus(innerRadius = 15, size=[10,6]); module PlaceQuad(quad) { PlaceTriangle([quad[0], quad[1], quad[2]]); PlaceTriangle([quad[0], quad[2], quad[3]]); } module PlaceTriangle(verts, reverse = 0) { if (reverse == true){ polyhedron(points=[verts[0], verts[1],verts[2]], triangles=[[0,1,2]]); } else { polyhedron(points=[verts[0], verts[1],verts[2]], triangles=[[2,1,0]]); } } module torus(innerRadius=1, size=[1,1]){ rotate([0, -90,0]) surface_rotation_torus(offset=[0,innerRadius], size = size, anglesteps = 40, sweepsteps = 40); } //=================================================== // Parametric Surface Functions //=================================================== // Point on the surface of a torus function param_torus(offset, size, theta, phi) = [offset[0]+size[0]*cos(theta), (offset[1]+size[1]*sin(theta))*cos(phi), (offset[1]+size[1]*sin(theta))*sin(phi)]; // x=(c+a*cos(v))*cos(u) // y=(c+a*cos(v))*sin(u) // z=a*sin(v) //=================================================== // Torus //=================================================== //Theta is used to represent an unknown angle. Theta represents an angle in degrees, but not in radians. module surface_rotation_torus(offset=[0,1], size=[0.5,0.5], anglesteps = 12, sweepsteps = 12){ sstepangle = 360 / sweepsteps; // phi astepangle = 360/ anglesteps; // theta // Angle 0 <= phi <= 2pi for (sstep = [0:sweepsteps-1]){ // Angle 0 <= theta <= 2pi for(astep = [0:anglesteps-1]){ assign(p0 = param_torus(offset=offset, size = size, theta = astep*astepangle, phi = sstep*sstepangle)) assign(p1 = param_torus(offset=offset, size=size, theta = (astep+1)*astepangle, phi = sstep*sstepangle)) assign(p2 = param_torus(offset=offset, size=size, theta = astep*astepangle, phi = (sstep+1)*sstepangle)) assign(p3 = param_torus(offset=offset, size=size, theta = (astep+1)*astepangle, phi = (sstep+1)*sstepangle)) { //DisplayQuadFrame([p0, p1, p3, p2]); PlaceQuad([p0, p1, p3, p2]); } } } }