1// Example of a generalized kaleidoscope. The idea is similar to a traditional 2// kaleidoscope, which consists of 3 flat mirrors with dihedral angles of 60 3// degrees. One can place an arbitrary object inside such a kaleidoscope and 4// reflections in the mirrors create an infinite repeating pattern. Here we use 5// both flat and spherical mirrors. "Reflection" in a spherical mirror is 6// inversion in the sphere. If the dihedral angles between the spheres and 7// planes are integer submultiples of the half turn (tau/2 or 180 degrees) the 8// reflections in such mirrors form a regular pattern. The type of pattern 9// created by such a kaleidoscope can be wildly complex. In this case we have 4 10// mirrors: 2 flat mirrors and 2 spherical mirrors. The mirrors are placed such 11// that the pattern scales down near the boundary of a disk. It resembles a 12// tiling of the 2D hyperbolic plane in the Poincare disk model, with the 13// important difference that our pattern is three dimensional. 14// 15// Credit: the ShapeJS project 16 17 18var voxelSize = 0.2*MM; 19 20function getQuad_1( r, r1, alpha){ 21 var r2 = r*r/(r1*Math.cos(alpha)); 22 var x1 = Math.sqrt(r1*r1 + r*r); 23 var y2 = Math.sqrt(r2*r2 + r*r); 24 25 var splanes = new Array(); 26 var count = 0; 27 splanes[count++] = new ReflectionSymmetry.getPlane(new Vector3d(0,-1,0), 0.0); 28 splanes[count++] = new ReflectionSymmetry.getPlane(new Vector3d(-1,0,0), 0.0); 29 splanes[count++] = new ReflectionSymmetry.getSphere(new Vector3d(x1,0,0), -r1); 30 splanes[count++] = new ReflectionSymmetry.getSphere(new Vector3d(0,y2,0), -r2); 31 32 return splanes; 33} 34 35function makePart_g(size, thickness){ 36 var t = (thickness/2) * 1.5; 37 var s = size/2; 38 //var g = createGrid(-t, t, -t, t, -s, s,voxelSize); 39 var b = 20*MM; 40 var g = createGrid(-b,b,-b,b,-b,b,0.5*MM); 41 42 var boxZ = new Box(0,0,0,thickness, thickness, size); 43 44 var mm = new GridMaker(); 45 mm.setSource(boxZ); 46 mm.setMaxAttributeValue(255); 47 mm.makeGrid(g); 48 49 var gmm = new GridMipMap(g); 50 51 gmm.setScalingType(GridMipMap.SCALING_AVERAGE); 52 //gmm.setScalingType(GridMipMap.SCALING_MAX); 53 54 return gmm; 55} 56 57function makePart(size, thickeness){ 58 var union = new Union(); 59 var boxX = new Box(0,0,0,thickeness, thickeness, size); 60 union.add(boxX); 61 return union; 62} 63 64function main(){ 65 var a = 25*MM; 66 var voxelSize = 0.1*MM; 67 var cz = 20.0*MM; 68 var cx = 5.0*MM; 69 var cy = 5.0*MM; 70 71 var part = makePart_g(30*MM, 5*MM); 72 part.setTransform(new Rotation(new Vector3d(-1,1,0), 3*Math.PI/8)); 73 74 var dt = new DataTransformer(); 75 dt.setSource(part); 76 77 var sym = new ReflectionSymmetry(getQuad_1(25*MM, 30*MM, Math.PI/3)); 78 sym.setMaxCount(50); 79 80 dt.setTransform(sym); 81 82 var maker = new GridMaker(); 83 maker.setSource(dt); 84 var dest = createGrid(-a,a,-a,a,-a,a,voxelSize); 85 maker.makeGrid(dest); 86 87 return dest; 88} 89 90