Skip to content

Instantly share code, notes, and snippets.

@thehans
Last active November 3, 2019 20:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thehans/2c96601af4e5c8c2d232e50252dd37b1 to your computer and use it in GitHub Desktop.
Save thehans/2c96601af4e5c8c2d232e50252dd37b1 to your computer and use it in GitHub Desktop.
Rounded cube implementation
use <functional.scad>
$fa = 0.1;
$fs = 0.1;
module rounded_cube(size, r=0, center=false) {
s = is_array(size) ? size : [size,size,size];
c = is_array(center) ?
[center.x ? 0 : s.x, center.y ? 0: s.y, center.z ? 0 : s.z]/2 :
(center ? 0 : s/2);
echo(c);
if (r > 0) {
translate(c) hull()
for(i=[0,1],j=[0,1],k=[0,1])
mirror([i,0,0]) mirror([0,j,0]) mirror([0,0,k])
translate([0.5*s.x-r,0.5*s.y-r,0.5*s.z-r])
rotate_extrude(angle=90)
polygon(concat(
[[0,0]],
arc(r=r, angle=90)
));
} else {
cube(size, center);
}
}
rounded_cube([4,6,8], r=1, center=false);
@NateTG
Copy link

NateTG commented Jan 30, 2018

Rounded cube has some particular symmetries... This ended up taking way too much effort, but it does make a very nice rounded cube.

use<FunctionalOpenSCAD/functional.scad>

function rounded_cube(size, r=0, center=false, fn=12)=
   (r>=size/2)?
      translate((center)?[0,0,0]:[size/2,size/2,size/2] ,sphere(r=size))
   :(r<=0)?
      cube(size=size,center=center)
   :
      let(steps=(fn>0)?ceil(fn/4):1,s=size/2-r,da=90/steps,count=4*(steps+1)*(steps+2)-1,
      rcube=[
          concat(
/* This section would have to get reworked a bit for an [x,y,z] cube... */
              [for (i=[0:steps]) for (rot=[0:-90:-270]) 
                  let(
                     z=r*(1-cos(da*i))-size/2,
                     l=r*sin(da*i),
                     dp=(i>0)?90/i:0,
                     m=[ [cos(rot),-sin(rot),0],
                         [sin(rot), cos(rot),0],
                         [       0,        0,1]]
                  )
                  for(j=[0:i])
                  [s+l*cos(dp*j),s+l*sin(dp*j),z]*m
              ],
              [for (i=[steps:-1:0]) for (rot=[0:-90:-270]) 
                  let(
                     z=r*(cos(da*i)-1)+size/2,
                     l=r*sin(da*i),
                     dp=(i>0)?90/i:0,
                     m=[ [cos(rot),-sin(rot),0],
                         [sin(rot), cos(rot),0],
                         [       0,        0,1]]
                  )
                  for(j=[0:i])
                  [s+l*cos(dp*j),s+l*sin(dp*j),z]*m
              ]
          ),
//Each side on the i'th row has i+1 points
//The rows start with 0,4,8,12 ... 2*i*(i+1)
//Each side on the ith row has i+1 points
             concat(
                [[0,1,2,3]],
                [for(i=[1:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3])
                   [
                      laststart+lpps*side,
                      laststart+(lpps*side+lppl-1)%lppl,
                      start+(pps*side+ppl-1)%ppl,
                      start+pps*side
                   ]
                ],
                [for(i=[1:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3]) for(j=[0:i-1])
                   [
                      laststart+lpps*side+j,
                      start+pps*side+j,
                      start+pps*side+1+j
                   ]
                ],
                (steps<2)?[]: [for(i=[2:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3]) for(j=[0:i-2])
                   [
                      laststart+lpps*side+j,
                      start+pps*side+j+1,
                      laststart+lpps*side+j+1
                   ]
                ],
//The steps'th row starts with 2*steps*(steps+1)
//The (steps+1)'th row starts with 2*steps*(steps+1)+4*steps
                [for(side=[0:3]) let(start=2*steps*(steps+1)+4*(steps+1),
                                      laststart=2*steps*(steps+1),
                                      ppl=4*(steps+1),lppl=4*(steps+1),
                                      pps=(steps+1),lpps=(steps+1)
                                      ) for(j=[0:steps])
                   
                   [
                      laststart+lpps*side+j,
                      laststart+(lpps*side+lppl-1+j)%lppl,
                      start+(pps*side+ppl-1+j)%ppl,
                      start+pps*side+j
                   ]
                ],
                [[count-0,count-1,count-2,count-3]],
                [for(i=[1:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3])
                   [
                      count-(laststart+lpps*side),
                      count-(laststart+(lpps*side+lppl-1)%lppl),
                      count-(start+(pps*side+ppl-1)%ppl),
                      count-(start+pps*side)
                   ]
                ],
                [for(i=[1:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3]) for(j=[0:i-1])
                   [
                      count-(laststart+lpps*side+j),
                      count-(start+pps*side+j),
                      count-(start+pps*side+1+j)
                   ]
                ],
                (steps<2)?[]: [for(i=[2:steps]) let(start=2*i*(i+1),laststart=2*i*(i-1),
                                      ppl=4*(i+1),lppl=4*i,
                                      pps=(i+1),lpps=i
                                      )
                   for(side=[0:3]) for(j=[0:i-2])
                   [
                      count-(laststart+lpps*side+j),
                      count-(start+pps*side+j+1),
                      count-(laststart+lpps*side+j+1)
                   ]
                ]
             )
      ]
   )
   center?rcube:translate([size/2,size/2,size/2],rcube)
;

rcube=(rounded_cube(1,1/6,fn=16));
poly3d(rcube);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment