Skip to content

Instantly share code, notes, and snippets.

@gfwilliams
Created March 22, 2017 08:05
Show Gist options
  • Save gfwilliams/f59a072436968510652404f325229383 to your computer and use it in GitHub Desktop.
Save gfwilliams/f59a072436968510652404f325229383 to your computer and use it in GitHub Desktop.
Koch snowflake vase for OpenJsCad
function circlify(v, opts) {
var d = Math.sqrt(v[0]*v[0] + v[1]*v[1]);
d = 1 + ((opts.radius-d)*opts.circle / d);
v[0] *= d;
v[1] *= d;
}
function kochs(a,b,opts) {
if (opts.d>=3) return [];
opts.d++;
var c = [(a[0]+b[0])/2, (a[1]+b[1])/2];
var x = [(b[0]-a[0])/3, (b[1]-a[1])/3];
var s = Math.sqrt(0.75)*opts.spread;
var y = [-x[1]*s, x[0]*s];
var pts = [];
var aa = [a[0]+x[0],a[1]+x[1], opts.z];
var cc = [c[0]+y[0],c[1]+y[1], opts.z];
var bb = [b[0]-x[0],b[1]-x[1], opts.z];
circlify(aa, opts);
circlify(bb, opts);
circlify(cc, opts);
pts = pts.concat(kochs(a,aa,opts));
pts.push(aa);
pts = pts.concat(kochs(aa,cc,opts));
pts.push(cc);
pts = pts.concat(kochs(cc,bb,opts));
pts.push(bb);
pts = pts.concat(kochs(bb,b,opts));
opts.d--;
return pts;
}
function koch(opts) {
opts.d = 0;
opts.rotate = opts.rotate||0;
var sides = 3;
var a,b;
var pts = [];
for (var i=0;i<sides;i++) {
var ang1 = opts.rotate + i*Math.PI*2/sides;
var ang2 = opts.rotate + (i+1)*Math.PI*2/sides;
a = [Math.sin(ang1)*opts.radius,Math.cos(ang1)*opts.radius, opts.z];
b = [Math.sin(ang2)*opts.radius,Math.cos(ang2)*opts.radius, opts.z];
pts.push(a);
pts = pts.concat(kochs(a,b,opts));
}
pts.push(b);
return pts;
}
function slice_extrude(slices) {
if (slices.length<2) return;
var polygons = [];
polygons = polygons.concat(polygon(slices[0])._toPlanePolygons({translation: [0, 0, slices[0][0][2]],
normalVector: CSG.Vector3D.Create(0, -1, 0), flipped: true}));
polygons = polygons.concat(polygon(slices[slices.length-1])._toPlanePolygons({translation: [0, 0, slices[slices.length-1][0][2]],
normalVector: CSG.Vector3D.Create(0, 1, 0), flipped: false}));
// walls
for (var i = 0; i < slices.length-1; i++) {
var a = slices[i];
var b = slices[i+1];
if (a.length!=b.length) throw new Error("All paths for slice_extrude must have the same number of points");
var k = a.length-1;
for (var j=0;j<a.length;j++) {
polygons.push(new CSG.Polygon([
new CSG.Vertex(new CSG.Vector3D(b[k])),
new CSG.Vertex(new CSG.Vector3D(b[j])),
new CSG.Vertex(new CSG.Vector3D(a[j]))]));
polygons.push(new CSG.Polygon([
new CSG.Vertex(new CSG.Vector3D(b[k])),
new CSG.Vertex(new CSG.Vector3D(a[j])),
new CSG.Vertex(new CSG.Vector3D(a[k]))]));
k=j;
}
}
return CSG.fromPolygons(polygons);
}
function main() {
var s = [];
for (var i=0;i<1;i+=0.05) {
var p = koch({
rotate:i,
radius:(4-Math.cos(i*Math.PI))*12.5,
circle:1-i,
z:i*100,
spread:i});
//s.push(translate([0,0,i*2],linear_extrude({ height: 0.1 },polygon({ points: p }))));
s.push(p);
}
return slice_extrude(s);
//return union(pts.map(function(xy) { return CSG.cube({center:[xy[0],xy[1],0], radius: [1, 1, 1]}) }));
return s;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment