├── .gitignore ├── AmberMachine ├── AmberMachine.pde ├── data │ ├── mirrorx.glsl │ ├── mirrorxy.glsl │ ├── mirrory.glsl │ └── vignette.glsl ├── slices.pde ├── structures.pde └── transforms.pde ├── CityOnTheHill ├── CityOnTheHill.pde └── readme.md ├── FakeSoftBody ├── FakeSoftBody.pde └── readme.md ├── FakeSoftBody3D ├── FakeSoftBody3D.pde └── readme.md ├── GenerativeDice ├── OrthoWalkInCircle │ └── OrthoWalkInCircle.pde └── OrthoWalkInCircleContinuous │ └── OrthoWalkInCircleContinuous.pde ├── MeshIntersection ├── MeshIntersection.pde └── readme.md ├── README.md ├── Slicer ├── readme.md └── slicer.pde ├── isovol2D ├── data.pde ├── isovol2D.pde ├── marchingSquaresVOL.pde └── readme.md ├── isovol2DDynamic ├── data.pde ├── isovol2DDynamic.pde ├── marchingSquaresVOL.pde └── readme.md ├── matcap ├── data │ ├── 500.png │ ├── MatCapFrag.glsl │ └── MatCapVert.glsl ├── matcap.pde └── readme.md ├── perpetualDiamond ├── perpetualDiamond.pde └── readme.md ├── pixelFont ├── pixelFont.pde └── readme.md ├── sliceSaga ├── sliceBox │ ├── fragments.pde │ ├── sliceBox.pde │ ├── structures.pde │ └── transforms.pde ├── sliceHalfedge │ └── sliceHalfedge.pde ├── slicePop │ ├── data │ │ ├── donothing.glsl │ │ ├── mirrord.glsl │ │ ├── mirrorx.glsl │ │ ├── mirrorxy.glsl │ │ ├── mirrory.glsl │ │ └── vignette.glsl │ ├── fragmenttree.pde │ ├── geometry.pde │ ├── halfedge.pde │ ├── meshdata.pde │ ├── slicePop.pde │ ├── slicemesh.pde │ └── transformations.pde ├── slicePop2 │ ├── data │ │ ├── donothing.glsl │ │ ├── mirrord.glsl │ │ ├── mirrorx.glsl │ │ ├── mirrorxy.glsl │ │ ├── mirrory.glsl │ │ └── vignette.glsl │ ├── fragmenttree.pde │ ├── geometry.pde │ ├── halfedge.pde │ ├── meshdata.pde │ ├── slicePop2.pde │ ├── slicemesh.pde │ └── transformations.pde ├── sliceQuartz │ ├── output.obj │ ├── sliceQuartz.pde │ └── structures.pde ├── sliceTree │ ├── sliceTree.pde │ ├── slices.pde │ ├── structures.pde │ └── transforms.pde ├── sliceTree_Hexagon │ ├── sliceTree_Hexagon.pde │ ├── slices.pde │ ├── structures.pde │ └── transforms.pde ├── sliceTree_Hexagon2 │ ├── data │ │ ├── donothing.glsl │ │ ├── mirrord.glsl │ │ ├── mirrorx.glsl │ │ ├── mirrorxy.glsl │ │ ├── mirrory.glsl │ │ └── vignette.glsl │ ├── sliceTree_Hexagon2.pde │ ├── slices.pde │ ├── structures.pde │ └── transforms.pde ├── sliceTree_Mono │ ├── sliceTree_Mono.pde │ ├── slices.pde │ ├── structures.pde │ └── transforms.pde ├── sliceTree_Variation │ ├── sliceTree_Variation.pde │ ├── slices.pde │ ├── structures.pde │ └── transforms.pde └── sliceVoronoi │ ├── sliceVoronoi.pde │ └── structures.pde ├── sphere004 ├── readme.md └── sphere004.pde ├── spiral ├── SVG │ ├── spiral001.svg │ ├── spiral002.svg │ ├── spiral003.svg │ ├── spiral004.svg │ └── spiral005.svg ├── data │ └── portrait.jpg ├── readme.md └── spiral.pde └── template └── template.pde /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | 45 | 46 | # Ignore class files 47 | *.class 48 | # Ignore Eclipse class path 49 | .classpath 50 | .project 51 | /.settings/ 52 | /bin/ 53 | -------------------------------------------------------------------------------- /AmberMachine/data/mirrorx.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.x < 0.5 ? vertTexCoord.xy : vec2(1.0-vertTexCoord.x, vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /AmberMachine/data/mirrorxy.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.x < 0.5 ? vertTexCoord.xy : vec2(1.0-vertTexCoord.x, vertTexCoord.y); 8 | p= p.y < 0.5 ? p.xy : vec2(p.x, 1.0-p.y); 9 | gl_FragColor = texture2D(texture, p); 10 | } -------------------------------------------------------------------------------- /AmberMachine/data/mirrory.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.y > 0.5 ? vertTexCoord.xy : vec2(vertTexCoord.x, 1.0-vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /AmberMachine/data/vignette.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | precision mediump int; 6 | #endif 7 | 8 | uniform sampler2D texture; 9 | uniform vec2 resolution; 10 | varying vec4 vertColor; 11 | varying vec4 vertTexCoord; 12 | 13 | const float RADIUS = 0.75; 14 | const float SOFTNESS = 0.45; 15 | const vec3 SEPIA = vec3(1.0, 0.8, 0.6); 16 | 17 | 18 | void main(void) { 19 | vec4 texColor = texture2D(texture,vertTexCoord.xy); 20 | vec2 position = (gl_FragCoord.xy / resolution.xy) - vec2(0.5); 21 | float len = length(position); 22 | float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len); 23 | texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5); 24 | float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); 25 | vec3 sepiaColor = vec3(gray) * SEPIA; 26 | texColor.rgb = mix(texColor.rgb, sepiaColor, 0.1); 27 | gl_FragColor = texColor * vertColor; 28 | } -------------------------------------------------------------------------------- /AmberMachine/slices.pde: -------------------------------------------------------------------------------- 1 | class SliceTree { 2 | ArrayList roots; 3 | float bufferedF; 4 | 5 | SliceTree(SliceBox mesh) { 6 | roots=new ArrayList(); 7 | roots.add(new Slice(mesh)); 8 | } 9 | 10 | SliceTree(ArrayList meshes) { 11 | roots=new ArrayList(); 12 | for (SliceBox mesh : meshes) { 13 | roots.add(new Slice(mesh)); 14 | } 15 | } 16 | 17 | SliceTree(SliceBox... meshes) { 18 | roots=new ArrayList(); 19 | for (SliceBox mesh : meshes) { 20 | roots.add(new Slice(mesh)); 21 | } 22 | } 23 | 24 | void split(Transformation M, color col, color col2) { 25 | for (Slice root : roots) { 26 | root.split(M, col, col2); 27 | } 28 | } 29 | 30 | void setPhase(float f) { 31 | for (Slice root : roots) { 32 | root.setPhase(f); 33 | } 34 | } 35 | 36 | float[] getExtents() { 37 | float[] extents=new float[]{1000000, 1000000, 1000000, -1000000, -1000000, -1000000}; 38 | for (Slice root : roots) { 39 | root.addExtents(extents); 40 | } 41 | return extents; 42 | } 43 | 44 | void draw() { 45 | 46 | for (Slice root : roots) { 47 | root.draw(); 48 | } 49 | } 50 | 51 | 52 | 53 | float minDistance(Plane P) { 54 | float minDistance=1000000; 55 | for (Slice root : roots) { 56 | minDistance=min(minDistance, root.minDistance(P)); 57 | } 58 | return minDistance; 59 | } 60 | } 61 | 62 | 63 | 64 | class Slice { 65 | Slice parent; 66 | Slice child1, child2; 67 | Transformation parentToChild; 68 | SliceBox mesh; 69 | SliceBox invTMesh; 70 | SliceBox dynMesh; 71 | SliceBox drawMesh; 72 | int level; 73 | 74 | Slice(SliceBox mesh) { 75 | this.mesh = mesh.copy(); 76 | invTMesh = mesh.copy(); 77 | dynMesh = mesh.copy(); 78 | parentToChild = null; 79 | parent = null; 80 | child1 = null; 81 | child2 = null; 82 | level = 0; 83 | } 84 | 85 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 86 | this.mesh = mesh.copy(); 87 | dynMesh= mesh.copy(); 88 | this.parentToChild = parentToChild; 89 | this.parent = parent; 90 | invTMesh = mesh.copy(); 91 | Slice p = this; 92 | do { 93 | if ( p.parentToChild!=null) { 94 | Transform T = p.parentToChild.getInverseTransform(1.0); 95 | T.apply(invTMesh); 96 | } 97 | p = p.parent; 98 | } while (p != null); 99 | level=parent.level+1; 100 | } 101 | 102 | void split(Transformation M, color col, color col2) { 103 | if ((child1 == null) && (child2 == null)) { 104 | SliceBox split1=mesh.copy(); 105 | SliceBox split2=mesh.copy(); 106 | split1.slice(M.plane, 0.0, col); 107 | split2.slice(M.plane.flip(), 0.0, col2); 108 | if (split1.vertices.size() > 0 && split1.isValid()) { 109 | child1 = new Slice(split1, this, null); 110 | } 111 | if (split2.vertices.size() > 0 && split2.isValid()) { 112 | M.getTransform(1.0).apply(split2); 113 | child2 = new Slice(split2, this, M); 114 | } 115 | } else { 116 | if (child1 != null) { 117 | child1.split(M, col, col2); 118 | } 119 | if (child2 != null) { 120 | child2.split(M, col2, col); 121 | } 122 | } 123 | } 124 | 125 | 126 | float minDistance(Plane P) { 127 | float minDistance=1000000; 128 | if (((child1 == null) && (child2 == null))) {//||f<=level) { 129 | for (Vertex v : mesh.vertices) { 130 | minDistance=min(minDistance, v.distance(P)); 131 | if(minDistance<5.0) return minDistance; 132 | } 133 | } else { 134 | if (child1 != null) { 135 | minDistance=min(minDistance, child1.minDistance(P)); 136 | } 137 | if (child2 != null) { 138 | minDistance=min(minDistance, child2.minDistance(P)); 139 | } 140 | } 141 | return minDistance; 142 | } 143 | 144 | void setPhase(float f) { 145 | if (((child1 == null) && (child2 == null))||f<=level) { 146 | drawMesh = getMesh(f); 147 | } else { 148 | drawMesh=null; 149 | if (child1 != null) { 150 | child1.setPhase(f); 151 | } 152 | if (child2 != null) { 153 | child2.setPhase(f); 154 | } 155 | } 156 | } 157 | 158 | void addExtents(float[] extents) { 159 | if (drawMesh!=null) { 160 | float[] fragmentExtents=drawMesh.getExtents(); 161 | for (int i=0; i<3; i++) { 162 | extents[i]=min(extents[i], fragmentExtents[i]); 163 | extents[i+3]=max(extents[i+3], fragmentExtents[i+3]); 164 | } 165 | } else { 166 | if (child1 != null) { 167 | child1.addExtents(extents); 168 | } 169 | if (child2 != null) { 170 | child2.addExtents(extents); 171 | } 172 | } 173 | } 174 | 175 | 176 | void draw() { 177 | if (drawMesh!=null) { 178 | drawMesh.draw(); 179 | } else { 180 | if (child1 != null) { 181 | child1.draw(); 182 | } 183 | if (child2 != null) { 184 | child2.draw(); 185 | } 186 | } 187 | } 188 | 189 | 190 | 191 | 192 | SliceBox getMesh(float f) { 193 | if (f<=0) { 194 | return invTMesh; 195 | } else if (f>=level) { 196 | return mesh; 197 | } else { 198 | 199 | Slice p = this; 200 | float fracf; 201 | Transform T=new Transform(); 202 | do { 203 | if (p.parentToChild!=null) { 204 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 205 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 206 | } 207 | p = p.parent; 208 | } while (p != null && f spheres; 11 | 12 | int num; 13 | void setup() { 14 | fullScreen(P3D); 15 | smooth(8); 16 | render=new WB_Render3D(this); 17 | WB_PointFactory pg=new WB_RandomRectangle().setSize(800, 800); 18 | spheres=new ArrayList(); 19 | num=200; 20 | 21 | for (int i=0; i spheres; 11 | 12 | int num; 13 | void setup() { 14 | fullScreen(P3D); 15 | smooth(8); 16 | render=new WB_Render3D(this); 17 | WB_PointFactory pg=new WB_RandomBox().setSize(600, 600, 600); 18 | spheres=new ArrayList(); 19 | num=200; 20 | 21 | for (int i=0; i256) { 54 | currentI=20; 55 | currentJ=20; 56 | run=false; 57 | } 58 | } 59 | 60 | 61 | void draw() { 62 | background(255); 63 | translate(width/2, height/2); 64 | stroke(0); 65 | strokeWeight(1.0); 66 | ellipse(0, 0, 800, 800); 67 | drawVertSegments(); 68 | drawHorSegments(); 69 | if (run) takeStep(); 70 | } 71 | 72 | void drawVertSegments() { 73 | for (int i=0; i<=40; i++) { 74 | for (int j=0; j<40; j++) { 75 | if (vertSegments[i][j]>0) { 76 | strokeWeight(vertSegments[i][j]); 77 | line(i*25-500, j*25-500, i*25-500, j*25-475); 78 | } 79 | } 80 | } 81 | } 82 | 83 | void drawHorSegments() { 84 | for (int i=0; i<40; i++) { 85 | for (int j=0; j<=40; j++) { 86 | if (horSegments[j][i]>0) { 87 | strokeWeight(horSegments[j][i]); 88 | line(i*25-500, j*25-500, i*25-475, j*25-500); 89 | } 90 | } 91 | } 92 | } 93 | 94 | void mousePressed() { 95 | run=true; 96 | } 97 | 98 | void keyPressed() { 99 | if (key=='r') { 100 | vertSegments=new float[41][40]; 101 | horSegments=new float[41][40]; 102 | currentI=20; 103 | currentJ=20; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /GenerativeDice/OrthoWalkInCircleContinuous/OrthoWalkInCircleContinuous.pde: -------------------------------------------------------------------------------- 1 | float[][] vertSegments; 2 | float[][] horSegments; 3 | int currentI, currentJ; 4 | 5 | 6 | void setup() { 7 | size(1000, 1000, P2D); 8 | smooth(16); 9 | //line thickness of vertical lines of the grid (41 lines of 40 segments each) 10 | vertSegments=new float[41][40]; 11 | //line thickness of horizontal lines of the grid (41 lines of 40 segments each) 12 | horSegments=new float[41][40]; 13 | //start point 14 | currentI=20; 15 | currentJ=20; 16 | } 17 | 18 | void takeStep() { 19 | checkBounds(); 20 | int direction =(int)random(4.0); 21 | int step=(int)random(6.0)+1; 22 | switch(direction) { 23 | case 0: 24 | for (int i=max(0, currentI-step); i256) { 55 | currentI=(int)random(10,31); 56 | currentJ=(int)random(10,31); 57 | } 58 | } 59 | 60 | 61 | void draw() { 62 | background(255); 63 | translate(width/2, height/2); 64 | stroke(0); 65 | strokeWeight(1.0); 66 | ellipse(0, 0, 800, 800); 67 | drawVertSegments(); 68 | drawHorSegments(); 69 | 70 | takeStep(); 71 | reduce(); 72 | } 73 | 74 | void reduce() { 75 | for (int i=0; i<=40; i++) { 76 | for (int j=0; j<40; j++) { 77 | vertSegments[i][j]=max(0.0, vertSegments[i][j]-0.01); 78 | horSegments[i][j]=max(0.0, horSegments[i][j]-0.01); 79 | } 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | void drawVertSegments() { 87 | for (int i=0; i<=40; i++) { 88 | for (int j=0; j<40; j++) { 89 | if (vertSegments[i][j]>0) { 90 | strokeWeight(vertSegments[i][j]); 91 | line(i*25-500, j*25-500, i*25-500, j*25-475); 92 | } 93 | } 94 | } 95 | } 96 | 97 | void drawHorSegments() { 98 | for (int i=0; i<40; i++) { 99 | for (int j=0; j<=40; j++) { 100 | if (horSegments[j][i]>0) { 101 | strokeWeight(horSegments[j][i]); 102 | line(i*25-500, j*25-500, i*25-475, j*25-500); 103 | } 104 | } 105 | } 106 | } 107 | 108 | void keyPressed() { 109 | if (key=='r') { 110 | vertSegments=new float[41][40]; 111 | horSegments=new float[41][40]; 112 | currentI=20; 113 | currentJ=20; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /MeshIntersection/MeshIntersection.pde: -------------------------------------------------------------------------------- 1 | import wblut.math.*; 2 | import wblut.hemesh.*; 3 | import wblut.core.*; 4 | import wblut.geom.*; 5 | import wblut.nurbs.*; 6 | import wblut.processing.*; 7 | import java.util.*; 8 | import wblut.hemesh.HE_MeshOp.HE_FaceFaceIntersection; 9 | WB_Render3D render; 10 | HE_Mesh mesh1; 11 | HE_Mesh mesh2; 12 | List intersections; 13 | 14 | void setup() { 15 | fullScreen(P3D); 16 | smooth(8); 17 | render=new WB_Render3D(this); 18 | mesh1=new HEC_Torus(100, 240, 16, 16).create(); 19 | mesh2=new HEC_Box(350, 350, 350, 10, 10, 10).setAxis(1, 1, 1).setCenter(100, 0, 0).create(); 20 | mesh1.smooth(); 21 | mesh2.smooth(); 22 | intersections=HE_MeshOp.getIntersection(mesh1, mesh2); 23 | } 24 | 25 | void draw() { 26 | background(15); 27 | translate(width/2, height/2); 28 | rotateY(map(mouseX, 0, width, -PI, PI)); 29 | rotateX(map(mouseY, 0, height, PI, -PI)); 30 | lights(); 31 | strokeWeight(1.0); 32 | stroke(240, 120); 33 | render.drawEdges(mesh1); 34 | render.drawEdges(mesh2); 35 | strokeWeight(4.0); 36 | stroke(0, 0, 255); 37 | for (HE_FaceFaceIntersection intersection : intersections) { 38 | render.drawSegment(intersection.getSegment()); 39 | } 40 | noStroke(); 41 | fill(255, 0, 0); 42 | render.drawFaces(mesh1.getSelection("intersection")); 43 | render.drawFaces(mesh2.getSelection("intersection")); 44 | } 45 | -------------------------------------------------------------------------------- /MeshIntersection/readme.md: -------------------------------------------------------------------------------- 1 | ![Mesh Intersection](https://wblut.github.io/img/MeshIntersection.png) 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Processing3Sketches 2 | 3 | * Slicer: requires https://www.wblut.com/hemesh/hemesh20190921.zip as your hemesh version. To use, replace in or add to the processing libraries folder. -------------------------------------------------------------------------------- /Slicer/readme.md: -------------------------------------------------------------------------------- 1 | ![Slicer](https://wblut.github.io/img/Slicer.png) 2 | -------------------------------------------------------------------------------- /isovol2D/data.pde: -------------------------------------------------------------------------------- 1 | final static int ONVERTEX = 0; 2 | final static int ONEDGE = 1; 3 | final static int NEGATIVE = 0; 4 | final static int EQUAL = 1; 5 | final static int POSITIVE = 2; 6 | int[] digits = new int[4]; 7 | float[][] gridvertices=new float[][]{{0, 0}, {1, 0}, {0, 1}, {1, 1}}; 8 | final static int[][] edges = { { 0, 1 }, { 0, 2 }, { 1, 3 }}; 9 | static int[][] isovertices = new int[][] { { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, { 1, 2, 0 }, 10 | { 1, 2, 1 }, { 1, 3, 0 }, { 1, 3, 1 }, { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 } }; 11 | final static int[][] entries=new int[][] 12 | {{0}, 13 | {1, 0, 2, 8}, 14 | {2, 1, 0, 2, 3, 1, 2}, 15 | {1, 0, 9, 4}, 16 | {2, 4, 2, 8, 9, 4, 8}, 17 | {3, 1, 4, 3, 9, 4, 1, 4, 2, 3}, 18 | {2, 1, 4, 0, 5, 4, 1}, 19 | {3, 1, 5, 2, 8, 1, 2, 4, 2, 5}, 20 | {2, 4, 3, 5, 4, 2, 3}, 21 | {1, 2, 6, 10}, 22 | {2, 6, 8, 0, 10, 8, 6}, 23 | {3, 6, 3, 1, 10, 3, 6, 6, 1, 0}, 24 | {4, 6, 9, 4, 10, 9, 6, 10, 2, 9, 2, 0, 9}, 25 | {3, 4, 6, 9, 9, 6, 10, 9, 10, 8}, 26 | {4, 4, 6, 1, 9, 4, 1, 1, 6, 3, 6, 10, 3}, 27 | {5, 6, 5, 4, 10, 5, 6, 10, 1, 5, 10, 2, 1, 2, 0, 1}, 28 | {4, 8, 1, 10, 1, 5, 10, 4, 6, 5, 6, 10, 5}, 29 | {3, 4, 6, 5, 10, 3, 5, 6, 10, 5}, 30 | {2, 3, 2, 6, 7, 3, 6}, 31 | {3, 3, 0, 7, 8, 0, 3, 6, 7, 0}, 32 | {2, 6, 7, 1, 6, 1, 0}, 33 | {5, 6, 7, 4, 9, 7, 3, 4, 7, 9, 9, 3, 0, 2, 0, 3}, 34 | {4, 9, 3, 8, 9, 7, 3, 9, 4, 7, 4, 6, 7}, 35 | {3, 4, 6, 7, 9, 4, 7, 1, 9, 7}, 36 | {4, 6, 7, 5, 6, 5, 4, 2, 1, 3, 2, 0, 1}, 37 | {3, 8, 1, 3, 5, 4, 6, 7, 5, 6}, 38 | {2, 4, 6, 5, 5, 6, 7}, 39 | {1, 4, 11, 6}, 40 | {4, 6, 2, 8, 11, 6, 8, 11, 8, 4, 4, 8, 0}, 41 | {5, 6, 2, 3, 11, 6, 3, 11, 3, 1, 11, 1, 4, 4, 1, 0}, 42 | {2, 6, 0, 9, 11, 6, 9}, 43 | {3, 2, 8, 6, 6, 8, 11, 9, 11, 8}, 44 | {4, 2, 3, 6, 1, 11, 3, 9, 11, 1, 6, 3, 11}, 45 | {3, 6, 1, 5, 11, 6, 5, 6, 0, 1}, 46 | {4, 2, 1, 6, 8, 1, 2, 1, 5, 6, 6, 5, 11}, 47 | {3, 2, 3, 6, 5, 11, 3, 6, 3, 11}, 48 | {2, 4, 10, 2, 11, 10, 4}, 49 | {3, 0, 4, 8, 4, 11, 8, 10, 8, 11}, 50 | {4, 0, 4, 1, 1, 11, 3, 4, 11, 1, 10, 3, 11}, 51 | {3, 2, 0, 9, 10, 2, 9, 10, 9, 11}, 52 | {2, 9, 11, 10, 9, 10, 8}, 53 | {3, 9, 11, 1, 1, 11, 3, 11, 10, 3}, 54 | {4, 2, 0, 1, 10, 2, 1, 10, 1, 5, 10, 5, 11}, 55 | {3, 8, 1, 10, 1, 5, 10, 11, 10, 5}, 56 | {2, 5, 10, 3, 5, 11, 10}, 57 | {3, 4, 7, 3, 11, 7, 4, 4, 3, 2}, 58 | {4, 0, 4, 3, 8, 0, 3, 3, 4, 7, 4, 11, 7}, 59 | {3, 0, 4, 1, 7, 1, 11, 4, 11, 1}, 60 | {4, 0, 9, 3, 2, 0, 3, 3, 9, 7, 9, 11, 7}, 61 | {3, 9, 3, 8, 9, 7, 3, 9, 11, 7}, 62 | {2, 11, 7, 9, 9, 7, 1}, 63 | {3, 2, 0, 1, 2, 1, 3, 7, 5, 11}, 64 | {2, 11, 7, 5, 8, 1, 3}, 65 | {1, 5, 11, 7}, 66 | {2, 5, 6, 4, 7, 6, 5}, 67 | {5, 6, 2, 7, 8, 5, 7, 2, 8, 7, 8, 0, 5, 4, 5, 0}, 68 | {4, 6, 3, 7, 6, 2, 3, 4, 5, 1, 4, 1, 0}, 69 | {3, 5, 7, 0, 9, 5, 0, 6, 0, 7}, 70 | {4, 2, 7, 6, 8, 7, 2, 5, 7, 8, 9, 5, 8}, 71 | {3, 9, 5, 1, 3, 6, 2, 7, 6, 3}, 72 | {2, 6, 1, 7, 6, 0, 1}, 73 | {3, 2, 7, 6, 8, 7, 2, 1, 7, 8}, 74 | {2, 7, 6, 3, 3, 6, 2}, 75 | {3, 4, 5, 2, 5, 7, 2, 10, 2, 7}, 76 | {4, 0, 4, 5, 8, 0, 5, 8, 5, 7, 10, 8, 7}, 77 | {3, 10, 3, 7, 1, 0, 4, 5, 1, 4}, 78 | {4, 0, 9, 5, 2, 0, 5, 2, 5, 7, 10, 2, 7}, 79 | {3, 8, 7, 10, 5, 7, 8, 9, 5, 8}, 80 | {2, 9, 5, 1, 7, 10, 3}, 81 | {3, 2, 0, 1, 10, 2, 1, 10, 1, 7}, 82 | {2, 7, 8, 1, 7, 10, 8}, 83 | {1, 7, 10, 3}, 84 | {2, 4, 5, 3, 4, 3, 2}, 85 | {3, 0, 4, 5, 8, 0, 5, 3, 8, 5}, 86 | {2, 5, 1, 4, 1, 0, 4}, 87 | {3, 0, 9, 3, 2, 0, 3, 9, 5, 3}, 88 | {2, 8, 5, 3, 9, 5, 8}, 89 | {1, 9, 5, 1}, 90 | {2, 2, 0, 1, 2, 1, 3}, 91 | {1, 8, 1, 3}, 92 | {0}}; 93 | -------------------------------------------------------------------------------- /isovol2D/isovol2D.pde: -------------------------------------------------------------------------------- 1 | //Find all triangles between two isolevel contours for a grid of values 2 | //https://www.goodreads.com/book/show/16195572-isosurfaces 3 | 4 | List isotriangles;//triangles between two isolevel contours 5 | int resx, resy;//resolution of grid 6 | float cx, cy;//center of grid 7 | float dx, dy;//size of grid cell 8 | float zFactor;//(grid values) x zFactor = height of triangle vertices 9 | float[][] values;// grid values 10 | 11 | void setup() { 12 | size(800, 800, P3D); 13 | smooth(16); 14 | resx=100; 15 | resy=100; 16 | values=new float[resx+1][resy+1]; 17 | 18 | for(int i=0;i<=resx;i++){ 19 | for(int j=0;j<=resy;j++){ 20 | values[i][j]= (noise(0.025*i, 0.025*j)-0.1)/0.8; 21 | } 22 | } 23 | 24 | cx=0; 25 | cy=0; 26 | dx=5; 27 | dy=5; 28 | zFactor=200.0; 29 | 30 | isotriangles=new ArrayList(); 31 | //get triangles between isolevel low and isolevel high, and give the color col: getTriangles(low, high, col) 32 | isotriangles.addAll(getTriangles(0.1, 0.15, color(255,0,0))); 33 | isotriangles.addAll(getTriangles(0.2, 0.25, color(255,128,0))); 34 | isotriangles.addAll(getTriangles(0.3, 0.35, color(255,255,0))); 35 | isotriangles.addAll(getTriangles(0.4, 0.45, color(128,255,0))); 36 | isotriangles.addAll(getTriangles(0.5, 0.55, color(0,255,0))); 37 | isotriangles.addAll(getTriangles(0.6, 0.65, color(0,255,128))); 38 | isotriangles.addAll(getTriangles(0.7, 0.75, color(0,128,255))); 39 | isotriangles.addAll(getTriangles(0.8, 0.85, color(0,0,255))); 40 | isotriangles.addAll(getTriangles(0.9, 0.95, color(128,0,255))); 41 | } 42 | 43 | //This function returns the values of (resX+1)x(resY+1) data points 44 | float getValue(int i, int j) { 45 | return values[i][j]; 46 | } 47 | 48 | void draw() { 49 | background(255); 50 | translate(width/2, height/2); 51 | lights(); 52 | rotateY(map(mouseX, 0, width, -PI, PI)); 53 | rotateX(map(mouseY, 0, height, PI, -PI)); 54 | for (Triangle triangle : isotriangles) { 55 | triangle.draw(); 56 | } 57 | } 58 | 59 | class Point { 60 | float x, y, z; 61 | Point(float x, float y, float z) { 62 | this.x=x; 63 | this.y=y; 64 | this.z=z; 65 | } 66 | } 67 | 68 | class Triangle { 69 | Point p1, p2, p3; 70 | color col; 71 | Triangle(Point p1, Point p2, Point p3, color col) { 72 | this.p1=new Point(p1.x, p1.y, p1.z); 73 | this.p2=new Point(p2.x, p2.y, p2.z); 74 | this.p3=new Point(p3.x, p3.y, p3.z); 75 | this.col=col; 76 | } 77 | 78 | void draw() { 79 | fill(col); 80 | beginShape(); 81 | vertex(p1.x, p1.y, p1.z); 82 | vertex(p2.x, p2.y, p2.z); 83 | vertex(p3.x, p3.y, p3.z); 84 | endShape(CLOSE); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /isovol2D/marchingSquaresVOL.pde: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | import java.util.HashMap; 3 | import java.util.List; 4 | 5 | Map xedges; 6 | Map yedges; 7 | Map vertices; 8 | float isolevelmin; 9 | float isolevelmax; 10 | List triangles; 11 | 12 | int index(int i, int j) { 13 | return i+1 +(resx+2)*(j+1); 14 | } 15 | 16 | 17 | 18 | Point vertex(final int i, final int j, final Point offset) { 19 | Point vertex = vertices.get(index(i, j)); 20 | if (vertex != null) { 21 | return vertex; 22 | } 23 | vertex = new Point(i * dx+offset.x, j * dy+offset.y, zFactor * getValue(i, j)+offset.z); 24 | vertices.put(index(i, j), vertex); 25 | return vertex; 26 | } 27 | 28 | Point interp(final float isolevel, final Point p1, final Point p2, final float valp1, 29 | final float valp2, Point offset) { 30 | if (isolevel==valp1) { 31 | return new Point(p1.x +offset.x, p1.y+offset.y, zFactor * isolevel); 32 | } 33 | if (isolevel==valp2) { 34 | return new Point(p2.x+offset.x, p2.y+offset.y, zFactor * isolevel); 35 | } 36 | if (valp1==valp2) { 37 | return new Point(p1.x+offset.x, p1.y+offset.y, zFactor * isolevel); 38 | } 39 | float mu = (isolevel - valp1) / (valp2 - valp1); 40 | return new Point(p1.x + mu * (p2.x - p1.x)+offset.x, p1.y + mu * (p2.y - p1.y)+offset.y, zFactor * isolevel); 41 | } 42 | 43 | Point xedge(final int i, final int j, final Point offset, final float isolevel) { 44 | Point xedge = xedges.get(index(i, j)); 45 | if (xedge != null) { 46 | return xedge; 47 | } 48 | final Point p0 = new Point(i * dx, j * dy, 0); 49 | final Point p1 = new Point(i * dx + dx, j * dy, 0); 50 | final float val0 = getValue(i, j); 51 | final float val1 = getValue(i + 1, j); 52 | xedge = interp(isolevel, p0, p1, val0, val1, offset); 53 | xedges.put(index(i, j), xedge); 54 | return xedge; 55 | } 56 | 57 | Point yedge(final int i, final int j, final Point offset, final float isolevel) { 58 | Point yedge = yedges.get(index(i, j)); 59 | if (yedge != null) { 60 | return yedge; 61 | } 62 | final Point p0 = new Point(i * dx, j * dy, 0); 63 | final Point p1 = new Point(i * dx, j * dy + dy, 0); 64 | final float val0 = getValue(i, j); 65 | final float val1 = getValue(i, j + 1); 66 | yedge =interp(isolevel, p0, p1, val0, val1, offset); 67 | yedges.put(index(i, j), yedge); 68 | return yedge; 69 | } 70 | 71 | int classifyCell(final int i, final int j) { 72 | if (i < 0 || j < 0 || i >= resx || j >= resy) { 73 | return -1; 74 | } 75 | digits = new int[8]; 76 | int cubeindex = 0; 77 | int offset = 1; 78 | if (getValue(i, j) > isolevelmax) { 79 | cubeindex += 2 * offset; 80 | digits[0] = POSITIVE; 81 | } else if (getValue(i, j) >= isolevelmin) { 82 | cubeindex += offset; 83 | digits[0] = EQUAL; 84 | } 85 | offset *= 3; 86 | if (getValue(i + 1, j) > isolevelmax) { 87 | cubeindex += 2 * offset; 88 | digits[1] = POSITIVE; 89 | } else if (getValue(i + 1, j) >= isolevelmin) { 90 | cubeindex += offset; 91 | digits[1] = EQUAL; 92 | } 93 | offset *= 3; 94 | if (getValue(i, j + 1) > isolevelmax) { 95 | cubeindex += 2 * offset; 96 | digits[2] = POSITIVE; 97 | } else if (getValue(i, j + 1) >= isolevelmin) { 98 | cubeindex += offset; 99 | digits[2] = EQUAL; 100 | } 101 | offset *= 3; 102 | if (getValue(i + 1, j + 1) > isolevelmax) { 103 | cubeindex += 2 * offset; 104 | digits[3] = POSITIVE; 105 | } else if (getValue(i + 1, j + 1) >= isolevelmin) { 106 | cubeindex += offset; 107 | digits[3] = EQUAL; 108 | } 109 | return cubeindex; 110 | } 111 | 112 | List getTriangles(float isomin, float isomax, color col) { 113 | isolevelmin=isomin; 114 | isolevelmax=isomax; 115 | xedges = new HashMap(); 116 | yedges = new HashMap(); 117 | vertices = new HashMap(); 118 | final Point offset = new Point(cx - 0.5 * resx * dx, cy - 0.5 * resy * dy, 0); 119 | triangles = new ArrayList(); 120 | for (int i = 0; i < resx; i++) { 121 | for (int j = 0; j < resy; j++) { 122 | triangulate(i, j, classifyCell(i, j), offset, col); 123 | } 124 | } 125 | return triangles; 126 | } 127 | 128 | void triangulate(final int i, final int j, final int cubeindex, final Point offset, color col) { 129 | final int[] indices = entries[cubeindex]; 130 | final int numtris = indices[0]; 131 | int currentindex = 1; 132 | for (int t = 0; t < numtris; t++) { 133 | final Point v2 = getIsoVertex(indices[currentindex++], i, j, offset); 134 | final Point v1 = getIsoVertex(indices[currentindex++], i, j, offset); 135 | final Point v3 = getIsoVertex(indices[currentindex++], i, j, offset); 136 | triangles.add(new Triangle(v1, v2, v3,col)); 137 | } 138 | 139 | } 140 | 141 | Point getIsoVertex(final int isopointindex, final int i, final int j, final Point offset) { 142 | if (isovertices[isopointindex][0] == ONVERTEX) { 143 | switch (isovertices[isopointindex][1]) { 144 | case 0: 145 | return vertex(i, j, offset); 146 | case 1: 147 | return vertex(i + 1, j, offset); 148 | case 2: 149 | return vertex(i, j + 1, offset); 150 | case 3: 151 | return vertex(i + 1, j + 1, offset); 152 | default: 153 | return null; 154 | } 155 | } else if (isovertices[isopointindex][0] == ONEDGE) { 156 | if (isovertices[isopointindex][2] == 0) { 157 | switch (isovertices[isopointindex][1]) { 158 | case 0: 159 | return xedge(i, j, offset, isolevelmin); 160 | case 1: 161 | return yedge(i, j, offset, isolevelmin); 162 | case 2: 163 | return yedge(i + 1, j, offset, isolevelmin); 164 | case 3: 165 | return xedge(i, j + 1, offset, isolevelmin); 166 | default: 167 | return null; 168 | } 169 | } else { 170 | switch (isovertices[isopointindex][1]) { 171 | case 0: 172 | return xedge(i, j, offset, isolevelmax); 173 | case 1: 174 | return yedge(i, j, offset, isolevelmax); 175 | case 2: 176 | return yedge(i + 1, j, offset, isolevelmax); 177 | case 3: 178 | return xedge(i, j + 1, offset, isolevelmax); 179 | default: 180 | return null; 181 | } 182 | } 183 | } 184 | return null; 185 | } 186 | -------------------------------------------------------------------------------- /isovol2D/readme.md: -------------------------------------------------------------------------------- 1 | ![isovol2D](https://wblut.github.com/img/isovol2D.png) 2 | ![isovol2D_2](https://wblut.github.com/img/isovol2D_2.png) -------------------------------------------------------------------------------- /isovol2DDynamic/data.pde: -------------------------------------------------------------------------------- 1 | final static int ONVERTEX = 0; 2 | final static int ONEDGE = 1; 3 | final static int NEGATIVE = 0; 4 | final static int EQUAL = 1; 5 | final static int POSITIVE = 2; 6 | int[] digits = new int[4]; 7 | float[][] gridvertices=new float[][]{{0, 0}, {1, 0}, {0, 1}, {1, 1}}; 8 | final static int[][] edges = { { 0, 1 }, { 0, 2 }, { 1, 3 }}; 9 | static int[][] isovertices = new int[][] { { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, { 1, 2, 0 }, 10 | { 1, 2, 1 }, { 1, 3, 0 }, { 1, 3, 1 }, { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 } }; 11 | final static int[][] entries=new int[][] 12 | {{0}, 13 | {1, 0, 2, 8}, 14 | {2, 1, 0, 2, 3, 1, 2}, 15 | {1, 0, 9, 4}, 16 | {2, 4, 2, 8, 9, 4, 8}, 17 | {3, 1, 4, 3, 9, 4, 1, 4, 2, 3}, 18 | {2, 1, 4, 0, 5, 4, 1}, 19 | {3, 1, 5, 2, 8, 1, 2, 4, 2, 5}, 20 | {2, 4, 3, 5, 4, 2, 3}, 21 | {1, 2, 6, 10}, 22 | {2, 6, 8, 0, 10, 8, 6}, 23 | {3, 6, 3, 1, 10, 3, 6, 6, 1, 0}, 24 | {4, 6, 9, 4, 10, 9, 6, 10, 2, 9, 2, 0, 9}, 25 | {3, 4, 6, 9, 9, 6, 10, 9, 10, 8}, 26 | {4, 4, 6, 1, 9, 4, 1, 1, 6, 3, 6, 10, 3}, 27 | {5, 6, 5, 4, 10, 5, 6, 10, 1, 5, 10, 2, 1, 2, 0, 1}, 28 | {4, 8, 1, 10, 1, 5, 10, 4, 6, 5, 6, 10, 5}, 29 | {3, 4, 6, 5, 10, 3, 5, 6, 10, 5}, 30 | {2, 3, 2, 6, 7, 3, 6}, 31 | {3, 3, 0, 7, 8, 0, 3, 6, 7, 0}, 32 | {2, 6, 7, 1, 6, 1, 0}, 33 | {5, 6, 7, 4, 9, 7, 3, 4, 7, 9, 9, 3, 0, 2, 0, 3}, 34 | {4, 9, 3, 8, 9, 7, 3, 9, 4, 7, 4, 6, 7}, 35 | {3, 4, 6, 7, 9, 4, 7, 1, 9, 7}, 36 | {4, 6, 7, 5, 6, 5, 4, 2, 1, 3, 2, 0, 1}, 37 | {3, 8, 1, 3, 5, 4, 6, 7, 5, 6}, 38 | {2, 4, 6, 5, 5, 6, 7}, 39 | {1, 4, 11, 6}, 40 | {4, 6, 2, 8, 11, 6, 8, 11, 8, 4, 4, 8, 0}, 41 | {5, 6, 2, 3, 11, 6, 3, 11, 3, 1, 11, 1, 4, 4, 1, 0}, 42 | {2, 6, 0, 9, 11, 6, 9}, 43 | {3, 2, 8, 6, 6, 8, 11, 9, 11, 8}, 44 | {4, 2, 3, 6, 1, 11, 3, 9, 11, 1, 6, 3, 11}, 45 | {3, 6, 1, 5, 11, 6, 5, 6, 0, 1}, 46 | {4, 2, 1, 6, 8, 1, 2, 1, 5, 6, 6, 5, 11}, 47 | {3, 2, 3, 6, 5, 11, 3, 6, 3, 11}, 48 | {2, 4, 10, 2, 11, 10, 4}, 49 | {3, 0, 4, 8, 4, 11, 8, 10, 8, 11}, 50 | {4, 0, 4, 1, 1, 11, 3, 4, 11, 1, 10, 3, 11}, 51 | {3, 2, 0, 9, 10, 2, 9, 10, 9, 11}, 52 | {2, 9, 11, 10, 9, 10, 8}, 53 | {3, 9, 11, 1, 1, 11, 3, 11, 10, 3}, 54 | {4, 2, 0, 1, 10, 2, 1, 10, 1, 5, 10, 5, 11}, 55 | {3, 8, 1, 10, 1, 5, 10, 11, 10, 5}, 56 | {2, 5, 10, 3, 5, 11, 10}, 57 | {3, 4, 7, 3, 11, 7, 4, 4, 3, 2}, 58 | {4, 0, 4, 3, 8, 0, 3, 3, 4, 7, 4, 11, 7}, 59 | {3, 0, 4, 1, 7, 1, 11, 4, 11, 1}, 60 | {4, 0, 9, 3, 2, 0, 3, 3, 9, 7, 9, 11, 7}, 61 | {3, 9, 3, 8, 9, 7, 3, 9, 11, 7}, 62 | {2, 11, 7, 9, 9, 7, 1}, 63 | {3, 2, 0, 1, 2, 1, 3, 7, 5, 11}, 64 | {2, 11, 7, 5, 8, 1, 3}, 65 | {1, 5, 11, 7}, 66 | {2, 5, 6, 4, 7, 6, 5}, 67 | {5, 6, 2, 7, 8, 5, 7, 2, 8, 7, 8, 0, 5, 4, 5, 0}, 68 | {4, 6, 3, 7, 6, 2, 3, 4, 5, 1, 4, 1, 0}, 69 | {3, 5, 7, 0, 9, 5, 0, 6, 0, 7}, 70 | {4, 2, 7, 6, 8, 7, 2, 5, 7, 8, 9, 5, 8}, 71 | {3, 9, 5, 1, 3, 6, 2, 7, 6, 3}, 72 | {2, 6, 1, 7, 6, 0, 1}, 73 | {3, 2, 7, 6, 8, 7, 2, 1, 7, 8}, 74 | {2, 7, 6, 3, 3, 6, 2}, 75 | {3, 4, 5, 2, 5, 7, 2, 10, 2, 7}, 76 | {4, 0, 4, 5, 8, 0, 5, 8, 5, 7, 10, 8, 7}, 77 | {3, 10, 3, 7, 1, 0, 4, 5, 1, 4}, 78 | {4, 0, 9, 5, 2, 0, 5, 2, 5, 7, 10, 2, 7}, 79 | {3, 8, 7, 10, 5, 7, 8, 9, 5, 8}, 80 | {2, 9, 5, 1, 7, 10, 3}, 81 | {3, 2, 0, 1, 10, 2, 1, 10, 1, 7}, 82 | {2, 7, 8, 1, 7, 10, 8}, 83 | {1, 7, 10, 3}, 84 | {2, 4, 5, 3, 4, 3, 2}, 85 | {3, 0, 4, 5, 8, 0, 5, 3, 8, 5}, 86 | {2, 5, 1, 4, 1, 0, 4}, 87 | {3, 0, 9, 3, 2, 0, 3, 9, 5, 3}, 88 | {2, 8, 5, 3, 9, 5, 8}, 89 | {1, 9, 5, 1}, 90 | {2, 2, 0, 1, 2, 1, 3}, 91 | {1, 8, 1, 3}, 92 | {0}}; 93 | -------------------------------------------------------------------------------- /isovol2DDynamic/isovol2DDynamic.pde: -------------------------------------------------------------------------------- 1 | //Find all triangles between two isolevel contours for a grid of values 2 | //https://www.goodreads.com/book/show/16195572-isosurfaces 3 | 4 | List isotriangles,isotriangles2;//triangles between two isolevel contours 5 | int resx, resy;//resolution of grid 6 | float cx, cy;//center of grid 7 | float dx, dy;//size of grid cell 8 | float zFactor;//(grid values) x zFactor = height of triangle vertices 9 | 10 | 11 | void setup() { 12 | size(800, 800, P3D); 13 | smooth(16); 14 | resx=100; 15 | resy=100; 16 | 17 | cx=0; 18 | cy=0; 19 | dx=5; 20 | dy=5; 21 | zFactor=200.0; 22 | } 23 | 24 | //This function returns the values of (resX+1)x(resY+1) data points 25 | float getValue(int i, int j) { 26 | return 1.0-2.0*(noise(0.025*i, 0.025*j,0.0025*frameCount)-0.1)/0.8 ; 27 | } 28 | 29 | void draw() { 30 | background(255); 31 | 32 | translate(width/2, height/2); 33 | lights(); 34 | rotateY(map(mouseX, 0, width, -PI, PI)); 35 | rotateX(map(mouseY, 0, height, PI, -PI)); 36 | isotriangles2=getTriangles(-1.0, 1.0, color(255)); 37 | noFill(); 38 | stroke(0); 39 | for (Triangle triangle : isotriangles2) { 40 | triangle.draw(); 41 | } 42 | noStroke(); 43 | isotriangles=getTriangles((frameCount%100)*0.02-1.0, (frameCount%100)*0.02-.9, color(255,0,0)); 44 | for (Triangle triangle : isotriangles) { 45 | fill(triangle.col); 46 | triangle.draw(); 47 | } 48 | 49 | 50 | } 51 | 52 | class Point { 53 | float x, y, z; 54 | Point(float x, float y, float z) { 55 | this.x=x; 56 | this.y=y; 57 | this.z=z; 58 | } 59 | } 60 | 61 | class Triangle { 62 | Point p1, p2, p3; 63 | color col; 64 | Triangle(Point p1, Point p2, Point p3, color col) { 65 | this.p1=new Point(p1.x, p1.y, p1.z); 66 | this.p2=new Point(p2.x, p2.y, p2.z); 67 | this.p3=new Point(p3.x, p3.y, p3.z); 68 | this.col=col; 69 | } 70 | 71 | void draw() { 72 | 73 | beginShape(); 74 | vertex(p1.x, p1.y, p1.z); 75 | vertex(p2.x, p2.y, p2.z); 76 | vertex(p3.x, p3.y, p3.z); 77 | endShape(CLOSE); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /isovol2DDynamic/marchingSquaresVOL.pde: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | import java.util.HashMap; 3 | import java.util.List; 4 | 5 | Map xedges; 6 | Map yedges; 7 | Map vertices; 8 | float isolevelmin; 9 | float isolevelmax; 10 | List triangles; 11 | 12 | int index(int i, int j) { 13 | return i+1 +(resx+2)*(j+1); 14 | } 15 | 16 | 17 | 18 | Point vertex(final int i, final int j, final Point offset) { 19 | Point vertex = vertices.get(index(i, j)); 20 | if (vertex != null) { 21 | return vertex; 22 | } 23 | vertex = new Point(i * dx+offset.x, j * dy+offset.y, zFactor * getValue(i, j)+offset.z); 24 | vertices.put(index(i, j), vertex); 25 | return vertex; 26 | } 27 | 28 | Point interp(final float isolevel, final Point p1, final Point p2, final float valp1, 29 | final float valp2, Point offset) { 30 | if (isolevel==valp1) { 31 | return new Point(p1.x +offset.x, p1.y+offset.y, zFactor * isolevel); 32 | } 33 | if (isolevel==valp2) { 34 | return new Point(p2.x+offset.x, p2.y+offset.y, zFactor * isolevel); 35 | } 36 | if (valp1==valp2) { 37 | return new Point(p1.x+offset.x, p1.y+offset.y, zFactor * isolevel); 38 | } 39 | float mu = (isolevel - valp1) / (valp2 - valp1); 40 | return new Point(p1.x + mu * (p2.x - p1.x)+offset.x, p1.y + mu * (p2.y - p1.y)+offset.y, zFactor * isolevel); 41 | } 42 | 43 | Point xedge(final int i, final int j, final Point offset, final float isolevel) { 44 | Point xedge = xedges.get(index(i, j)); 45 | if (xedge != null) { 46 | return xedge; 47 | } 48 | final Point p0 = new Point(i * dx, j * dy, 0); 49 | final Point p1 = new Point(i * dx + dx, j * dy, 0); 50 | final float val0 = getValue(i, j); 51 | final float val1 = getValue(i + 1, j); 52 | xedge = interp(isolevel, p0, p1, val0, val1, offset); 53 | xedges.put(index(i, j), xedge); 54 | return xedge; 55 | } 56 | 57 | Point yedge(final int i, final int j, final Point offset, final float isolevel) { 58 | Point yedge = yedges.get(index(i, j)); 59 | if (yedge != null) { 60 | return yedge; 61 | } 62 | final Point p0 = new Point(i * dx, j * dy, 0); 63 | final Point p1 = new Point(i * dx, j * dy + dy, 0); 64 | final float val0 = getValue(i, j); 65 | final float val1 = getValue(i, j + 1); 66 | yedge =interp(isolevel, p0, p1, val0, val1, offset); 67 | yedges.put(index(i, j), yedge); 68 | return yedge; 69 | } 70 | 71 | int classifyCell(final int i, final int j) { 72 | if (i < 0 || j < 0 || i >= resx || j >= resy) { 73 | return -1; 74 | } 75 | digits = new int[8]; 76 | int cubeindex = 0; 77 | int offset = 1; 78 | if (getValue(i, j) > isolevelmax) { 79 | cubeindex += 2 * offset; 80 | digits[0] = POSITIVE; 81 | } else if (getValue(i, j) >= isolevelmin) { 82 | cubeindex += offset; 83 | digits[0] = EQUAL; 84 | } 85 | offset *= 3; 86 | if (getValue(i + 1, j) > isolevelmax) { 87 | cubeindex += 2 * offset; 88 | digits[1] = POSITIVE; 89 | } else if (getValue(i + 1, j) >= isolevelmin) { 90 | cubeindex += offset; 91 | digits[1] = EQUAL; 92 | } 93 | offset *= 3; 94 | if (getValue(i, j + 1) > isolevelmax) { 95 | cubeindex += 2 * offset; 96 | digits[2] = POSITIVE; 97 | } else if (getValue(i, j + 1) >= isolevelmin) { 98 | cubeindex += offset; 99 | digits[2] = EQUAL; 100 | } 101 | offset *= 3; 102 | if (getValue(i + 1, j + 1) > isolevelmax) { 103 | cubeindex += 2 * offset; 104 | digits[3] = POSITIVE; 105 | } else if (getValue(i + 1, j + 1) >= isolevelmin) { 106 | cubeindex += offset; 107 | digits[3] = EQUAL; 108 | } 109 | return cubeindex; 110 | } 111 | 112 | List getTriangles(float isomin, float isomax, color col) { 113 | isolevelmin=isomin; 114 | isolevelmax=isomax; 115 | xedges = new HashMap(); 116 | yedges = new HashMap(); 117 | vertices = new HashMap(); 118 | final Point offset = new Point(cx - 0.5 * resx * dx, cy - 0.5 * resy * dy, 0); 119 | triangles = new ArrayList(); 120 | for (int i = 0; i < resx; i++) { 121 | for (int j = 0; j < resy; j++) { 122 | triangulate(i, j, classifyCell(i, j), offset, col); 123 | } 124 | } 125 | return triangles; 126 | } 127 | 128 | void triangulate(final int i, final int j, final int cubeindex, final Point offset, color col) { 129 | final int[] indices = entries[cubeindex]; 130 | final int numtris = indices[0]; 131 | int currentindex = 1; 132 | for (int t = 0; t < numtris; t++) { 133 | final Point v2 = getIsoVertex(indices[currentindex++], i, j, offset); 134 | final Point v1 = getIsoVertex(indices[currentindex++], i, j, offset); 135 | final Point v3 = getIsoVertex(indices[currentindex++], i, j, offset); 136 | triangles.add(new Triangle(v1, v2, v3,col)); 137 | } 138 | 139 | } 140 | 141 | Point getIsoVertex(final int isopointindex, final int i, final int j, final Point offset) { 142 | if (isovertices[isopointindex][0] == ONVERTEX) { 143 | switch (isovertices[isopointindex][1]) { 144 | case 0: 145 | return vertex(i, j, offset); 146 | case 1: 147 | return vertex(i + 1, j, offset); 148 | case 2: 149 | return vertex(i, j + 1, offset); 150 | case 3: 151 | return vertex(i + 1, j + 1, offset); 152 | default: 153 | return null; 154 | } 155 | } else if (isovertices[isopointindex][0] == ONEDGE) { 156 | if (isovertices[isopointindex][2] == 0) { 157 | switch (isovertices[isopointindex][1]) { 158 | case 0: 159 | return xedge(i, j, offset, isolevelmin); 160 | case 1: 161 | return yedge(i, j, offset, isolevelmin); 162 | case 2: 163 | return yedge(i + 1, j, offset, isolevelmin); 164 | case 3: 165 | return xedge(i, j + 1, offset, isolevelmin); 166 | default: 167 | return null; 168 | } 169 | } else { 170 | switch (isovertices[isopointindex][1]) { 171 | case 0: 172 | return xedge(i, j, offset, isolevelmax); 173 | case 1: 174 | return yedge(i, j, offset, isolevelmax); 175 | case 2: 176 | return yedge(i + 1, j, offset, isolevelmax); 177 | case 3: 178 | return xedge(i, j + 1, offset, isolevelmax); 179 | default: 180 | return null; 181 | } 182 | } 183 | } 184 | return null; 185 | } 186 | -------------------------------------------------------------------------------- /isovol2DDynamic/readme.md: -------------------------------------------------------------------------------- 1 | ![isovol2DDynamic](https://wblut.github.com/img/isovol2DDynamic.png) -------------------------------------------------------------------------------- /matcap/data/500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wblut/Processing3Sketches/93240ead4d38e53ef46a8de67a3759fd443257f3/matcap/data/500.png -------------------------------------------------------------------------------- /matcap/data/MatCapFrag.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D matcap; 4 | varying vec3 eyeNormal; 5 | 6 | uniform float range=1.1; 7 | void main() { 8 | vec2 uv = range*0.5*vec2(normalize(eyeNormal).xy)+vec2(0.5); 9 | gl_FragColor = gl_FrontFacing ?texture2D(matcap,vec2(uv.x,1.0-uv.y)):texture2D(matcap,vec2(1.0-uv.x,uv.y)); 10 | } 11 | -------------------------------------------------------------------------------- /matcap/data/MatCapVert.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_COLOR_SHADER 2 | 3 | uniform mat4 transformMatrix; 4 | uniform mat3 normalMatrix; 5 | 6 | attribute vec4 position; 7 | attribute vec3 normal; 8 | 9 | varying vec3 eyeNormal; 10 | 11 | void main() { 12 | eyeNormal= normalMatrix*normal; 13 | gl_Position = transformMatrix * position; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /matcap/matcap.pde: -------------------------------------------------------------------------------- 1 | PShader matcap; 2 | float range; 3 | PShape shape; 4 | public void setup() { 5 | size(600, 600, P3D); 6 | smooth(8); 7 | matcap=loadShader("MatCapFrag.glsl", "MatCapVert.glsl"); 8 | range=0.98; 9 | matcap.set("range", range); 10 | matcap.set("matcap", loadImage("500.png")); 11 | shape=createShape(); 12 | shape.beginShape(TRIANGLES); 13 | for (int i=-100; i<100; i++) { 14 | for (int j=-100; j<100; j++) { 15 | shape.vertex(i*2, j*2, bump(i, j)); 16 | shape.vertex((i+1)*2, j*2, bump(i+1, j)); 17 | shape.vertex((i+1)*2, (j+1)*2, bump(i+1, j+1)); 18 | shape.vertex(i*2, j*2, bump(i, j)); 19 | shape.vertex((i+1)*2, (j+1)*2, bump(i+1, j+1)); 20 | shape.vertex(i*2, (j+1)*2, bump(i, j+1)); 21 | } 22 | } 23 | shape.endShape(); 24 | shape.disableStyle(); 25 | } 26 | 27 | void draw() { 28 | background(25); 29 | translate(width / 2, height / 2); 30 | rotateY(map(mouseX, 0, width, -PI, PI)); 31 | rotateX(map(mouseY, 0, height, PI, -PI)); 32 | scale(1.0); 33 | noLights(); 34 | shader(matcap); 35 | noStroke(); 36 | shape(shape); 37 | } 38 | 39 | float bump(int i, int j) { 40 | return 40*cos(radians(0.1*i*j)); 41 | } 42 | -------------------------------------------------------------------------------- /matcap/readme.md: -------------------------------------------------------------------------------- 1 | ![matcap](https://wblut.github.com/img/matcap.png) 2 | -------------------------------------------------------------------------------- /perpetualDiamond/perpetualDiamond.pde: -------------------------------------------------------------------------------- 1 | void setup() { 2 | size(800, 800); 3 | smooth(8); 4 | frameRate(30); 5 | } 6 | 7 | 8 | void draw() { 9 | float backgroundAngle= frameCount*24; //2hz = 720°/s = 24°/frame 10 | background(120+80*sin(radians(backgroundAngle))); 11 | translate(width/2, height/2); 12 | 13 | float phaseShiftUL=-90; 14 | float phaseShiftUR=+90; 15 | float phaseShiftLL=-90; 16 | float phaseShiftLR=+90; 17 | 18 | //edges 19 | strokeWeight(3.0); 20 | 21 | float edgeAngleUL= frameCount*24+phaseShiftUL; 22 | stroke(80+120*sin(radians(edgeAngleUL))); 23 | line(-200, 0, 0, -200); 24 | 25 | float edgeAngleUR= frameCount*24+phaseShiftUR; 26 | stroke(80+120*sin(radians(edgeAngleUR))); 27 | line(200, 0, 0, -200); 28 | 29 | float edgeAngleLL= frameCount*24+phaseShiftLL; 30 | stroke(80+120*sin(radians(edgeAngleLL))); 31 | line(-200,0,0, 200); 32 | 33 | float edgeAngleLR= frameCount*24+phaseShiftLR; 34 | stroke(80+120*sin(radians(edgeAngleLR))); 35 | line(200, 0, 0, 200); 36 | 37 | //diamond 38 | noStroke(); 39 | fill(120); 40 | beginShape(); 41 | vertex(-200, 0); 42 | vertex(0, -200); 43 | vertex(200, 0); 44 | vertex(0, 200); 45 | endShape(); 46 | } 47 | -------------------------------------------------------------------------------- /perpetualDiamond/readme.md: -------------------------------------------------------------------------------- 1 | ![Perpetual Diamond](https://wblut.github.io/img/perpetualDiamond.png) 2 | -------------------------------------------------------------------------------- /pixelFont/pixelFont.pde: -------------------------------------------------------------------------------- 1 | void setup() { 2 | fullScreen(P3D); 3 | smooth(); 4 | rectMode(CENTER); 5 | } 6 | 7 | void draw() { 8 | background(255); 9 | translate(width/2, height/2); 10 | noStroke(); 11 | fill(128); 12 | scale(-1, 1); 13 | draw3xN("abcdefghijklmnopqrstuvwxyz", 0, 50, 9, 50, 15); 14 | draw3x3("abcdefghijklmnopqrstuvwxyz", 0, -100, 50, 15); 15 | fill(0); 16 | scale(-1, 1); 17 | draw3xN("abcdefghijklmnopqrstuvwxyz", 0, 50, 9, 50, 15); 18 | draw3x3("abcdefghijklmnopqrstuvwxyz", 0, -100, 50, 15); 19 | } 20 | 21 | void draw3x3(String text, float cx, float cy, float size, float spacing) { 22 | float cs=size/3.0f; 23 | pushMatrix(); 24 | translate(-0.5*(text.length()*(size+spacing)-spacing), -0.5*size); 25 | float offset=0; 26 | for (int i=0; i>id)&1)==1) { 39 | //if(300*noise(0.0035*(lx+size*i),0.0035*(ly+size*j))>i)&1)==1) { 173 | rect(lx+size*(i+0.5), ly+size*(j+.5), size, size); 174 | } 175 | } 176 | } 177 | } 178 | 179 | int[] code3xN(char c) { 180 | /* 181 | 182 | 1 | 2 | 4 183 | 184 | 0 185 | 1 186 | 2 187 | 3 188 | . 189 | . 190 | 3 191 | 4 192 | 5 193 | 194 | */ 195 | switch(c) { 196 | case '/': 197 | return new int[]{4, 4, 2, 2, 1, 1}; 198 | case 'a': 199 | return new int[]{7, 5, 7, 5, 5, 5}; 200 | case 'b': 201 | return new int[]{7, 5, 3, 5, 5, 7}; 202 | case 'c': 203 | return new int[]{7, 1, 1, 1, 1, 7}; 204 | case 'd': 205 | return new int[]{3, 5, 5, 5, 5, 3}; 206 | case 'e': 207 | return new int[]{7, 1, 3, 1, 1, 7}; 208 | case 'f': 209 | return new int[]{7, 1, 3, 1, 1, 1}; 210 | case 'g': 211 | return new int[]{6, 1, 1, 5, 5, 7}; 212 | case 'h': 213 | return new int[]{5, 5, 7, 5, 5, 5}; 214 | case 'i': 215 | return new int[]{7, 2, 2, 2, 2, 7}; 216 | case 'j': 217 | return new int[]{7, 2, 2, 2, 2, 3}; 218 | case 'k': 219 | return new int[]{5, 5, 3, 5, 5, 5}; 220 | case 'l': 221 | return new int[]{1, 1, 1, 1, 1, 7}; 222 | case 'm': 223 | return new int[]{5, 7, 7, 5, 5, 5}; 224 | case 'n': 225 | return new int[]{3, 7, 5, 5, 5, 5}; 226 | case 'o': 227 | return new int[]{2, 5, 5, 5, 5, 2}; 228 | case 'p': 229 | return new int[]{7, 5, 7, 1, 1, 1}; 230 | case 'q': 231 | return new int[]{2, 5, 5, 5, 5, 6}; 232 | case 'r': 233 | return new int[]{7, 5, 3, 5, 5, 5}; 234 | case 's': 235 | return new int[]{7, 1, 7, 4, 4, 7}; 236 | case 't': 237 | return new int[]{7, 2, 2, 2, 2, 2}; 238 | case 'u': 239 | return new int[]{5, 5, 5, 5, 5, 7}; 240 | case 'v': 241 | return new int[]{5, 5, 5, 5, 5, 2}; 242 | case 'w': 243 | return new int[]{5, 5, 7, 7, 7, 2}; 244 | case 'x': 245 | return new int[]{5, 5, 2, 5, 5, 5}; 246 | case 'y': 247 | return new int[]{5, 5, 2, 2, 2, 2}; 248 | case 'z': 249 | return new int[]{7, 4, 7, 1, 1, 7}; 250 | case '0': 251 | return new int[]{7, 5, 5, 5, 5, 7}; 252 | case '1': 253 | return new int[]{3, 2, 2, 2, 2, 7}; 254 | case '2': 255 | return new int[]{7, 4, 7, 1, 1, 7}; 256 | case '3': 257 | return new int[]{7, 4, 7, 4, 4, 7}; 258 | case '4': 259 | return new int[]{5, 5, 7, 4, 4, 4}; 260 | case '5': 261 | return new int[]{7, 1, 7, 4, 4, 7}; 262 | case '6': 263 | return new int[]{7, 1, 7, 5, 5, 7}; 264 | case '7': 265 | return new int[]{7, 4, 4, 4, 4, 4}; 266 | case '8': 267 | return new int[]{7, 5, 7, 5, 5, 7}; 268 | case '9': 269 | return new int[]{7, 5, 7, 4, 4, 7}; 270 | case '.': 271 | return new int[] {0, 0, 0, 0, 0, 1}; 272 | case ',': 273 | return new int[] {0, 0, 0, 0, 1, 1}; 274 | case '\'': 275 | return new int[] {1, 1, 0, 0, 0, 0}; 276 | case '-': 277 | return new int[] {0, 0, 7, 0, 0, 0}; 278 | case ':': 279 | return new int[]{0, 2, 0, 0, 2, 0}; 280 | case '?': 281 | return new int[] {7, 4, 3, 1, 0, 1}; 282 | case '!': 283 | return new int[] {1, 1, 1, 1, 0, 1}; 284 | default: 285 | return new int[]{0, 0, 0, 0, 0, 0}; 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /pixelFont/readme.md: -------------------------------------------------------------------------------- 1 | ![Pixel Font](https://wblut.github.io/img/pixelFont.png) 2 | -------------------------------------------------------------------------------- /sliceSaga/sliceBox/fragments.pde: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wblut/Processing3Sketches/93240ead4d38e53ef46a8de67a3759fd443257f3/sliceSaga/sliceBox/fragments.pde -------------------------------------------------------------------------------- /sliceSaga/sliceBox/sliceBox.pde: -------------------------------------------------------------------------------- 1 | ArrayList sliceBoxes; 2 | int GAP; 3 | float CHANCE; 4 | 5 | void setup() { 6 | size(1000, 1000, P3D); 7 | smooth(16); 8 | sliceBoxes=new ArrayList (); 9 | SliceBox sliceBox=new SliceBox(); 10 | sliceBox.createBoxWithCenterAndSize(0, 0, 0, 300, 300, 300); 11 | sliceBoxes.add( sliceBox); 12 | GAP=20; 13 | CHANCE=1.0; 14 | } 15 | 16 | void draw() { 17 | background(250); 18 | translate(width/2, height/2); 19 | lights(); 20 | rotateY(map(mouseX, 0, width, -PI, PI)); 21 | rotateX(map(mouseY, 0, height, PI, -PI)); 22 | hint(DISABLE_DEPTH_MASK); 23 | stroke(0); 24 | fill(0, 25); 25 | for (SliceBox sliceBox : sliceBoxes) { 26 | sliceBox.draw(); 27 | } 28 | hint(ENABLE_DEPTH_MASK); 29 | } 30 | 31 | void slice(PVector origin, PVector normal, float gap, float chance) { 32 | ArrayList newSliceBoxes=new ArrayList (); 33 | PVector N=new PVector(normal.x, normal.y, normal.z); 34 | N.normalize(); 35 | PVector Nflip=new PVector(-N.x, -N.y, -N.z); 36 | for (SliceBox sliceBox : sliceBoxes) { 37 | if (random(1.0)0) newSliceBoxes.add(sliceBox); 41 | copy.slice(origin, Nflip, 0.5*gap); 42 | if (copy.isValid() && copy.vertices.size()>0) newSliceBoxes.add(copy); 43 | } else { 44 | newSliceBoxes.add(sliceBox); 45 | } 46 | } 47 | sliceBoxes=newSliceBoxes; 48 | } 49 | 50 | void mousePressed() { 51 | PVector normal=new PVector(random(-1, 1), random(-1, 1), random(-1, 1)); 52 | /* 53 | int roll=(int)random(3.0); 54 | switch(roll) { 55 | case 0: 56 | normal=new PVector(1, 0, 0); 57 | break; 58 | case 1: 59 | normal=new PVector(0, 1, 0); 60 | break; 61 | default: 62 | normal=new PVector(0, 0, 1); 63 | } 64 | */ 65 | PVector origin=new PVector(40*(int)random(-4, 5), 40*(int)random(-4, 5), 40*(int)random(-4, 5)); 66 | slice(origin, normal, GAP, CHANCE); 67 | } 68 | -------------------------------------------------------------------------------- /sliceSaga/sliceBox/transforms.pde: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wblut/Processing3Sketches/93240ead4d38e53ef46a8de67a3759fd443257f3/sliceSaga/sliceBox/transforms.pde -------------------------------------------------------------------------------- /sliceSaga/sliceHalfedge/sliceHalfedge.pde: -------------------------------------------------------------------------------- 1 | HalfedgeMesh mesh; 2 | 3 | void setup() { 4 | size(800, 800, P3D); 5 | smooth(16); 6 | float[][] vertices=new float[][]{{-100, -100, -100}, {100, -100, -100}, {100, 100, -100}, {-100, 100, -100}, {-100, -100, 100}, {100, -100, 100}, {100, 100, 100}, {-100, 100, 100}}; 7 | int[][] faces=new int[][]{{0, 1, 2, 3}, {7, 6, 5, 4}, {1, 0, 4, 5}, {3, 2, 6, 7}, {2, 1, 5, 6}, {0, 3, 7, 4}}; 8 | 9 | mesh=new HalfedgeMesh(); 10 | mesh.create(vertices, faces); 11 | } 12 | 13 | void draw() { 14 | background(250); 15 | translate(width/2, height/2); 16 | lights(); 17 | rotateY(map(mouseX, 0, width, -PI, PI)); 18 | rotateX(map(mouseY, 0, height, PI, -PI)); 19 | mesh.draw(); 20 | } 21 | 22 | void mousePressed() { 23 | mesh.split(new Point(random(-50, 50), random(-50, 50), random(-50, 50)), new Vector(random(-1, 1), random(-1, 1), random(-1, 1))); 24 | } 25 | 26 | class Halfedge { 27 | Halfedge pair; 28 | Halfedge next; 29 | Halfedge prev; 30 | Vertex v; 31 | Face f; 32 | Edge e; 33 | 34 | Halfedge() { 35 | } 36 | 37 | Halfedge nextInVertex() { 38 | return pair.next; 39 | } 40 | 41 | Halfedge prevInVertex() { 42 | return prev.pair; 43 | } 44 | } 45 | 46 | class Vertex { 47 | float x, y, z; 48 | Halfedge he; 49 | int index; 50 | Vertex(float x, float y, float z, int i) { 51 | this.x=x; 52 | this.y=y; 53 | this.z=z; 54 | this.index=i; 55 | } 56 | } 57 | 58 | 59 | class Edge { 60 | Halfedge he; 61 | Edge() { 62 | } 63 | } 64 | 65 | class Face { 66 | Halfedge he; 67 | Face() { 68 | } 69 | } 70 | 71 | class HalfedgeMesh { 72 | ArrayList halfedges; 73 | ArrayList vertices; 74 | ArrayList faces; 75 | ArrayList edges; 76 | 77 | HalfedgeMesh() { 78 | initialize(); 79 | } 80 | 81 | void initialize() { 82 | halfedges=new ArrayList(); 83 | vertices=new ArrayList(); 84 | faces=new ArrayList(); 85 | edges=new ArrayList(); 86 | } 87 | 88 | void create(float[][] vertexArray, int[][] faceArray) { 89 | initialize(); 90 | for (float[] vertex : vertexArray) { 91 | createVertex(vertex); 92 | } 93 | for (int[] face : faceArray) { 94 | createFace(face); 95 | } 96 | createEdges(); 97 | } 98 | 99 | void createVertex(float... vertex) { 100 | vertices.add(new Vertex(vertex[0], vertex[1], vertex[2], vertices.size())); 101 | } 102 | 103 | void createFace(int[] face) { 104 | Face f=new Face(); 105 | faces.add(f); 106 | Vertex v; 107 | Halfedge he; 108 | ArrayList faceHalfedges=new ArrayList(); 109 | for (int i=0; i intersections=new ArrayList(); 206 | int es=edges.size(); 207 | for (int i=0; i intersections) { 218 | Halfedge he=e.he; 219 | Halfedge hep=he.pair; 220 | Vertex v=he.v; 221 | Vertex vp=hep.v; 222 | Vector u=new Vector(vp.x-v.x, vp.y-v.y, vp.z-v.z); 223 | Vector w=new Vector(v.x-origin.x, v.y-origin.y, v.z-origin.z); 224 | float D=normal.dot(u); 225 | float N=-normal.dot(w); 226 | if (abs(D)<0.0001) { 227 | return; 228 | } 229 | float f=N/D; 230 | if (f<-0.0001||f>1.0001) { 231 | return; 232 | } else if (f<0.0001) { 233 | intersections.add(new EdgeIntersection(e, v)); 234 | } else if (f>0.9999) { 235 | intersections.add(new EdgeIntersection(e, vp)); 236 | } else { 237 | splitEdge(e, f); 238 | Vertex nv=vertices.get(vertices.size()-1); 239 | intersections.add(new EdgeIntersection(e, nv)); 240 | } 241 | } 242 | 243 | void splitFace(Face f, ArrayList intersections) { 244 | Vertex vi=null; 245 | Vertex vj=null; 246 | for (EdgeIntersection ei : intersections) { 247 | if (ei.e.he.f==f || ei.e.he.pair.f==f) { 248 | if (vi==null) { 249 | vi=ei.v; 250 | } else 251 | if (vi!=ei.v) { 252 | vj=ei.v; 253 | break; 254 | } 255 | } 256 | } 257 | if (vi!=null&&vj!=null) splitFace(f, vi.index, vj.index); 258 | } 259 | 260 | void splitFace(Face f, int i, int j) { 261 | Vertex vi=vertices.get(i); 262 | Halfedge hei=f.he; 263 | while (hei.v!=vi) { 264 | hei=hei.next; 265 | if (hei==f.he) return; 266 | } 267 | 268 | Vertex vj=vertices.get(j); 269 | Halfedge hej=f.he; 270 | while (hej.v!=vj) { 271 | hej=hej.next; 272 | if (hej==f.he) return; 273 | } 274 | 275 | if (hei.next==hej || hej.next==hei) return; 276 | 277 | Halfedge heip=hei.prev; 278 | Halfedge hejp=hej.prev; 279 | Halfedge heNew=new Halfedge(); 280 | Halfedge hepNew=new Halfedge(); 281 | connectVertex(vi, hepNew); 282 | connectVertex(vj, heNew); 283 | pairHalfedges(heNew, hepNew); 284 | createEdge(heNew); 285 | halfedges.add(heNew); 286 | halfedges.add(hepNew); 287 | connectHalfedges(heip, hepNew); 288 | connectHalfedges(hepNew, hej); 289 | connectHalfedges(hejp, heNew); 290 | connectHalfedges(heNew, hei); 291 | heNew.f=f; 292 | Halfedge he=hej; 293 | Face nf=new Face(); 294 | faces.add(nf); 295 | do { 296 | connectFace(nf, he); 297 | he=he.next; 298 | } while (he!=hej); 299 | f.he=hei; 300 | } 301 | 302 | void draw() { 303 | Halfedge he; 304 | for (Face f : faces) { 305 | beginShape(); 306 | he=f.he; 307 | do { 308 | vertex(he.v.x, he.v.y, he.v.z); 309 | he=he.next; 310 | } while (he!=f.he); 311 | endShape(CLOSE); 312 | } 313 | 314 | for (Vertex v : vertices) { 315 | pushMatrix(); 316 | translate(v.x, v.y, v.z); 317 | box(2); 318 | popMatrix(); 319 | } 320 | 321 | } 322 | } 323 | 324 | 325 | class Point { 326 | float x, y, z; 327 | Point(float x, float y, float z) { 328 | this.x=x; 329 | this.y=y; 330 | this.z=z; 331 | } 332 | } 333 | 334 | class Vector { 335 | float x, y, z; 336 | Vector(float x, float y, float z) { 337 | this.x=x; 338 | this.y=y; 339 | this.z=z; 340 | } 341 | 342 | float dot(Vector v) { 343 | return x*v.x+y*v.y+z*v.z; 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/donothing.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | 8 | gl_FragColor = texture2D(texture, vertTexCoord.xy); 9 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/mirrord.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vec2(0.5+abs(vertTexCoord.x-0.5),0.5+abs(vertTexCoord.y-0.5)); 8 | 9 | gl_FragColor = texture2D(texture, p); 10 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/mirrorx.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.x < 0.5 ? vertTexCoord.xy : vec2(1.0-vertTexCoord.x, vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/mirrorxy.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.x < 0.5 ? vertTexCoord.xy : vec2(1.0-vertTexCoord.x, vertTexCoord.y); 8 | p= p.y < 0.5 ? p.xy : vec2(p.x, 1.0-p.y); 9 | gl_FragColor = texture2D(texture, p); 10 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/mirrory.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | uniform sampler2D texture; 4 | varying vec4 vertTexCoord; 5 | 6 | void main(void) { 7 | vec2 p = vertTexCoord.y > 0.5 ? vertTexCoord.xy : vec2(vertTexCoord.x, 1.0-vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/data/vignette.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | precision mediump int; 6 | #endif 7 | 8 | uniform sampler2D texture; 9 | uniform vec2 resolution; 10 | varying vec4 vertColor; 11 | varying vec4 vertTexCoord; 12 | 13 | const float RADIUS = 0.75; 14 | const float SOFTNESS = 0.45; 15 | const vec3 SEPIA = vec3(1.0, 0.8, 0.6); 16 | 17 | 18 | void main(void) { 19 | vec4 texColor = texture2D(texture,vertTexCoord.xy); 20 | vec2 position = (gl_FragCoord.xy / resolution.xy) - vec2(0.5); 21 | float len = length(position); 22 | float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len); 23 | texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5); 24 | float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); 25 | vec3 sepiaColor = vec3(gray) * SEPIA; 26 | texColor.rgb = mix(texColor.rgb, sepiaColor, 0.1); 27 | gl_FragColor = texColor * vertColor; 28 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop/fragmenttree.pde: -------------------------------------------------------------------------------- 1 | class FragmentTree { 2 | ArrayList roots; 3 | 4 | FragmentTree(SliceMesh mesh) { 5 | roots=new ArrayList(); 6 | roots.add(new Fragment(mesh)); 7 | } 8 | 9 | FragmentTree(ArrayList meshes) { 10 | roots=new ArrayList(); 11 | for (SliceMesh mesh : meshes) { 12 | roots.add(new Fragment(mesh)); 13 | } 14 | } 15 | 16 | FragmentTree(SliceMesh... meshes) { 17 | roots=new ArrayList(); 18 | for (SliceMesh mesh : meshes) { 19 | roots.add(new Fragment(mesh)); 20 | } 21 | } 22 | 23 | void split(Transformation M, color col, color col2) { 24 | for (Fragment root : roots) { 25 | root.split(M, col, col2); 26 | } 27 | } 28 | 29 | void setPhase(float f) { 30 | for (Fragment root : roots) { 31 | root.setPhase(f); 32 | } 33 | } 34 | 35 | float[] getExtents() { 36 | float[] extents=new float[]{1000000, 1000000, 1000000, -1000000, -1000000, -1000000}; 37 | for (Fragment root : roots) { 38 | root.addExtents(extents); 39 | } 40 | return extents; 41 | } 42 | 43 | void draw() { 44 | for (Fragment root : roots) { 45 | root.draw(); 46 | } 47 | } 48 | 49 | void draw(PImage[] textures) { 50 | for (Fragment root : roots) { 51 | root.draw(textures); 52 | } 53 | } 54 | 55 | float minDistance(Plane P) { 56 | float minDistance=1000000; 57 | for (Fragment root : roots) { 58 | minDistance=min(minDistance, root.minDistance(P)); 59 | } 60 | return minDistance; 61 | } 62 | } 63 | 64 | 65 | 66 | class Fragment { 67 | Fragment parent; 68 | Fragment child1, child2; 69 | Transformation parentToChild; 70 | SliceMesh mesh; 71 | SliceMesh invTMesh; 72 | SliceMesh dynMesh; 73 | SliceMesh drawMesh; 74 | int level; 75 | 76 | Fragment(SliceMesh mesh) { 77 | this.mesh = mesh.copy(); 78 | invTMesh = mesh.copy(); 79 | dynMesh = mesh.copy(); 80 | parentToChild = null; 81 | parent = null; 82 | child1 = null; 83 | child2 = null; 84 | level = 0; 85 | } 86 | 87 | Fragment(SliceMesh mesh, Fragment parent, Transformation parentToChild) { 88 | this.mesh = mesh.copy(); 89 | dynMesh= mesh.copy(); 90 | this.parentToChild = parentToChild; 91 | this.parent = parent; 92 | invTMesh = mesh.copy(); 93 | Fragment p = this; 94 | do { 95 | if ( p.parentToChild!=null) { 96 | Transform T = p.parentToChild.getInverseTransform(1.0); 97 | T.apply(invTMesh); 98 | } 99 | p = p.parent; 100 | } while (p != null); 101 | level=parent.level+1; 102 | } 103 | 104 | void split(Transformation M, color col, color col2) { 105 | if ((child1 == null) && (child2 == null)) { 106 | SliceMesh split1=mesh.copy(); 107 | SliceMesh split2=mesh.copy(); 108 | split1.slice(M.plane, 0.0, col); 109 | split2.slice(M.plane.flip(), 0.0, col2); 110 | if (split1.vertices.size() > 0 && split1.isValid()) { 111 | child1 = new Fragment(split1, this, null); 112 | } 113 | if (split2.vertices.size() > 0 && split2.isValid()) { 114 | M.getTransform(1.0).apply(split2); 115 | child2 = new Fragment(split2, this, M); 116 | } 117 | } else { 118 | if (child1 != null) { 119 | child1.split(M, col, col2); 120 | } 121 | if (child2 != null) { 122 | child2.split(M, col2, col); 123 | } 124 | } 125 | } 126 | 127 | 128 | float minDistance(Plane P) { 129 | float minDistance=1000000; 130 | if (((child1 == null) && (child2 == null))) {//||f<=level) { 131 | for (Vertex v : mesh.vertices) { 132 | minDistance=min(minDistance, v.distance(P)); 133 | if(minDistance<5.0) return minDistance; 134 | } 135 | } else { 136 | if (child1 != null) { 137 | minDistance=min(minDistance, child1.minDistance(P)); 138 | } 139 | if (child2 != null) { 140 | minDistance=min(minDistance, child2.minDistance(P)); 141 | } 142 | } 143 | return minDistance; 144 | } 145 | 146 | void setPhase(float f) { 147 | if (((child1 == null) && (child2 == null))||f<=level) { 148 | drawMesh = getMesh(f); 149 | } else { 150 | drawMesh=null; 151 | if (child1 != null) { 152 | child1.setPhase(f); 153 | } 154 | if (child2 != null) { 155 | child2.setPhase(f); 156 | } 157 | } 158 | } 159 | 160 | void addExtents(float[] extents) { 161 | if (drawMesh!=null) { 162 | float[] fragmentExtents=drawMesh.getExtents(); 163 | for (int i=0; i<3; i++) { 164 | extents[i]=min(extents[i], fragmentExtents[i]); 165 | extents[i+3]=max(extents[i+3], fragmentExtents[i+3]); 166 | } 167 | } else { 168 | if (child1 != null) { 169 | child1.addExtents(extents); 170 | } 171 | if (child2 != null) { 172 | child2.addExtents(extents); 173 | } 174 | } 175 | } 176 | 177 | 178 | void draw() { 179 | if (drawMesh!=null) { 180 | drawMesh.draw(); 181 | } else { 182 | if (child1 != null) { 183 | child1.draw(); 184 | } 185 | if (child2 != null) { 186 | child2.draw(); 187 | } 188 | } 189 | } 190 | 191 | void draw(PImage[] textures) { 192 | if (drawMesh!=null) { 193 | drawMesh.draw(textures); 194 | } else { 195 | if (child1 != null) { 196 | child1.draw(textures); 197 | } 198 | if (child2 != null) { 199 | child2.draw(textures); 200 | } 201 | } 202 | } 203 | 204 | SliceMesh getMesh(float f) { 205 | if (f<=0) { 206 | return invTMesh; 207 | } else if (f>=level) { 208 | return mesh; 209 | } else { 210 | Fragment p = this; 211 | float fracf; 212 | Transform T=new Transform(); 213 | do { 214 | if (p.parentToChild!=null) { 215 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 216 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 217 | } 218 | p = p.parent; 219 | } while (p != null && f initialGeometry() { 85 | Transform T=new Transform(); 86 | T.addRotateY(QUARTER_PI); 87 | T.addRotateX(radians(35.264)); 88 | ArrayList sliceMeshes=new ArrayList(); 89 | SliceMesh sliceMesh; 90 | sliceMesh=new SliceMesh(); 91 | sliceMesh.create(MeshDataFactory.createBoxWithCenterAndSize(0, 0, 0, 420, 420, 420, color(0))); 92 | T.apply(sliceMesh); 93 | sliceMeshes.add(sliceMesh); 94 | tree=new FragmentTree(sliceMeshes); 95 | return sliceMeshes; 96 | } 97 | 98 | void slice(int sliceCount, color col, color col2) { 99 | currentSlice=sliceCount; 100 | Transformation M; 101 | int trial=0; 102 | do { 103 | 104 | float sliceRoll=random(1.0); 105 | if (sliceRoll180) ax-=360; 184 | } 185 | } else if (key=='y') { 186 | if (freeze) { 187 | ay-=5; 188 | if (ay<=-180) ay+=360; 189 | } 190 | } else if (key=='Y') { 191 | if (freeze) { 192 | ay+=5; 193 | if (ay>180) ay-=360; 194 | } 195 | } else if (key=='z') { 196 | if (freeze) { 197 | az-=5; 198 | if (az<=-180) az+=360; 199 | } 200 | } else if (key=='Z') { 201 | if (freeze) { 202 | az+=5; 203 | if (az>180) az-=360; 204 | } 205 | } else if (key=='+') { 206 | zoom+=0.05; 207 | } else if (key=='-') { 208 | zoom-=0.05; 209 | } else if (key== CODED) { 210 | if (keyCode==UP) { 211 | ty-=10; 212 | } else if (keyCode==DOWN) { 213 | ty+=10; 214 | } else if (keyCode==RIGHT) { 215 | tx+=10; 216 | } else if (keyCode==LEFT) { 217 | tx-=10; 218 | } 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /sliceSaga/slicePop/slicemesh.pde: -------------------------------------------------------------------------------- 1 | class SliceMesh extends Mesh { 2 | SliceMesh() { 3 | super(); 4 | } 5 | 6 | SliceMesh copy() { 7 | SliceMesh copy=new SliceMesh(); 8 | copy.createRaw(copyVertexArray(), copyFaceArray(), copyHalfedgePairArray(), copyFaceColor()); 9 | copy.setFaceTextureIds(copyFaceTextureIds()); 10 | copy.setUVs(copyUVs()); 11 | 12 | return copy; 13 | } 14 | 15 | void slice(Plane P, float offset, color col) { 16 | Plane offsetP=P.offset(offset); 17 | ArrayList intersections=new ArrayList(); 18 | 19 | int es=edges.size(); 20 | for (int i=0; i intersections) { 35 | Halfedge he=e.he; 36 | Halfedge hep=he.pair; 37 | Vertex v=he.v; 38 | Vertex vp=hep.v; 39 | PVector u=new PVector(vp.x-v.x, vp.y-v.y, vp.z-v.z); 40 | PVector w=new PVector(v.x-P.origin.x, v.y-P.origin.y, v.z-P.origin.z); 41 | float D=P.normal.dot(u); 42 | float N=-P.normal.dot(w); 43 | if (abs(D)OPEPS) { 48 | return; 49 | } else if (fOMEPS) { 52 | intersections.add(new EdgeIntersection(e, vp)); 53 | } else { 54 | splitEdge(e, f); 55 | Vertex nv=vertices.get(vertices.size()-1); 56 | intersections.add(new EdgeIntersection(e, nv)); 57 | } 58 | } 59 | 60 | void splitEdge(Edge e, float f) { 61 | Halfedge he=e.he; 62 | Halfedge hep=he.pair; 63 | Halfedge hen=he.next; 64 | Halfedge hepn=hep.next; 65 | Vertex v=he.v; 66 | Vertex vp=hep.v; 67 | createVertex((1.0-f)*v.x+f*vp.x, (1.0-f)*v.y+f*vp.y, (1.0-f)*v.z+f*vp.z); 68 | Vertex splitv=vertices.get(vertices.size()-1); 69 | Halfedge heNew=new Halfedge(halfedges.size()); 70 | halfedges.add(heNew); 71 | connectVertex(splitv, heNew); 72 | connectFace(he.f, heNew); 73 | Halfedge hepNew=new Halfedge(halfedges.size()); 74 | halfedges.add(hepNew); 75 | connectVertex(splitv, hepNew); 76 | connectFace(hep.f, hepNew); 77 | connectHalfedges(he, heNew); 78 | connectHalfedges(heNew, hen); 79 | heNew.UV=PVector.lerp(he.UV,hen.UV,f); 80 | connectHalfedges(hep, hepNew); 81 | connectHalfedges(hepNew, hepn); 82 | hepNew.UV=PVector.lerp(hep.UV,hepn.UV,1.0-f); 83 | pairHalfedges(he, hepNew); 84 | connectEdge(e, he); 85 | pairHalfedges(hep, heNew); 86 | createEdge(hep); 87 | } 88 | 89 | class EdgeIntersection { 90 | Edge e; 91 | Vertex v; 92 | 93 | EdgeIntersection(Edge e, Vertex v) { 94 | this.e=e; 95 | this.v=v; 96 | } 97 | } 98 | 99 | void sliceFace(Face f, ArrayList intersections) { 100 | Vertex vi=null; 101 | Vertex vj=null; 102 | for (EdgeIntersection ei : intersections) { 103 | if (ei.e.he.f==f || ei.e.he.pair.f==f) { 104 | if (vi==null) { 105 | vi=ei.v; 106 | } else 107 | if (vi!=ei.v) { 108 | vj=ei.v; 109 | break; 110 | } 111 | } 112 | } 113 | if (vi!=null&&vj!=null) splitFace(f, vi.index, vj.index); 114 | } 115 | 116 | void splitFace(Face f, int i, int j) { 117 | Vertex vi=vertices.get(i); 118 | Halfedge hei=f.he; 119 | while (hei.v!=vi) { 120 | hei=hei.next; 121 | if (hei==f.he) return; 122 | } 123 | Vertex vj=vertices.get(j); 124 | Halfedge hej=f.he; 125 | while (hej.v!=vj) { 126 | hej=hej.next; 127 | if (hej==f.he) return; 128 | } 129 | if (hei.next==hej || hej.next==hei) return; 130 | Halfedge heip=hei.prev; 131 | Halfedge hejp=hej.prev; 132 | Halfedge heNew=new Halfedge(halfedges.size()); 133 | Halfedge hepNew=new Halfedge(halfedges.size()); 134 | heNew.UV=hej.UV.copy(); 135 | hepNew.UV=hei.UV.copy(); 136 | connectVertex(vi, hepNew); 137 | connectVertex(vj, heNew); 138 | pairHalfedges(heNew, hepNew); 139 | createEdge(heNew); 140 | halfedges.add(heNew); 141 | halfedges.add(hepNew); 142 | connectHalfedges(heip, hepNew); 143 | connectHalfedges(hepNew, hej); 144 | connectHalfedges(hejp, heNew); 145 | connectHalfedges(heNew, hei); 146 | heNew.f=f; 147 | Halfedge he=hej; 148 | Face nf=new Face(faces.size(), f.col); 149 | faces.add(nf); 150 | nf.textureId=f.textureId; 151 | do { 152 | connectFace(nf, he); 153 | he=he.next; 154 | } while (he!=hej); 155 | f.he=hei; 156 | } 157 | 158 | void deleteFace(Face f) { 159 | Halfedge he=f.he; 160 | do { 161 | if (he.v.he==he) he.v.he=null; 162 | if (he.pair!=null) { 163 | he.pair.pair=null; 164 | he.pair.e=null; 165 | } 166 | halfedges.remove(he); 167 | edges.remove(he.e); 168 | he=he.next; 169 | } while (he!=f.he); 170 | faces.remove(f); 171 | reconnectVertices(); 172 | indexHalfedges(); 173 | indexFaces(); 174 | indexEdges(); 175 | ArrayList checklist=new ArrayList(); 176 | checklist.addAll(vertices); 177 | for (Vertex v : checklist) { 178 | if (v.he==null) vertices.remove(v); 179 | } 180 | indexVertices(); 181 | } 182 | 183 | void deleteFrontFaces(Plane P) { 184 | ArrayList checklist=new ArrayList(); 185 | checklist.addAll(faces); 186 | for (Face f : checklist) { 187 | if (f.sideOfPlane(P)==1) { 188 | deleteFace(f); 189 | } 190 | } 191 | } 192 | 193 | void capSlice(color col, Plane P) { 194 | Face cap=new Face(faces.size(), col); 195 | Halfedge caphe, trial; 196 | ArrayList capHalfedges=new ArrayList(); 197 | for (Halfedge he : halfedges) { 198 | if (he.pair==null) { 199 | caphe=new Halfedge(halfedges.size()+capHalfedges.size()); 200 | capHalfedges.add(caphe); 201 | pairHalfedges(he, caphe); 202 | createEdge(he); 203 | connectVertex(he.next.v, caphe); 204 | PVector local=P.local(caphe.v.x,caphe.v.y,caphe.v.z); 205 | caphe.UV=new PVector((local.x+400.0)/800.0,(local.y+400.0)/800.0); 206 | connectFace(cap, caphe); 207 | cap.textureId=7+currentSlice; 208 | } 209 | } 210 | halfedges.addAll(capHalfedges); 211 | if (capHalfedges.size()>0) faces.add(cap); 212 | for (int i=0; i 0.5 ? vertTexCoord.xy : vec2(vertTexCoord.x, 1.0-vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop2/data/vignette.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | precision mediump int; 6 | #endif 7 | 8 | uniform sampler2D texture; 9 | uniform vec2 resolution; 10 | varying vec4 vertColor; 11 | varying vec4 vertTexCoord; 12 | 13 | const float RADIUS = 0.75; 14 | const float SOFTNESS = 0.45; 15 | const vec3 SEPIA = vec3(1.0, 0.8, 0.6); 16 | 17 | 18 | void main(void) { 19 | vec4 texColor = texture2D(texture,vertTexCoord.xy); 20 | vec2 position = (gl_FragCoord.xy / resolution.xy) - vec2(0.5); 21 | float len = length(position); 22 | float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len); 23 | texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5); 24 | float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); 25 | vec3 sepiaColor = vec3(gray) * SEPIA; 26 | texColor.rgb = mix(texColor.rgb, sepiaColor, 0.1); 27 | gl_FragColor = texColor * vertColor; 28 | } -------------------------------------------------------------------------------- /sliceSaga/slicePop2/fragmenttree.pde: -------------------------------------------------------------------------------- 1 | class FragmentTree { 2 | ArrayList roots; 3 | 4 | FragmentTree(SliceMesh mesh) { 5 | roots=new ArrayList(); 6 | roots.add(new Fragment(mesh)); 7 | } 8 | 9 | FragmentTree(ArrayList meshes) { 10 | roots=new ArrayList(); 11 | for (SliceMesh mesh : meshes) { 12 | roots.add(new Fragment(mesh)); 13 | } 14 | } 15 | 16 | FragmentTree(SliceMesh... meshes) { 17 | roots=new ArrayList(); 18 | for (SliceMesh mesh : meshes) { 19 | roots.add(new Fragment(mesh)); 20 | } 21 | } 22 | 23 | void split(Transformation M, color col, color col2) { 24 | for (Fragment root : roots) { 25 | root.split(M, col, col2); 26 | } 27 | } 28 | 29 | void setPhase(float f) { 30 | for (Fragment root : roots) { 31 | root.setPhase(f); 32 | } 33 | } 34 | 35 | float[] getExtents() { 36 | float[] extents=new float[]{1000000, 1000000, 1000000, -1000000, -1000000, -1000000}; 37 | for (Fragment root : roots) { 38 | root.addExtents(extents); 39 | } 40 | return extents; 41 | } 42 | 43 | void draw() { 44 | for (Fragment root : roots) { 45 | root.draw(); 46 | } 47 | } 48 | 49 | void draw(PImage[] textures) { 50 | for (Fragment root : roots) { 51 | root.draw(textures); 52 | } 53 | } 54 | 55 | float minDistance(Plane P) { 56 | float minDistance=1000000; 57 | for (Fragment root : roots) { 58 | minDistance=min(minDistance, root.minDistance(P)); 59 | } 60 | return minDistance; 61 | } 62 | } 63 | 64 | 65 | 66 | class Fragment { 67 | Fragment parent; 68 | Fragment child1, child2; 69 | Transformation parentToChild; 70 | SliceMesh mesh; 71 | SliceMesh invTMesh; 72 | SliceMesh dynMesh; 73 | SliceMesh drawMesh; 74 | int level; 75 | 76 | Fragment(SliceMesh mesh) { 77 | this.mesh = mesh.copy(); 78 | invTMesh = mesh.copy(); 79 | dynMesh = mesh.copy(); 80 | parentToChild = null; 81 | parent = null; 82 | child1 = null; 83 | child2 = null; 84 | level = 0; 85 | } 86 | 87 | Fragment(SliceMesh mesh, Fragment parent, Transformation parentToChild) { 88 | this.mesh = mesh.copy(); 89 | dynMesh= mesh.copy(); 90 | this.parentToChild = parentToChild; 91 | this.parent = parent; 92 | invTMesh = mesh.copy(); 93 | Fragment p = this; 94 | do { 95 | if ( p.parentToChild!=null) { 96 | Transform T = p.parentToChild.getInverseTransform(1.0); 97 | T.apply(invTMesh); 98 | } 99 | p = p.parent; 100 | } while (p != null); 101 | level=parent.level+1; 102 | } 103 | 104 | void split(Transformation M, color col, color col2) { 105 | if ((child1 == null) && (child2 == null)) { 106 | SliceMesh split1=mesh.copy(); 107 | SliceMesh split2=mesh.copy(); 108 | split1.slice(M.plane, 0.0, col); 109 | split2.slice(M.plane.flip(), 0.0, col2); 110 | if (split1.vertices.size() > 0 && split1.isValid()) { 111 | child1 = new Fragment(split1, this, null); 112 | } 113 | if (split2.vertices.size() > 0 && split2.isValid()) { 114 | M.getTransform(1.0).apply(split2); 115 | child2 = new Fragment(split2, this, M); 116 | } 117 | } else { 118 | if (child1 != null) { 119 | child1.split(M, col, col2); 120 | } 121 | if (child2 != null) { 122 | child2.split(M, col2, col); 123 | } 124 | } 125 | } 126 | 127 | 128 | float minDistance(Plane P) { 129 | float minDistance=1000000; 130 | if (((child1 == null) && (child2 == null))) {//||f<=level) { 131 | for (Vertex v : mesh.vertices) { 132 | minDistance=min(minDistance, v.distance(P)); 133 | if(minDistance<5.0) return minDistance; 134 | } 135 | } else { 136 | if (child1 != null) { 137 | minDistance=min(minDistance, child1.minDistance(P)); 138 | } 139 | if (child2 != null) { 140 | minDistance=min(minDistance, child2.minDistance(P)); 141 | } 142 | } 143 | return minDistance; 144 | } 145 | 146 | void setPhase(float f) { 147 | if (((child1 == null) && (child2 == null))||f<=level) { 148 | drawMesh = getMesh(f); 149 | } else { 150 | drawMesh=null; 151 | if (child1 != null) { 152 | child1.setPhase(f); 153 | } 154 | if (child2 != null) { 155 | child2.setPhase(f); 156 | } 157 | } 158 | } 159 | 160 | void addExtents(float[] extents) { 161 | if (drawMesh!=null) { 162 | float[] fragmentExtents=drawMesh.getExtents(); 163 | for (int i=0; i<3; i++) { 164 | extents[i]=min(extents[i], fragmentExtents[i]); 165 | extents[i+3]=max(extents[i+3], fragmentExtents[i+3]); 166 | } 167 | } else { 168 | if (child1 != null) { 169 | child1.addExtents(extents); 170 | } 171 | if (child2 != null) { 172 | child2.addExtents(extents); 173 | } 174 | } 175 | } 176 | 177 | 178 | void draw() { 179 | if (drawMesh!=null) { 180 | drawMesh.draw(); 181 | } else { 182 | if (child1 != null) { 183 | child1.draw(); 184 | } 185 | if (child2 != null) { 186 | child2.draw(); 187 | } 188 | } 189 | } 190 | 191 | void draw(PImage[] textures) { 192 | if (drawMesh!=null) { 193 | drawMesh.draw(textures); 194 | } else { 195 | if (child1 != null) { 196 | child1.draw(textures); 197 | } 198 | if (child2 != null) { 199 | child2.draw(textures); 200 | } 201 | } 202 | } 203 | 204 | SliceMesh getMesh(float f) { 205 | if (f<=0) { 206 | return invTMesh; 207 | } else if (f>=level) { 208 | return mesh; 209 | } else { 210 | Fragment p = this; 211 | float fracf; 212 | Transform T=new Transform(); 213 | do { 214 | if (p.parentToChild!=null) { 215 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 216 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 217 | } 218 | p = p.parent; 219 | } while (p != null && f initialGeometry() { 91 | Transform T=new Transform(); 92 | T.addRotateY(QUARTER_PI); 93 | T.addRotateX(radians(35.264)); 94 | ArrayList sliceMeshes=new ArrayList(); 95 | SliceMesh sliceMesh; 96 | sliceMesh=new SliceMesh(); 97 | sliceMesh.create(MeshDataFactory.createBoxWithCenterAndSize(0, 0, 0, 300, 300, 1200, color(0))); 98 | //T.apply(sliceMesh); 99 | sliceMeshes.add(sliceMesh); 100 | tree=new FragmentTree(sliceMeshes); 101 | return sliceMeshes; 102 | } 103 | 104 | void slice(int sliceCount, color col, color col2) { 105 | currentSlice=sliceCount; 106 | Transformation M; 107 | int trial=0; 108 | do { 109 | 110 | float sliceRoll=random(1.0); 111 | if (sliceRoll180) ax-=360; 190 | } 191 | } else if (key=='y') { 192 | if (freeze) { 193 | ay-=5; 194 | if (ay<=-180) ay+=360; 195 | } 196 | } else if (key=='Y') { 197 | if (freeze) { 198 | ay+=5; 199 | if (ay>180) ay-=360; 200 | } 201 | } else if (key=='z') { 202 | if (freeze) { 203 | az-=5; 204 | if (az<=-180) az+=360; 205 | } 206 | } else if (key=='Z') { 207 | if (freeze) { 208 | az+=5; 209 | if (az>180) az-=360; 210 | } 211 | } else if (key=='+') { 212 | zoom+=0.05; 213 | } else if (key=='-') { 214 | zoom-=0.05; 215 | } else if (key== CODED) { 216 | if (keyCode==UP) { 217 | ty-=10; 218 | } else if (keyCode==DOWN) { 219 | ty+=10; 220 | } else if (keyCode==RIGHT) { 221 | tx+=10; 222 | } else if (keyCode==LEFT) { 223 | tx-=10; 224 | } 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /sliceSaga/slicePop2/slicemesh.pde: -------------------------------------------------------------------------------- 1 | class SliceMesh extends Mesh { 2 | SliceMesh() { 3 | super(); 4 | } 5 | 6 | SliceMesh copy() { 7 | SliceMesh copy=new SliceMesh(); 8 | copy.createRaw(copyVertexArray(), copyFaceArray(), copyHalfedgePairArray(), copyFaceColor()); 9 | copy.setFaceTextureIds(copyFaceTextureIds()); 10 | copy.setUVs(copyUVs()); 11 | 12 | return copy; 13 | } 14 | 15 | void slice(Plane P, float offset, color col) { 16 | Plane offsetP=P.offset(offset); 17 | ArrayList intersections=new ArrayList(); 18 | 19 | int es=edges.size(); 20 | for (int i=0; i intersections) { 35 | Halfedge he=e.he; 36 | Halfedge hep=he.pair; 37 | Vertex v=he.v; 38 | Vertex vp=hep.v; 39 | PVector u=new PVector(vp.x-v.x, vp.y-v.y, vp.z-v.z); 40 | PVector w=new PVector(v.x-P.origin.x, v.y-P.origin.y, v.z-P.origin.z); 41 | float D=P.normal.dot(u); 42 | float N=-P.normal.dot(w); 43 | if (abs(D)OPEPS) { 48 | return; 49 | } else if (fOMEPS) { 52 | intersections.add(new EdgeIntersection(e, vp)); 53 | } else { 54 | splitEdge(e, f); 55 | Vertex nv=vertices.get(vertices.size()-1); 56 | intersections.add(new EdgeIntersection(e, nv)); 57 | } 58 | } 59 | 60 | void splitEdge(Edge e, float f) { 61 | Halfedge he=e.he; 62 | Halfedge hep=he.pair; 63 | Halfedge hen=he.next; 64 | Halfedge hepn=hep.next; 65 | Vertex v=he.v; 66 | Vertex vp=hep.v; 67 | createVertex((1.0-f)*v.x+f*vp.x, (1.0-f)*v.y+f*vp.y, (1.0-f)*v.z+f*vp.z); 68 | Vertex splitv=vertices.get(vertices.size()-1); 69 | Halfedge heNew=new Halfedge(halfedges.size()); 70 | halfedges.add(heNew); 71 | connectVertex(splitv, heNew); 72 | connectFace(he.f, heNew); 73 | Halfedge hepNew=new Halfedge(halfedges.size()); 74 | halfedges.add(hepNew); 75 | connectVertex(splitv, hepNew); 76 | connectFace(hep.f, hepNew); 77 | connectHalfedges(he, heNew); 78 | connectHalfedges(heNew, hen); 79 | heNew.UV=PVector.lerp(he.UV,hen.UV,f); 80 | connectHalfedges(hep, hepNew); 81 | connectHalfedges(hepNew, hepn); 82 | hepNew.UV=PVector.lerp(hep.UV,hepn.UV,1.0-f); 83 | pairHalfedges(he, hepNew); 84 | connectEdge(e, he); 85 | pairHalfedges(hep, heNew); 86 | createEdge(hep); 87 | } 88 | 89 | class EdgeIntersection { 90 | Edge e; 91 | Vertex v; 92 | 93 | EdgeIntersection(Edge e, Vertex v) { 94 | this.e=e; 95 | this.v=v; 96 | } 97 | } 98 | 99 | void sliceFace(Face f, ArrayList intersections) { 100 | Vertex vi=null; 101 | Vertex vj=null; 102 | for (EdgeIntersection ei : intersections) { 103 | if (ei.e.he.f==f || ei.e.he.pair.f==f) { 104 | if (vi==null) { 105 | vi=ei.v; 106 | } else 107 | if (vi!=ei.v) { 108 | vj=ei.v; 109 | break; 110 | } 111 | } 112 | } 113 | if (vi!=null&&vj!=null) splitFace(f, vi.index, vj.index); 114 | } 115 | 116 | void splitFace(Face f, int i, int j) { 117 | Vertex vi=vertices.get(i); 118 | Halfedge hei=f.he; 119 | while (hei.v!=vi) { 120 | hei=hei.next; 121 | if (hei==f.he) return; 122 | } 123 | Vertex vj=vertices.get(j); 124 | Halfedge hej=f.he; 125 | while (hej.v!=vj) { 126 | hej=hej.next; 127 | if (hej==f.he) return; 128 | } 129 | if (hei.next==hej || hej.next==hei) return; 130 | Halfedge heip=hei.prev; 131 | Halfedge hejp=hej.prev; 132 | Halfedge heNew=new Halfedge(halfedges.size()); 133 | Halfedge hepNew=new Halfedge(halfedges.size()); 134 | heNew.UV=hej.UV.copy(); 135 | hepNew.UV=hei.UV.copy(); 136 | connectVertex(vi, hepNew); 137 | connectVertex(vj, heNew); 138 | pairHalfedges(heNew, hepNew); 139 | createEdge(heNew); 140 | halfedges.add(heNew); 141 | halfedges.add(hepNew); 142 | connectHalfedges(heip, hepNew); 143 | connectHalfedges(hepNew, hej); 144 | connectHalfedges(hejp, heNew); 145 | connectHalfedges(heNew, hei); 146 | heNew.f=f; 147 | Halfedge he=hej; 148 | Face nf=new Face(faces.size(), f.col); 149 | faces.add(nf); 150 | nf.textureId=f.textureId; 151 | do { 152 | connectFace(nf, he); 153 | he=he.next; 154 | } while (he!=hej); 155 | f.he=hei; 156 | } 157 | 158 | void deleteFace(Face f) { 159 | Halfedge he=f.he; 160 | do { 161 | if (he.v.he==he) he.v.he=null; 162 | if (he.pair!=null) { 163 | he.pair.pair=null; 164 | he.pair.e=null; 165 | } 166 | halfedges.remove(he); 167 | edges.remove(he.e); 168 | he=he.next; 169 | } while (he!=f.he); 170 | faces.remove(f); 171 | reconnectVertices(); 172 | indexHalfedges(); 173 | indexFaces(); 174 | indexEdges(); 175 | ArrayList checklist=new ArrayList(); 176 | checklist.addAll(vertices); 177 | for (Vertex v : checklist) { 178 | if (v.he==null) vertices.remove(v); 179 | } 180 | indexVertices(); 181 | } 182 | 183 | void deleteFrontFaces(Plane P) { 184 | ArrayList checklist=new ArrayList(); 185 | checklist.addAll(faces); 186 | for (Face f : checklist) { 187 | if (f.sideOfPlane(P)==1) { 188 | deleteFace(f); 189 | } 190 | } 191 | } 192 | 193 | void capSlice(color col, Plane P) { 194 | Face cap=new Face(faces.size(), col); 195 | Halfedge caphe, trial; 196 | ArrayList capHalfedges=new ArrayList(); 197 | for (Halfedge he : halfedges) { 198 | if (he.pair==null) { 199 | caphe=new Halfedge(halfedges.size()+capHalfedges.size()); 200 | capHalfedges.add(caphe); 201 | pairHalfedges(he, caphe); 202 | createEdge(he); 203 | connectVertex(he.next.v, caphe); 204 | PVector local=P.local(caphe.v.x,caphe.v.y,caphe.v.z); 205 | caphe.UV=new PVector((local.x+400.0)/800.0,(local.y+400.0)/800.0); 206 | connectFace(cap, caphe); 207 | cap.textureId=7+currentSlice; 208 | } 209 | } 210 | halfedges.addAll(capHalfedges); 211 | if (capHalfedges.size()>0) faces.add(cap); 212 | for (int i=0; i majorPlanes; 2 | ArrayList minorPlanes; 3 | SliceBox stock, crystal; 4 | 5 | void setup() { 6 | size(1000, 1000, P3D); 7 | smooth(16); 8 | create(); 9 | } 10 | 11 | void create() { 12 | majorPlanes = new ArrayList(); 13 | minorPlanes = new ArrayList(); 14 | stock=new SliceBox(); 15 | 16 | //Create a slightly irregular rectangular prism wit N sides, radius varying between 90-110% radius and a "stock height" of 1.6*height; 17 | float radius=120; 18 | float prismHeight=500; 19 | int N=6; 20 | stock.createPrismWithCenterRadiusRangeAndHeight(N, 0, 0, 0, 0.9*radius, 1.1*radius, 1.6*prismHeight); 21 | 22 | //Carve a crystal from the stock, by slicing it with an "umbrella" of planes 23 | 24 | crystal=stock.copy(); 25 | //Hieght of origin of slicing planes 26 | float heightSpread=0; 27 | //Downward slope of the slicing planes 28 | float inclination=38; 29 | float inclinationSpread=5; 30 | //Radial offset of slicing planes 31 | float penetration=0.7*radius; 32 | float penetrationSpread=0; 33 | //Rotation of slicing plan around height axis of stock 34 | float rotation=0; 35 | float rotationSpread=0; 36 | 37 | // Major facets, top and bottom 38 | carveCrystal(crystal, radius, N, 0.5*prismHeight, heightSpread, inclination, inclinationSpread, penetration, penetrationSpread, rotation, rotationSpread, false, majorPlanes); 39 | carveCrystal(crystal, radius, N, 0.5*prismHeight, heightSpread, inclination, inclinationSpread, penetration, penetrationSpread, rotation, rotationSpread, true, majorPlanes); 40 | 41 | //Minor facets, top and bottom 42 | inclination=45; 43 | penetration=0.45*radius;//less deep 44 | prismHeight-=120;//random(0.1, 0.3)*radius;//a bit lower 45 | rotation=180.0/N;// half a division rotated 46 | carveCrystal(crystal, radius, N, 0.5*prismHeight, heightSpread, inclination, inclinationSpread, penetration, penetrationSpread, rotation, rotationSpread, false, minorPlanes); 47 | carveCrystal(crystal, radius, N, 0.5*prismHeight, heightSpread, inclination, inclinationSpread, penetration, penetrationSpread, rotation, rotationSpread, true, minorPlanes); 48 | crystal.save(sketchPath("output.obj")); 49 | } 50 | 51 | void carveCrystal(SliceBox crystal, float radius, int N, float height, float heightSpread, float inclination, float inclinationSpread, float penetration, float penetrationSpread, float rotation, float rotationSpread, boolean invert, ArrayList planes) { 52 | 53 | float dInc, dH, dRot, dPen; 54 | PVector normal; 55 | PVector origin; 56 | 57 | for (int i=0; i xRolls; 12 | Set yRolls; 13 | Set zRolls; 14 | 15 | boolean freeze; 16 | int counter; 17 | float zoom; 18 | void setup() { 19 | fullScreen(P3D); 20 | smooth(16); 21 | noCursor(); 22 | 23 | 24 | init(); 25 | } 26 | 27 | void init() { 28 | zoom=1.0; 29 | translationChance=random(1.0); 30 | rotationChance=random(1.0-translationChance); 31 | shearChance=random(1.0-translationChance-rotationChance); 32 | //stretchChance=1.0-translationChance-rotationChance-shearChance; 33 | slices=25; 34 | ArrayList sliceBoxes=new ArrayList(); 35 | SliceBox sliceBox; 36 | sliceBox=new SliceBox(); 37 | sliceBox.createBoxWithCenterAndSize(0, 0, 0, 300, 300, 300, color(255)); 38 | sliceBoxes.add(sliceBox); 39 | tree=new SliceTree(sliceBoxes); 40 | xRolls=new HashSet(); 41 | yRolls=new HashSet(); 42 | zRolls=new HashSet(); 43 | for (int r=0; r roots; 3 | SliceTree(SliceBox mesh) { 4 | roots=new ArrayList(); 5 | roots.add(new Slice(mesh)); 6 | } 7 | 8 | SliceTree(ArrayList meshes) { 9 | roots=new ArrayList(); 10 | for (SliceBox mesh : meshes) { 11 | roots.add(new Slice(mesh)); 12 | } 13 | } 14 | 15 | SliceTree(SliceBox... meshes) { 16 | roots=new ArrayList(); 17 | for (SliceBox mesh : meshes) { 18 | roots.add(new Slice(mesh)); 19 | } 20 | } 21 | 22 | void split(Transformation M, color col) { 23 | for (Slice root : roots) { 24 | root.split(M, col); 25 | } 26 | } 27 | 28 | void draw(double f) { 29 | for (Slice root : roots) { 30 | root.draw(f); 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | class Slice { 38 | Slice parent; 39 | Slice child1, child2; 40 | Transformation parentToChild; 41 | SliceBox mesh; 42 | SliceBox invTMesh; 43 | SliceBox dynMesh; 44 | int level; 45 | 46 | Slice(SliceBox mesh) { 47 | this.mesh = mesh.copy(); 48 | invTMesh = mesh.copy(); 49 | dynMesh = mesh.copy(); 50 | parentToChild = null; 51 | parent = null; 52 | child1 = null; 53 | child2 = null; 54 | level = 0; 55 | } 56 | 57 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 58 | this.mesh = mesh.copy(); 59 | dynMesh= mesh.copy(); 60 | this.parentToChild = parentToChild; 61 | this.parent = parent; 62 | invTMesh = mesh.copy(); 63 | Slice p = this; 64 | do { 65 | if ( p.parentToChild!=null) { 66 | Transform T = p.parentToChild.getInverseTransform(1.0); 67 | T.apply(invTMesh); 68 | } 69 | p = p.parent; 70 | } while (p != null); 71 | level=parent.level+1; 72 | } 73 | 74 | void split(Transformation M, color col) { 75 | if ((child1 == null) && (child2 == null)) { 76 | SliceBox split1=mesh.copy(); 77 | SliceBox split2=mesh.copy(); 78 | split1.slice(M.plane, 0.0,col); 79 | split2.slice(M.plane.flip(), 0.0, col); 80 | if (split1.vertices.size() > 0 && split1.isValid()) { 81 | child1 = new Slice(split1, this, null); 82 | } 83 | if (split2.vertices.size() > 0 && split2.isValid()) { 84 | M.getTransform(1.0).apply(split2); 85 | child2 = new Slice(split2, this, M); 86 | } 87 | } else { 88 | if (child1 != null) { 89 | child1.split(M,col); 90 | } 91 | if (child2 != null) { 92 | child2.split(M,col); 93 | } 94 | } 95 | } 96 | 97 | 98 | void draw(double f) { 99 | if (((child1 == null) && (child2 == null))||f<=level) { 100 | SliceBox m = getMesh(f); 101 | m.draw(); 102 | } else { 103 | if (child1 != null) { 104 | child1.draw(f); 105 | } 106 | if (child2 != null) { 107 | child2.draw(f); 108 | } 109 | } 110 | } 111 | 112 | SliceBox getMesh(double f) { 113 | if (f<=0) { 114 | return invTMesh; 115 | } else if (f>=level) { 116 | return mesh; 117 | } else { 118 | Slice p = this; 119 | float fracf; 120 | Transform T=new Transform(); 121 | do { 122 | if (p.parentToChild!=null) { 123 | 124 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 125 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 126 | } 127 | p = p.parent; 128 | } while (p != null && f xRolls; 12 | Set yRolls; 13 | Set zRolls; 14 | 15 | boolean freeze; 16 | int counter; 17 | float zoom; 18 | float tx, ty; 19 | void setup() { 20 | fullScreen(P3D); 21 | smooth(16); 22 | noCursor(); 23 | 24 | 25 | init(); 26 | } 27 | 28 | void init() { 29 | zoom=1.0; 30 | translationChance=random(1.0); 31 | rotationChance=random(1.0-translationChance); 32 | shearChance=random(1.0-translationChance-rotationChance); 33 | //stretchChance=1.0-translationChance-rotationChance-shearChance; 34 | slices=24; 35 | ArrayList sliceBoxes=new ArrayList(); 36 | 37 | SliceBox sliceBox; 38 | sliceBox=new SliceBox(); 39 | sliceBox.createBoxWithCenterAndSize(0, 0, 0, 300, 300, 300, color(255)); 40 | sliceBoxes.add(sliceBox); 41 | 42 | tree=new SliceTree(sliceBoxes); 43 | xRolls=new HashSet(); 44 | yRolls=new HashSet(); 45 | zRolls=new HashSet(); 46 | int hue=(int)random(256); 47 | for (int r=0; r roots; 3 | SliceTree(SliceBox mesh) { 4 | roots=new ArrayList(); 5 | roots.add(new Slice(mesh)); 6 | } 7 | 8 | SliceTree(ArrayList meshes) { 9 | roots=new ArrayList(); 10 | for (SliceBox mesh : meshes) { 11 | roots.add(new Slice(mesh)); 12 | } 13 | } 14 | 15 | SliceTree(SliceBox... meshes) { 16 | roots=new ArrayList(); 17 | for (SliceBox mesh : meshes) { 18 | roots.add(new Slice(mesh)); 19 | } 20 | } 21 | 22 | void split(Transformation M, color col) { 23 | for (Slice root : roots) { 24 | root.split(M, col); 25 | } 26 | } 27 | 28 | void draw(double f) { 29 | for (Slice root : roots) { 30 | root.draw(f); 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | class Slice { 38 | Slice parent; 39 | Slice child1, child2; 40 | Transformation parentToChild; 41 | SliceBox mesh; 42 | SliceBox invTMesh; 43 | SliceBox dynMesh; 44 | int level; 45 | 46 | Slice(SliceBox mesh) { 47 | this.mesh = mesh.copy(); 48 | invTMesh = mesh.copy(); 49 | dynMesh = mesh.copy(); 50 | parentToChild = null; 51 | parent = null; 52 | child1 = null; 53 | child2 = null; 54 | level = 0; 55 | } 56 | 57 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 58 | this.mesh = mesh.copy(); 59 | dynMesh= mesh.copy(); 60 | this.parentToChild = parentToChild; 61 | this.parent = parent; 62 | invTMesh = mesh.copy(); 63 | Slice p = this; 64 | do { 65 | if ( p.parentToChild!=null) { 66 | Transform T = p.parentToChild.getInverseTransform(1.0); 67 | T.apply(invTMesh); 68 | } 69 | p = p.parent; 70 | } while (p != null); 71 | level=parent.level+1; 72 | } 73 | 74 | void split(Transformation M, color col) { 75 | if ((child1 == null) && (child2 == null)) { 76 | SliceBox split1=mesh.copy(); 77 | SliceBox split2=mesh.copy(); 78 | split1.slice(M.plane, 0.0,col); 79 | split2.slice(M.plane.flip(), 0.0, col); 80 | if (split1.vertices.size() > 0 && split1.isValid()) { 81 | child1 = new Slice(split1, this, null); 82 | } 83 | if (split2.vertices.size() > 0 && split2.isValid()) { 84 | M.getTransform(1.0).apply(split2); 85 | child2 = new Slice(split2, this, M); 86 | } 87 | } else { 88 | if (child1 != null) { 89 | child1.split(M,col); 90 | } 91 | if (child2 != null) { 92 | child2.split(M,col); 93 | } 94 | } 95 | } 96 | 97 | 98 | void draw(double f) { 99 | if (((child1 == null) && (child2 == null))||f<=level) { 100 | SliceBox m = getMesh(f); 101 | m.draw(); 102 | } else { 103 | if (child1 != null) { 104 | child1.draw(f); 105 | } 106 | if (child2 != null) { 107 | child2.draw(f); 108 | } 109 | } 110 | } 111 | 112 | SliceBox getMesh(double f) { 113 | if (f<=0) { 114 | return invTMesh; 115 | } else if (f>=level) { 116 | return mesh; 117 | } else { 118 | Slice p = this; 119 | float fracf; 120 | Transform T=new Transform(); 121 | do { 122 | if (p.parentToChild!=null) { 123 | 124 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 125 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 126 | } 127 | p = p.parent; 128 | } while (p != null && f 0.5 ? vertTexCoord.xy : vec2(vertTexCoord.x, 1.0-vertTexCoord.y); 8 | gl_FragColor = texture2D(texture, p); 9 | } -------------------------------------------------------------------------------- /sliceSaga/sliceTree_Hexagon2/data/vignette.glsl: -------------------------------------------------------------------------------- 1 | #define PROCESSING_TEXTURE_SHADER 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | precision mediump int; 6 | #endif 7 | 8 | uniform sampler2D texture; 9 | uniform vec2 resolution; 10 | varying vec4 vertColor; 11 | varying vec4 vertTexCoord; 12 | 13 | const float RADIUS = 0.75; 14 | const float SOFTNESS = 0.45; 15 | const vec3 SEPIA = vec3(1.0, 0.8, 0.6); 16 | 17 | 18 | void main(void) { 19 | vec4 texColor = texture2D(texture,vertTexCoord.xy); 20 | vec2 position = (gl_FragCoord.xy / resolution.xy) - vec2(0.5); 21 | float len = length(position); 22 | float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len); 23 | texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5); 24 | float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); 25 | vec3 sepiaColor = vec3(gray) * SEPIA; 26 | texColor.rgb = mix(texColor.rgb, sepiaColor, 0.1); 27 | gl_FragColor = texColor * vertColor; 28 | } -------------------------------------------------------------------------------- /sliceSaga/sliceTree_Hexagon2/slices.pde: -------------------------------------------------------------------------------- 1 | class SliceTree { 2 | ArrayList roots; 3 | SliceTree(SliceBox mesh) { 4 | roots=new ArrayList(); 5 | roots.add(new Slice(mesh)); 6 | } 7 | 8 | SliceTree(ArrayList meshes) { 9 | roots=new ArrayList(); 10 | for (SliceBox mesh : meshes) { 11 | roots.add(new Slice(mesh)); 12 | } 13 | } 14 | 15 | SliceTree(SliceBox... meshes) { 16 | roots=new ArrayList(); 17 | for (SliceBox mesh : meshes) { 18 | roots.add(new Slice(mesh)); 19 | } 20 | } 21 | 22 | void split(Transformation M, color col) { 23 | for (Slice root : roots) { 24 | root.split(M, col); 25 | } 26 | } 27 | 28 | void draw(double f) { 29 | for (Slice root : roots) { 30 | root.draw(f); 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | class Slice { 38 | Slice parent; 39 | Slice child1, child2; 40 | Transformation parentToChild; 41 | SliceBox mesh; 42 | SliceBox invTMesh; 43 | SliceBox dynMesh; 44 | int level; 45 | 46 | Slice(SliceBox mesh) { 47 | this.mesh = mesh.copy(); 48 | invTMesh = mesh.copy(); 49 | dynMesh = mesh.copy(); 50 | parentToChild = null; 51 | parent = null; 52 | child1 = null; 53 | child2 = null; 54 | level = 0; 55 | } 56 | 57 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 58 | this.mesh = mesh.copy(); 59 | dynMesh= mesh.copy(); 60 | this.parentToChild = parentToChild; 61 | this.parent = parent; 62 | invTMesh = mesh.copy(); 63 | Slice p = this; 64 | do { 65 | if ( p.parentToChild!=null) { 66 | Transform T = p.parentToChild.getInverseTransform(1.0); 67 | T.apply(invTMesh); 68 | } 69 | p = p.parent; 70 | } while (p != null); 71 | level=parent.level+1; 72 | } 73 | 74 | void split(Transformation M, color col) { 75 | if ((child1 == null) && (child2 == null)) { 76 | SliceBox split1=mesh.copy(); 77 | SliceBox split2=mesh.copy(); 78 | split1.slice(M.plane, 0.0,col); 79 | split2.slice(M.plane.flip(), 0.0, col); 80 | if (split1.vertices.size() > 0 && split1.isValid()) { 81 | child1 = new Slice(split1, this, null); 82 | } 83 | if (split2.vertices.size() > 0 && split2.isValid()) { 84 | M.getTransform(1.0).apply(split2); 85 | child2 = new Slice(split2, this, M); 86 | } 87 | } else { 88 | if (child1 != null) { 89 | child1.split(M,col); 90 | } 91 | if (child2 != null) { 92 | child2.split(M,col); 93 | } 94 | } 95 | } 96 | 97 | 98 | void draw(double f) { 99 | if (((child1 == null) && (child2 == null))||f<=level) { 100 | SliceBox m = getMesh(f); 101 | m.draw(); 102 | } else { 103 | if (child1 != null) { 104 | child1.draw(f); 105 | } 106 | if (child2 != null) { 107 | child2.draw(f); 108 | } 109 | } 110 | } 111 | 112 | SliceBox getMesh(double f) { 113 | if (f<=0) { 114 | return invTMesh; 115 | } else if (f>=level) { 116 | return mesh; 117 | } else { 118 | Slice p = this; 119 | float fracf; 120 | Transform T=new Transform(); 121 | do { 122 | if (p.parentToChild!=null) { 123 | 124 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 125 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 126 | } 127 | p = p.parent; 128 | } while (p != null && f initialGeometry() { 54 | ArrayList sliceBoxes=new ArrayList(); 55 | SliceBox sliceBox; 56 | sliceBox=new SliceBox(); 57 | sliceBox.createBoxWithCenterAndSize(0, 0, 0, 300, 300, 300, color(255)); 58 | sliceBoxes.add(sliceBox); 59 | return sliceBoxes; 60 | } 61 | 62 | void slice(int slicecount, color col, color col2) { 63 | Transformation M; 64 | int trial=0; 65 | do { 66 | 67 | float sliceRoll=random(1.0); 68 | if (sliceRoll180) ax-=360; 320 | } 321 | } else if (key=='y') { 322 | if (freeze) { 323 | ay-=5; 324 | if (ay<=-180) ay+=360; 325 | } 326 | } else if (key=='Y') { 327 | if (freeze) { 328 | ay+=5; 329 | if (ay>180) ay-=360; 330 | } 331 | } else if (key=='z') { 332 | if (freeze) { 333 | az-=5; 334 | if (az<=-180) az+=360; 335 | } 336 | } else if (key=='Z') { 337 | if (freeze) { 338 | az+=5; 339 | if (az>180) az-=360; 340 | } 341 | } else if (key=='+') { 342 | zoom+=0.05; 343 | } else if (key=='-') { 344 | zoom-=0.05; 345 | } else if (key== CODED) { 346 | if (keyCode==UP) { 347 | ty-=10; 348 | } else if (keyCode==DOWN) { 349 | ty+=10; 350 | } else if (keyCode==RIGHT) { 351 | tx+=10; 352 | } else if (keyCode==LEFT) { 353 | tx-=10; 354 | } 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /sliceSaga/sliceTree_Mono/slices.pde: -------------------------------------------------------------------------------- 1 | class SliceTree { 2 | ArrayList roots; 3 | float bufferedF; 4 | 5 | SliceTree(SliceBox mesh) { 6 | roots=new ArrayList(); 7 | roots.add(new Slice(mesh)); 8 | } 9 | 10 | SliceTree(ArrayList meshes) { 11 | roots=new ArrayList(); 12 | for (SliceBox mesh : meshes) { 13 | roots.add(new Slice(mesh)); 14 | } 15 | } 16 | 17 | SliceTree(SliceBox... meshes) { 18 | roots=new ArrayList(); 19 | for (SliceBox mesh : meshes) { 20 | roots.add(new Slice(mesh)); 21 | } 22 | } 23 | 24 | void split(Transformation M, color col, color col2) { 25 | for (Slice root : roots) { 26 | root.split(M, col, col2); 27 | } 28 | } 29 | 30 | void setPhase(float f) { 31 | for (Slice root : roots) { 32 | root.setPhase(f); 33 | } 34 | } 35 | 36 | float[] getExtents() { 37 | float[] extents=new float[]{1000000, 1000000, 1000000, -1000000, -1000000, -1000000}; 38 | for (Slice root : roots) { 39 | root.addExtents(extents); 40 | } 41 | return extents; 42 | } 43 | 44 | void draw() { 45 | 46 | for (Slice root : roots) { 47 | root.draw(); 48 | } 49 | } 50 | 51 | 52 | void draw(color col, PGraphics pg) { 53 | 54 | for (Slice root : roots) { 55 | root.draw(col, pg); 56 | } 57 | } 58 | 59 | float minDistance(Plane P) { 60 | float minDistance=1000000; 61 | for (Slice root : roots) { 62 | minDistance=min(minDistance, root.minDistance(P)); 63 | } 64 | return minDistance; 65 | } 66 | } 67 | 68 | 69 | 70 | class Slice { 71 | Slice parent; 72 | Slice child1, child2; 73 | Transformation parentToChild; 74 | SliceBox mesh; 75 | SliceBox invTMesh; 76 | SliceBox dynMesh; 77 | SliceBox drawMesh; 78 | int level; 79 | 80 | Slice(SliceBox mesh) { 81 | this.mesh = mesh.copy(); 82 | invTMesh = mesh.copy(); 83 | dynMesh = mesh.copy(); 84 | parentToChild = null; 85 | parent = null; 86 | child1 = null; 87 | child2 = null; 88 | level = 0; 89 | } 90 | 91 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 92 | this.mesh = mesh.copy(); 93 | dynMesh= mesh.copy(); 94 | this.parentToChild = parentToChild; 95 | this.parent = parent; 96 | invTMesh = mesh.copy(); 97 | Slice p = this; 98 | do { 99 | if ( p.parentToChild!=null) { 100 | Transform T = p.parentToChild.getInverseTransform(1.0); 101 | T.apply(invTMesh); 102 | } 103 | p = p.parent; 104 | } while (p != null); 105 | level=parent.level+1; 106 | } 107 | 108 | void split(Transformation M, color col, color col2) { 109 | if ((child1 == null) && (child2 == null)) { 110 | SliceBox split1=mesh.copy(); 111 | SliceBox split2=mesh.copy(); 112 | split1.slice(M.plane, 0.0, col); 113 | split2.slice(M.plane.flip(), 0.0, col2); 114 | if (split1.vertices.size() > 0 && split1.isValid()) { 115 | child1 = new Slice(split1, this, null); 116 | } 117 | if (split2.vertices.size() > 0 && split2.isValid()) { 118 | M.getTransform(1.0).apply(split2); 119 | child2 = new Slice(split2, this, M); 120 | } 121 | } else { 122 | if (child1 != null) { 123 | child1.split(M, col, col2); 124 | } 125 | if (child2 != null) { 126 | child2.split(M, col2, col); 127 | } 128 | } 129 | } 130 | 131 | 132 | float minDistance(Plane P) { 133 | float minDistance=1000000; 134 | if (((child1 == null) && (child2 == null))) {//||f<=level) { 135 | for (Vertex v : mesh.vertices) { 136 | minDistance=min(minDistance, v.distance(P)); 137 | if(minDistance<5.0) return minDistance; 138 | } 139 | } else { 140 | if (child1 != null) { 141 | minDistance=min(minDistance, child1.minDistance(P)); 142 | } 143 | if (child2 != null) { 144 | minDistance=min(minDistance, child2.minDistance(P)); 145 | } 146 | } 147 | return minDistance; 148 | } 149 | 150 | void setPhase(float f) { 151 | if (((child1 == null) && (child2 == null))) {//||f<=level) { 152 | drawMesh = getMesh(f); 153 | } else { 154 | drawMesh=null; 155 | if (child1 != null) { 156 | child1.setPhase(f); 157 | } 158 | if (child2 != null) { 159 | child2.setPhase(f); 160 | } 161 | } 162 | } 163 | 164 | void addExtents(float[] extents) { 165 | if (drawMesh!=null) { 166 | float[] fragmentExtents=drawMesh.getExtents(); 167 | for (int i=0; i<3; i++) { 168 | extents[i]=min(extents[i], fragmentExtents[i]); 169 | extents[i+3]=max(extents[i+3], fragmentExtents[i+3]); 170 | } 171 | } else { 172 | if (child1 != null) { 173 | child1.addExtents(extents); 174 | } 175 | if (child2 != null) { 176 | child2.addExtents(extents); 177 | } 178 | } 179 | } 180 | 181 | 182 | void draw() { 183 | if (drawMesh!=null) { 184 | drawMesh.draw(); 185 | } else { 186 | if (child1 != null) { 187 | child1.draw(); 188 | } 189 | if (child2 != null) { 190 | child2.draw(); 191 | } 192 | } 193 | } 194 | 195 | void draw(color col, PGraphics pg) { 196 | if (drawMesh!=null) { 197 | drawMesh.draw(col, pg); 198 | } else { 199 | if (child1 != null) { 200 | child1.draw(col, pg); 201 | } 202 | if (child2 != null) { 203 | child2.draw(col, pg); 204 | } 205 | } 206 | } 207 | 208 | 209 | SliceBox getMesh(float f) { 210 | if (f<=0) { 211 | return invTMesh; 212 | } else if (f>=level) { 213 | return mesh; 214 | } else { 215 | 216 | Slice p = this; 217 | float fracf; 218 | Transform T=new Transform(); 219 | do { 220 | if (p.parentToChild!=null) { 221 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 222 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 223 | } 224 | p = p.parent; 225 | } while (p != null && f xRolls; 12 | Set yRolls; 13 | Set zRolls; 14 | 15 | boolean freeze; 16 | int counter; 17 | float zoom; 18 | float tx,ty; 19 | void setup() { 20 | fullScreen(P3D); 21 | smooth(16); 22 | noCursor(); 23 | 24 | 25 | init(); 26 | } 27 | 28 | void init() { 29 | zoom=1.0; 30 | translationChance=random(1.0); 31 | rotationChance=random(1.0-translationChance); 32 | shearChance=random(1.0-translationChance-rotationChance); 33 | //stretchChance=1.0-translationChance-rotationChance-shearChance; 34 | slices=32; 35 | ArrayList sliceBoxes=new ArrayList(); 36 | for (int i=-5; i<=5; i++) { 37 | for (int j=-5; j<=5; j++) { 38 | SliceBox sliceBox; 39 | sliceBox=new SliceBox(); 40 | sliceBox.createBoxWithCenterAndSize(i*60, j*60, 0, 27, 27, 800, color(0)); 41 | sliceBoxes.add(sliceBox); 42 | } 43 | } 44 | tree=new SliceTree(sliceBoxes); 45 | xRolls=new HashSet(); 46 | yRolls=new HashSet(); 47 | zRolls=new HashSet(); 48 | for (int r=0; r roots; 3 | SliceTree(SliceBox mesh) { 4 | roots=new ArrayList(); 5 | roots.add(new Slice(mesh)); 6 | } 7 | 8 | SliceTree(ArrayList meshes) { 9 | roots=new ArrayList(); 10 | for (SliceBox mesh : meshes) { 11 | roots.add(new Slice(mesh)); 12 | } 13 | } 14 | 15 | SliceTree(SliceBox... meshes) { 16 | roots=new ArrayList(); 17 | for (SliceBox mesh : meshes) { 18 | roots.add(new Slice(mesh)); 19 | } 20 | } 21 | 22 | void split(Transformation M, color col) { 23 | for (Slice root : roots) { 24 | root.split(M, col); 25 | } 26 | } 27 | 28 | void draw(double f) { 29 | for (Slice root : roots) { 30 | root.draw(f); 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | class Slice { 38 | Slice parent; 39 | Slice child1, child2; 40 | Transformation parentToChild; 41 | SliceBox mesh; 42 | SliceBox invTMesh; 43 | SliceBox dynMesh; 44 | int level; 45 | 46 | Slice(SliceBox mesh) { 47 | this.mesh = mesh.copy(); 48 | invTMesh = mesh.copy(); 49 | dynMesh = mesh.copy(); 50 | parentToChild = null; 51 | parent = null; 52 | child1 = null; 53 | child2 = null; 54 | level = 0; 55 | } 56 | 57 | Slice(SliceBox mesh, Slice parent, Transformation parentToChild) { 58 | this.mesh = mesh.copy(); 59 | dynMesh= mesh.copy(); 60 | this.parentToChild = parentToChild; 61 | this.parent = parent; 62 | invTMesh = mesh.copy(); 63 | Slice p = this; 64 | do { 65 | if ( p.parentToChild!=null) { 66 | Transform T = p.parentToChild.getInverseTransform(1.0); 67 | T.apply(invTMesh); 68 | } 69 | p = p.parent; 70 | } while (p != null); 71 | level=parent.level+1; 72 | } 73 | 74 | void split(Transformation M, color col) { 75 | if ((child1 == null) && (child2 == null)) { 76 | SliceBox split1=mesh.copy(); 77 | SliceBox split2=mesh.copy(); 78 | split1.slice(M.plane, 0.0,col); 79 | split2.slice(M.plane.flip(), 0.0, col); 80 | if (split1.vertices.size() > 0 && split1.isValid()) { 81 | child1 = new Slice(split1, this, null); 82 | } 83 | if (split2.vertices.size() > 0 && split2.isValid()) { 84 | M.getTransform(1.0).apply(split2); 85 | child2 = new Slice(split2, this, M); 86 | } 87 | } else { 88 | if (child1 != null) { 89 | child1.split(M,col); 90 | } 91 | if (child2 != null) { 92 | child2.split(M,col); 93 | } 94 | } 95 | } 96 | 97 | 98 | void draw(double f) { 99 | if (((child1 == null) && (child2 == null))||f<=level) { 100 | SliceBox m = getMesh(f); 101 | m.draw(); 102 | } else { 103 | if (child1 != null) { 104 | child1.draw(f); 105 | } 106 | if (child2 != null) { 107 | child2.draw(f); 108 | } 109 | } 110 | } 111 | 112 | SliceBox getMesh(double f) { 113 | if (f<=0) { 114 | return invTMesh; 115 | } else if (f>=level) { 116 | return mesh; 117 | } else { 118 | Slice p = this; 119 | float fracf; 120 | Transform T=new Transform(); 121 | do { 122 | if (p.parentToChild!=null) { 123 | 124 | fracf=constrain((float)(p.level-f), 0.0, 1.0); 125 | T.addTransform(p.parentToChild.getInverseTransform(fracf)); 126 | } 127 | p = p.parent; 128 | } while (p != null && f vorCells; 2 | ArrayList vorPoints; 3 | int numPoints; 4 | int GAP; 5 | float CHANCE; 6 | 7 | void setup() { 8 | size(1000, 1000, P3D); 9 | smooth(16); 10 | 11 | create(); 12 | } 13 | 14 | //Brute force, unoptimized Voronoi 15 | void create() { 16 | vorCells=new ArrayList (); 17 | vorPoints = new ArrayList (); 18 | int numPoints =100; 19 | for (int i=0; i paths; 12 | HET_MeshNetwork meshNetwork; 13 | WB_Network network; 14 | int currentSource; 15 | WB_Vector[] rotAxis; 16 | float ax, ay; 17 | void setup() { 18 | fullScreen(P3D); 19 | smooth(8); 20 | render= new WB_Render3D(this); 21 | factory=WB_GeometryFactory3D.instance(); 22 | create(); 23 | } 24 | 25 | void create() { 26 | meshes=new HE_Mesh[10]; 27 | rotAxis=new WB_Vector[10]; 28 | for (int i=0; i<10; i++) { 29 | container=new HE_Mesh(new HEC_Geodesic().setRadius(40+40*i).setB(3).setC(0)).modify(new HEM_Dual()); 30 | rotAxis[i]=container.getVertexWithIndex(8*i).getVertexNormal(); 31 | meshNetwork=new HET_MeshNetwork(container); 32 | network=meshNetwork.getNetwork(8*i,8); 33 | HEC_FromNetwork creator=new HEC_FromNetwork(); 34 | creator.setNetwork(network); 35 | creator.setConnectionRadius(1+0.3*i);// strut radius 36 | creator.setConnectionFacets(4);// number of faces in the struts, min 3, max whatever blows up the CPU 37 | creator.setTaper(true);// allow struts to have different radii at each end? 38 | creator.setMaximumConnectionOffset(2+0.6*i); 39 | creator.setUseNodeValues(false); 40 | meshes[i]=new HE_Mesh(creator); 41 | } 42 | } 43 | 44 | void draw() { 45 | background(20); 46 | directionalLight(255, 255, 255, 1, 1, -1); 47 | directionalLight(127, 127, 127, -1, -1, 1); 48 | translate(width/2, height/2, 0); 49 | ay=mouseX*1.0f/width*TWO_PI; 50 | rotateY(ay); 51 | ax=mouseY*1.0f/height*TWO_PI; 52 | rotateX(ax); 53 | fill(255); 54 | noStroke(); 55 | for (int i=0; i<10; i++) { 56 | render.drawFaces(meshes[i]); 57 | } 58 | stroke(255, 50); 59 | render.drawEdges(container); 60 | stroke(255, 0, 0); 61 | render.drawNetwork(meshNetwork); 62 | update(); 63 | } 64 | 65 | 66 | void update(){ 67 | for (int i=0; i<9; i++) { 68 | meshes[i].rotateAboutAxisSelf((9-i)*0.001,WB_Point.ZERO(),rotAxis[i]); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /spiral/data/portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wblut/Processing3Sketches/93240ead4d38e53ef46a8de67a3759fd443257f3/spiral/data/portrait.jpg -------------------------------------------------------------------------------- /spiral/readme.md: -------------------------------------------------------------------------------- 1 | ![spiral](https://wblut.github.com/img/spiral.png) -------------------------------------------------------------------------------- /spiral/spiral.pde: -------------------------------------------------------------------------------- 1 | import processing.svg.*; 2 | Spiral S; 3 | float RADIUS; 4 | int NUMPOINTSPERTURN; 5 | int NUMTURNS; 6 | PImage image; 7 | float imageScale; 8 | void setup() { 9 | size(1000, 1000, P3D); 10 | smooth(16); 11 | image=loadImage("portrait.jpg");//CC0 https://www.piqsels.com/ 12 | 13 | NUMTURNS=40; 14 | NUMPOINTSPERTURN=1000; 15 | RADIUS=400.0; 16 | imageScale=min(0.5*image.width/(RADIUS+4), 0.5*image.height/(RADIUS+4)); 17 | } 18 | 19 | void draw() { 20 | background(255); 21 | drawSpiral("spiral001", color(0), 0, 0); 22 | drawSpiral("spiral002", color(0), 0, 1); 23 | drawSpiral("spiral003", color(0), 0, -1); 24 | drawSpiral("spiral004", color(0), 0, 2); 25 | drawSpiral("spiral005", color(0), 0, -2); 26 | noLoop(); 27 | } 28 | 29 | void drawSpiral(String name, color col, float angle, float displacement) { 30 | pushMatrix(); 31 | beginRecord(SVG, "/SVG/"+name+".svg"); 32 | translate(width/2, height/2); 33 | S=new Spiral(RADIUS, NUMTURNS*NUMPOINTSPERTURN, NUMTURNS, angle, displacement); 34 | noFill(); 35 | stroke(col); 36 | S.draw(); 37 | rect(-width/2, -height/2, width, height); 38 | endRecord(); 39 | popMatrix(); 40 | } 41 | 42 | 43 | class Spiral { 44 | float[] points; 45 | Spiral(float r, int num, float s, float angle, float displacement) { 46 | float dr=r/num; 47 | points=new float[2*num]; 48 | int id=0; 49 | float radius; 50 | float displacementFactor=0.0; 51 | float hysteresis=0.5; 52 | for (int i=0; i