Created
March 22, 2017 08:05
-
-
Save gfwilliams/f59a072436968510652404f325229383 to your computer and use it in GitHub Desktop.
Koch snowflake vase for OpenJsCad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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