Calculates the volume of a point-face triangel mesh.
points=[[0,0,0], ... ]
faces=[[0,1,2],[0,2,3],[4,6,5],[4,7,6],
[0,4,5],[1,0,5],[1,5,6],[2,1,6],
[2,6,7],[2,7,3],[3,7,4],[3,0,4]]
function meshVolume(points,faces)=
let(
sum=[for(faces)-1]*[for(f=faces)
SignedVolumeOfTriangle(points[f[0]],points[f[1]],points[f[2]])])
sum
;
function SignedVolumeOfTriangle( p1, p2, p3) =
let(
v321 = p3.x*p2.y*p1.z,
v231 = p2.x*p3.y*p1.z,
v312 = p3.x*p1.y*p2.z,
v132 = p1.x*p3.y*p2.z,
v213 = p2.x*p1.y*p3.z,
v123 = p1.x*p2.y*p3.z
) (1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123);
Saturday, December 19, 2020
Volume of mesh
Saturday, December 5, 2020
Marching Cubes for OpenSCAD function literals
Marching Cubes for OpenSCAD function literals
Usage: sdMarchingCubes( sdScene = f ( [ x , y , z ] ) , sub = subdivisions )
Usage: sdMarchingCubes( sdScene = f ( [ x , y , z ] ) , sub = subdivisions )
// MarchingCubes for function literals v0.1 - Torleif Ceder 2020
// With function literals of bounded closed isosufaces
// in the form f([x,y,z])
// Signed distans function can be output as polyhedron.
// Quality and problens is as expected with MarchingCubes
////////////// DEMO ////////////////////////////////////////////////////////////
sdScene = function(p) min(
max(abs(p.x)-6.5,abs(p.y+3)-4.5,abs(p.z*.7-p.x*.7)-0.5) ,
max(abs(p.x)-6.5,abs(p.y-3)-4.5,abs(p.z*.7+p.x*.7)-0.5) ,
norm(p )-5.5 ); // function literal of our Signed distance function
// learn more at https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
sdDemo= true;
if(sdDemo) sdMarchingCubes(sdScene,sub=5);
/////////////////////////////////////////////////////////////////////////////////////
//sdMC is a Octree subdivision MarchingCubes with direct gemoetry output
module sdMarchingCubes(sdScene, cell=[],sub){
assert(!is_undef(sub)&&!is_undef(sdScene),
" sdMarchingCubes() Usage: sdMarchingCubes( sdScene = f([ x , y , z ]) , sub = subdivisions ) ")
if (cell==[]) sdMarchingCubes(sdScene,autoBound(sdScene,cubic=true,pad=0.5 ),sub); else{
O = cell[0]; S = cell[1]; C = (O + S) / 2; D = S - O;
maxD = max( abs (D.x),abs (D.y),abs (D.z));
if (abs(sdScene(C))<=maxD )//ignore completly empty or full cells
{ p=vertFromCell (cell) ;
evals=[for(p=p)eval(p,sdScene)];
case=bitMaskToValue(evals);
if (sub>0){ // subdivide cell into eight smaller if subdivisions left
pxxx=[O+[0,0,0],O+[D.x,0,0],O+[0,D.y,0],O+[0,D.y,D.z],
O+[0,0,D.z],O+[D.x,D.y,0],O+[D.x,0,D.z],O+[D.x,D.y,D.z]];
for(i=[0:7]){sdMarchingCubes(sdScene,([C,pxxx[i]]),sub-1 ); } }
else { // Make polyhedron of this cell
faces=(CASES()[ (case)]); // Use MC 256 table to find conectivity
edgepoints=[for(e=EDGES()) // intersecion points along edges
lerp(p[e[0]],p[e[1]], findZero(evals[e[0]],evals[e[1]]) )];
polyhedron(edgepoints,faces); } } } } // Showtime
/////////////////////////////////////////////////////////////////////////////////////
// tiny utils fuctions
function vertFromCell(cell)= [for(c=VERTICES())[cell[c.x].x,cell[c.y].y,cell[c.z].z ]];
function findZero(e1,e2)=sign(e1)==sign(e2)||e1+e2==0?0.5: (abs(e1)/(abs(e1)+abs(e2)) );
function lerp(start,end,bias) = (end * bias + start * (1 - bias));
function un(v) = v / max(norm(v), 0.000001) * 1; // div by zero safe unit normal
function clamp(a,b=0,c=1) = min(max(a,min(b,c)),max(b,c));
/////////////////////////////////////////////////////////////////////////////////////
function eval(p,sdScene)=sdScene(p);// For legacy
//////////////////////////////////////////////////////////////////////////////////////
function evalnorm(q,sdScene) =
let (tiny = -1e16, e = eval(q,sdScene))[
eval([q.x + tiny,q.y,q.z],sdScene) - eval([q.x - tiny,q.y,q.z],sdScene),
eval([q.x,q.y + tiny,q.z],sdScene) - eval([q.x,q.y - tiny,q.z],sdScene),
eval([q.x,q.y,q.z + tiny],sdScene) - eval([q.x,q.y,q.z - tiny],sdScene), e];
//////////////////////////////////////////////////////////////////////////////////////
// Takes a vector. Any number >0 is 1 rest 0. use binary to build a number
function bitMaskToValue(v=[0])= is_undef(v[0])?0:
[for(j=v)1]* [for (i=[0:max(0,len(v)-1)]) max(0,sign(v[i]))*pow(2,i)] ;
//////////////////////////////////////////////////////////////////////////////////////
// arrange bundary box from sloppy to proper orientation of minor corner and major corner
function bflip(a,b) = is_undef(b)&&len(a)==2?bflip(a[0],a[1]):[ [min(a.x,b.x),min(a.y,b.y),min(a.z,b.z)], [max(a.x,b.x),max(a.y,b.y),max(a.z,b.z)] ];
//////////////////////////////////////////////////////////////////////////////////////
function autoBound(sdScene,cubic = (false),pad = 1) = let (
up = findBound([0,0,1],sdScene), down = -findBound([0,0,-1],sdScene),
north = findBound([0,1,0],sdScene), south = -findBound([ 0,-1,0],sdScene),
west = findBound([1,0,0],sdScene), east = -findBound([- 1,0,0],sdScene),
esd = min(east,south,down),wnu = max(west,north,up) )
cubic == true ?
let(scenecenter=[(east+west)/2,(south+north)/2,(up+down)/2],
scenemax=max(abs(east-west),abs(south-north),abs(up+down))/2,
d = [scenemax,scenemax,scenemax] )
[scenecenter - (d * (1+pad)),scenecenter + d * (1+pad)] :
let (d = [west,north,up ] - [east,south,down])
[[east,south,down ] - d * pad,[west,north,up] + d * pad];
//////////////////////////////////////////////////////////////////////////////////////
function findBound(vec,sdScene) =
let (VeryFar = 10e6, p1 = vec * VeryFar, p2 = p1 + un(vec ),
e1 = abs(eval(p1,sdScene)), e2 = abs(eval(p2,sdScene)),
scale = abs(e2 - e1),// Account for non unit_for_unit field.
corrected = (e1 / scale), distance = VeryFar - e1/scale //distance= VeryFar-corrected
)/*[p1,p2,e1,e2,scale,corrected,distance ]*/ distance ;
//////////////////////////////////////////////////////////////////////////////////////
////// MC Tables by BorisTheBrav /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
function VERTICES ()= [
[0,0,0], [1,0,0],
[1,1,0], [0,1,0],
[0,0,1], [1,0,1],
[1,1,1], [0,1,1], ];
//# BorisTheBrave convention for the edges
function EDGES() = [
[0,1], [1,2], [2,3],
[3,0], [4,5], [5,6],
[6,7], [7,4], [0,4],
[1,5], [2,6], [3,7] ];
//BorisTheBrave # Table driven approach to the 256 combinations. Pro-tip,don't write this by hand,copy mine!
//BorisTheBrave# See marching_cubes_gen.py for how I generated these.
//BorisTheBrave# Each index is the bitwise representation of what is solid.
//BorisTheBrave# Each value is a list of triples indicating what edges are used for that triangle
//BorisTheBrave# (Recall each edge of the cell may become a vertex in the output boundary)
function CASES() = [[],[[8,0,3]],[[1,0,9]],[[8,1,3],[8,9,1]],[[10,2,1]],[[8,0,3],[1,10,2]],[[9,2,0],[9,10,2]],[[3,8,2],[2,8,10],[10,8,9]],[[3,2,11]],[[0,2,8],[2,11,8]],[[1,0,9],[2,11,3]],[[2,9,1],[11,9,2],[8,9,11]],[[3,10,11],[3,1,10]],[[1,10,0],[0,10,8],[8,10,11]],[[0,11,3],[9,11,0],[10,11,9]],[[8,9,11],[11,9,10]],[[7,4,8]],[[3,7,0],[7,4,0]],[[7,4,8],[9,1,0]],[[9,1,4],[4,1,7],[7,1,3]],[[7,4,8],[2,1,10]],[[4,3,7],[4,0,3],[2,1,10]],[[2,0,10],[0,9,10],[7,4,8]],[[9,10,4],[4,10,3],[3,10,2],[4,3,7]],[[4,8,7],[3,2,11]],[[7,4,11],[11,4,2],[2,4,0]],[[1,0,9],[2,11,3],[8,7,4]],[[2,11,1],[1,11,9],[9,11,7],[9,7,4]],[[10,11,1],[11,3,1],[4,8,7]],[[4,0,7],[7,0,10],[0,1,10],[7,10,11]],[[7,4,8],[0,11,3],[9,11,0],[10,11,9]],[[4,11,7],[9,11,4],[10,11,9]],[[9,4,5]],[[9,4,5],[0,3,8]],[[0,5,1],[0,4,5]],[[4,3,8],[5,3,4],[1,3,5]],[[5,9,4],[10,2,1]],[[8,0,3],[1,10,2],[4,5,9]],[[10,4,5],[2,4,10],[0,4,2]],[[3,10,2],[8,10,3],[5,10,8],[4,5,8]],[[9,4,5],[11,3,2]],[[11,0,2],[11,8,0],[9,4,5]],[[5,1,4],[1,0,4],[11,3,2]],[[5,1,4],[4,1,11],[1,2,11],[4,11,8]],[[3,10,11],[3,1,10],[5,9,4]],[[9,4,5],[1,10,0],[0,10,8],[8,10,11]],[[5,0,4],[11,0,5],[11,3,0],[10,11,5]],[[5,10,4],[4,10,8],[8,10,11]],[[9,7,5],[9,8,7]],[[0,5,9],[3,5,0],[7,5,3]],[[8,7,0],[0,7,1],[1,7,5]],[[7,5,3],[3,5,1]],[[7,5,8],[5,9,8],[2,1,10]],[[10,2,1],[0,5,9],[3,5,0],[7,5,3]],[[8,2,0],[5,2,8],[10,2,5],[7,5,8]],[[2,3,10],[10,3,5],[5,3,7]],[[9,7,5],[9,8,7],[11,3,2]],[[0,2,9],[9,2,7],[7,2,11],[9,7,5]],
[[3,2,11],[8,7,0],[0,7,1],[1,7,5]],[[11,1,2],[7,1,11],[5,1,7]],[[3,1,11],[11,1,10],[8,7,9],[9,7,5]],[[11,7,0],[7,5,0],[5,9,0],[10,11,0],[1,10,0]],[[0,5,10],[0,7,5],[0,8,7],[0,10,11],[0,11,3]],[[10,11,5],[11,7,5]],[[5,6,10]],[[8,0,3],[10,5,6]],[[0,9,1],[5,6,10]],[[8,1,3],[8,9,1],[10,5,6]],[[1,6,2],[1,5,6]],[[6,2,5],[2,1,5],[8,0,3]],[[5,6,9],[9,6,0],[0,6,2]],[[5,8,9],[2,8,5],[3,8,2],[6,2,5]],[[3,2,11],[10,5,6]],[[0,2,8],[2,11,8],[5,6,10]],[[3,2,11],[0,9,1],[10,5,6]],[[5,6,10],[2,9,1],[11,9,2],[8,9,11]],[[11,3,6],[6,3,5],[5,3,1]],[[11,8,6],[6,8,1],[1,8,0],[6,1,5]],[[5,0,9],[6,0,5],[3,0,6],[11,3,6]],[[6,9,5],[11,9,6],[8,9,11]],[[7,4,8],[6,10,5]],[[3,7,0],[7,4,0],[10,5,6]],[[7,4,8],[6,10,5],[9,1,0]],[[5,6,10],[9,1,4],[4,1,7],[7,1,3]],[[1,6,2],[1,5,6],[7,4,8]],[[6,1,5],[2,1,6],[0,7,4],[3,7,0]],[[4,8,7],[5,6,9],[9,6,0],[0,6,2]],[[2,3,9],[3,7,9],[7,4,9],[6,2,9],[5,6,9]],[[2,11,3],[7,4,8],[10,5,6]],[[6,10,5],[7,4,11],[11,4,2],[2,4,0]],[[1,0,9],[8,7,4],[3,2,11],[5,6,10]],[[1,2,9],[9,2,11],[9,11,4],[4,11,7],[5,6,10]],
[[7,4,8],[11,3,6],[6,3,5],[5,3,1]],[[11,0,1],[11,4,0],[11,7,4],[11,1,5],[11,5,6]],[[6,9,5],[0,9,6],[11,0,6],[3,0,11],[4,8,7]],[[5,6,9],[9,6,11],[9,11,7],[9,7,4]],[[4,10,9],[4,6,10]],[[10,4,6],[10,9,4],[8,0,3]],[[1,0,10],[10,0,6],[6,0,4]],[[8,1,3],[6,1,8],[6,10,1],[4,6,8]],[[9,2,1],[4,2,9],[6,2,4]],[[3,8,0],[9,2,1],[4,2,9],[6,2,4]],[[0,4,2],[2,4,6]],[[8,2,3],[4,2,8],[6,2,4]],[[4,10,9],[4,6,10],[2,11,3]],[[11,8,2],[2,8,0],[6,10,4],[4,10,9]],[[2,11,3],[1,0,10],[10,0,6],[6,0,4]],[[8,4,1],[4,6,1],[6,10,1],[11,8,1],[2,11,1]],[[3,1,11],[11,1,4],[1,9,4],[11,4,6]],[[6,11,1],[11,8,1],[8,0,1],[4,6,1],[9,4,1]],[[3,0,11],[11,0,6],[6,0,4]],[[4,11,8],[4,6,11]],[[6,8,7],[10,8,6],[9,8,10]],[[3,7,0],[0,7,10],[7,6,10],[0,10,9]],[[1,6,10],[0,6,1],[7,6,0],[8,7,0]],[[10,1,6],[6,1,7],[7,1,3]],[[9,8,1],[1,8,6],[6,8,7],[1,6,2]],[[9,7,6],[9,3,7],[9,0,3],[9,6,2],[9,2,1]],[[7,6,8],[8,6,0],[0,6,2]],[[3,6,2],[3,7,6]],[[3,2,11],[6,8,7],[10,8,6],[9,8,10]],[[7,9,0],[7,10,9],[7,6,10],[7,0,2],[7,2,11]],[[0,10,1],[6,10,0],[8,6,0],[7,6,8],[2,11,3]],[[1,6,10],[7,6,1],[11,7,1],[2,11,1]],[[1,9,6],[9,8,6],[8,7,6],[3,1,6],[11,3,6]],
[[9,0,1],[11,7,6]],[[0,11,3],[6,11,0],[7,6,0],[8,7,0]],[[7,6,11]],[[11,6,7]],[[3,8,0],[11,6,7]],[[1,0,9],[6,7,11]],[[1,3,9],[3,8,9],[6,7,11]],[[10,2,1],[6,7,11]],[[10,2,1],[3,8,0],[6,7,11]],[[9,2,0],[9,10,2],[11,6,7]],[[11,6,7],[3,8,2],[2,8,10],[10,8,9]],[[2,6,3],[6,7,3]],[[8,6,7],[0,6,8],[2,6,0]],[[7,2,6],[7,3,2],[1,0,9]],[[8,9,7],[7,9,2],[2,9,1],[7,2,6]],[[6,1,10],[7,1,6],[3,1,7]],[[8,0,7],[7,0,6],[6,0,1],[6,1,10]],[[7,3,6],[6,3,9],[3,0,9],[6,9,10]],[[7,8,6],[6,8,10],[10,8,9]],[[8,11,4],[11,6,4]],[[11,0,3],[6,0,11],[4,0,6]],[[6,4,11],[4,8,11],[1,0,9]],[[1,3,9],[9,3,6],[3,11,6],[9,6,4]],[[8,11,4],[11,6,4],[1,10,2]],[[1,10,2],[11,0,3],[6,0,11],[4,0,6]],[[2,9,10],[0,9,2],[4,11,6],[8,11,4]],[[3,4,9],[3,6,4],[3,11,6],[3,9,10],[3,10,2]],[[3,2,8],[8,2,4],[4,2,6]],[[2,4,0],[6,4,2]],[[0,9,1],[3,2,8],[8,2,4],[4,2,6]],[[1,2,9],[9,2,4],[4,2,6]],[[10,3,1],[4,3,10],[4,8,3],[6,4,10]],[[10,0,1],[6,0,10],[4,0,6]],[[3,10,6],[3,9,10],[3,0,9],[3,6,4],[3,4,8]],[[9,10,4],[10,6,4]],[[9,4,5],[7,11,6]],[[9,4,5],[7,11,6],[0,3,8]],[[0,5,1],[0,4,5],[6,7,11]],[[11,6,7],[4,3,8],[5,3,4],[1,3,5]],[[1,10,2],[9,4,5],[6,7,11]],
[[8,0,3],[4,5,9],[10,2,1],[11,6,7]],[[7,11,6],[10,4,5],[2,4,10],[0,4,2]],[[8,2,3],[10,2,8],[4,10,8],[5,10,4],[11,6,7]],[[2,6,3],[6,7,3],[9,4,5]],[[5,9,4],[8,6,7],[0,6,8],[2,6,0]],[[7,3,6],[6,3,2],[4,5,0],[0,5,1]],[[8,1,2],[8,5,1],[8,4,5],[8,2,6],[8,6,7]],[[9,4,5],[6,1,10],[7,1,6],[3,1,7]],[[7,8,6],[6,8,0],[6,0,10],[10,0,1],[5,9,4]],[[3,0,10],[0,4,10],[4,5,10],[7,3,10],[6,7,10]],[[8,6,7],[10,6,8],[5,10,8],[4,5,8]],[[5,9,6],[6,9,11],[11,9,8]],[[11,6,3],[3,6,0],[0,6,5],[0,5,9]],[[8,11,0],[0,11,5],[5,11,6],[0,5,1]],[[6,3,11],[5,3,6],[1,3,5]],[[10,2,1],[5,9,6],[6,9,11],[11,9,8]],[[3,11,0],[0,11,6],[0,6,9],[9,6,5],[1,10,2]],[[0,8,5],[8,11,5],[11,6,5],[2,0,5],[10,2,5]],[[11,6,3],[3,6,5],[3,5,10],[3,10,2]],[[3,9,8],[6,9,3],[5,9,6],[2,6,3]],[[9,6,5],[0,6,9],[2,6,0]],[[6,5,8],[5,1,8],[1,0,8],[2,6,8],[3,2,8]],[[2,6,1],[6,5,1]],[[6,8,3],[6,9,8],[6,5,9],[6,3,1],[6,1,10]],[[1,10,0],[0,10,6],[0,6,5],[0,5,9]],[[3,0,8],[6,5,10]],[[10,6,5]],[[5,11,10],[5,7,11]],[[5,11,10],[5,7,11],[3,8,0]],[[11,10,7],[10,5,7],[0,9,1]],[[5,7,10],[10,7,11],[9,1,8],[8,1,3]],[[2,1,11],[11,1,7],[7,1,5]],[[3,8,0],[2,1,11],[11,1,7],[7,1,5]],[[2,0,11],[11,0,5],[5,0,9],[11,5,7]],[[2,9,5],[2,8,9],[2,3,8],[2,5,7],[2,7,11]],[[10,3,2],[5,3,10],[7,3,5]],[[10,0,2],[7,0,10],[8,0,7],[5,7,10]],[[0,9,1],[10,3,2],[5,3,10],[7,3,5]],[[7,8,2],[8,9,2],[9,1,2],[5,7,2],[10,5,2]],[[3,1,7],[7,1,5]],[[0,7,8],[1,7,0],[5,7,1]],[[9,5,0],[0,5,3],[3,5,7]],[[5,7,9],[7,8,9]],[[4,10,5],[8,10,4],[11,10,8]],[[3,4,0],[10,4,3],[10,5,4],[11,10,3]],[[1,0,9],[4,10,5],[8,10,4],[11,10,8]],
[[4,3,11],[4,1,3],[4,9,1],[4,11,10],[4,10,5]],[[1,5,2],[2,5,8],[5,4,8],[2,8,11]],[[5,4,11],[4,0,11],[0,3,11],[1,5,11],[2,1,11]],[[5,11,2],[5,8,11],[5,4,8],[5,2,0],[5,0,9]],[[5,4,9],[2,3,11]],[[3,4,8],[2,4,3],[5,4,2],[10,5,2]],[[5,4,10],[10,4,2],[2,4,0]],[[2,8,3],[4,8,2],[10,4,2],[5,4,10],[0,9,1]],[[4,10,5],[2,10,4],[1,2,4],[9,1,4]],[[8,3,4],[4,3,5],[5,3,1]],[[1,5,0],[5,4,0]],[[5,0,9],[3,0,5],[8,3,5],[4,8,5]],[[5,4,9]],[[7,11,4],[4,11,9],[9,11,10]],[[8,0,3],[7,11,4],[4,11,9],[9,11,10]],[[0,4,1],[1,4,11],[4,7,11],[1,11,10]],[[10,1,4],[1,3,4],[3,8,4],[11,10,4],[7,11,4]],[[9,4,1],[1,4,2],[2,4,7],[2,7,11]],[[1,9,2],[2,9,4],[2,4,11],[11,4,7],[3,8,0]],[[11,4,7],[2,4,11],[0,4,2]],[[7,11,4],[4,11,2],[4,2,3],[4,3,8]],[[10,9,2],[2,9,7],[7,9,4],[2,7,3]],[[2,10,7],[10,9,7],[9,4,7],[0,2,7],[8,0,7]],[[10,4,7],[10,0,4],[10,1,0],[10,7,3],[10,3,2]],[[8,4,7],[10,1,2]],[[4,1,9],[7,1,4],[3,1,7]],[[8,0,7],[7,0,1],[7,1,9],[7,9,4]],[[0,7,3],[0,4,7]],[[8,4,7]],[[9,8,10],[10,8,11]],[[3,11,0],[0,11,9],[9,11,10]],[[0,10,1],[8,10,0],[11,10,8]],[[11,10,3],[10,1,3]],[[1,9,2],[2,9,11],[11,9,8]],[[9,2,1],[11,2,9],[3,11,9],[0,3,9]],[[8,2,0],[8,11,2]],[[11,2,3]],[[2,8,3],[10,8,2],[9,8,10]],[[0,2,9],[2,10,9]],[[3,2,8],[8,2,10],[8,10,1],[8,1,0]],[[1,2,10]],[[3,1,8],[1,9,8]],[[9,0,1]],[[3,0,8]],[]];
Tuesday, August 4, 2020
Tuesday, July 21, 2020
Self Balancing Compact Loader
Skid steer compact loader can reduce tire wear and slip with a computer controlled self balancing system. Low pressure tires ensure excellent grip in loose soil.
Labels:
bobcat,
bucket,
construction,
dirt work,
haul,
implement,
load,
low pressure,
segway,
self balancing,
skid steer.compact loader,
tire,
two wheel
Monday, July 20, 2020
Solar Trail Tail
Overlanding vehicles could be powered by a series of connected trailers. Each carrying a solar panel contributing to power the main tractor vehicle.
When not in us,e the trailers can be collapsed and stacked on top.
When not in us,e the trailers can be collapsed and stacked on top.
Sunday, May 17, 2020
Social Unmasking Personal Protection
Unmask: Socially enhanced PPE design
transparent area in front of mouth to unmask mouth mimicry.
Extended filter area on rear part of cheeks to makeup for lost area.
Saturday, May 16, 2020
Saturday, May 9, 2020
Friday, January 10, 2020
SpaceX Spiral welded tube
Spiral weld stainless 30X into a tube that can be continuously
unrolled from coil, laser edge profiled, welded, heat treated, weld forming by a cryo weld planisher, X-ray inspected and cut to length with laser or precision plasma.
unrolled from coil, laser edge profiled, welded, heat treated, weld forming by a cryo weld planisher, X-ray inspected and cut to length with laser or precision plasma.
{
//
for (i = [-1: 0.01: 3])
color("gray") hull() {
translate([jsin(10 * i * 360) * 0.1, 0, 0])
translate([i * 2, min(i, 0) * -12, 0]) rotate([max(i, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - 0.1, 0.01, 0.001], center = true);
j = i + 0.01;
translate([jsin(10 * j * 360) * 0.1, 0, 0])
translate([j * 2, min(j, 0) * -12, 0]) rotate([max(j, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - .1, 0.01, 0.001], center = true);
}
// uncut stainless
color("gray") translate([-0.17, 1, 0] * 0.22)
translate([0, 0, 2])
linear_extrude(0.002)
polygon([
[-3, 12],
[-1, 12],
[0, 6],
[-2, 6]
]);
// final rocket trunk
translate([4, 0, 0]) color([0.6, 0.6, 0.6]) rotate([0, 90, 0])
linear_extrude(13) difference() {
$fn = 120;
circle(2 - 0.001);
circle(2 - 0.002);
}
$fn = 120;
// laser cutter profile edges
color([0.4, 0.5, 0.7]) translate([-1.8, 12] * 0.5) translate([0, 0, 2])
cube([2.4, 0.5, 1], center = true);
// coil
color([0.6, 0.6, 0.6]) translate([-2, 12] * 1.025) translate([0, 0, 1])
rotate([0, 0, 7]) rotate([0, 90, 0]) cylinder(2, 1, 1, center = true);
// xray and heat treat
color("red") rotate([30, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("orange") rotate([50, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("gold") rotate([60, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("blue") rotate([90, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
//welder
color("yellow") rotate([1, 0, 0]) translate([1, 0, 2]) cube([.125, 0.125, 1.5], center = true);
color([1, .8, .3]) rotate([1, 0, 0]) translate([1, 0, 2]) cube([.4, 0.4, .25], center = true);
}
function jsin(s) =
max(clamp(sin(s + 60) * 3, -0.5, 0.5), clamp(sin(s) * 3, -0.5, 0.5));
function clamp(a, b, c) = min(max(a, min(b, c)), max(b, c));
Subscribe to:
Posts (Atom)