├── exampleImages ├── beetles.png └── colored.png ├── bleetlegen ├── bleetlegen.pde └── Beetle.pde ├── README.md └── LICENSE /exampleImages/beetles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleeptrack/generativeBugs/HEAD/exampleImages/beetles.png -------------------------------------------------------------------------------- /exampleImages/colored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleeptrack/generativeBugs/HEAD/exampleImages/colored.png -------------------------------------------------------------------------------- /bleetlegen/bleetlegen.pde: -------------------------------------------------------------------------------- 1 | import java.awt.*; 2 | 3 | public void setup(){ 4 | size(500,250); 5 | background(255); 6 | noLoop(); 7 | 8 | 9 | Beetle b1 = new Beetle(true); 10 | image(b1.getImage(),0,0,250,250); 11 | 12 | Beetle b2 = new Beetle(false); 13 | image(b2.getImage(),250,0,250,250); 14 | 15 | 16 | } 17 | 18 | void draw(){ 19 | 20 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generativeBugs 2 | Processing script for generating random bug images. 3 | ![generated bugs](exampleImages/beetles.png) 4 | ![generated colored bugs](exampleImages/colored.png) 5 | 6 | Create a new Bug by creating a Object 7 | ``` 8 | Beetle b = new Beetle(); 9 | ``` 10 | 11 | You can choose if the bug should be colored or not in the constructor (colored is default). 12 | ``` 13 | Beetle b = new Beetle(false); 14 | ``` 15 | 16 | To draw your bug, get the Image from the bug and draw it on your canvas: 17 | ``` 18 | Beetle b = new Beetle(); 19 | image(b.getImage(),0,0,500,500); 20 | ``` 21 | 22 | A bug generated 1-2 attributes which you can get by using the name attribute: 23 | ``` 24 | Beetle b = new Beetle(); 25 | System.out.println(b.name); 26 | ``` 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 bleeptrack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bleetlegen/Beetle.pde: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Beetle{ 4 | 5 | PGraphics canvas; 6 | int size = 500; 7 | 8 | ArrayList attributes = new ArrayList(); 9 | ArrayList colors = new ArrayList(); 10 | String name; 11 | 12 | PGraphics wingMaskL; 13 | PGraphics wingMaskR; 14 | PGraphics wingPattern; 15 | 16 | int mainC; 17 | int headC; 18 | int feetC; 19 | int wingsC1; 20 | int wingsC2; 21 | 22 | PVector neck; 23 | int neckHandle; 24 | PVector shoulderR; 25 | PVector shoulderL; 26 | int shoulderHandle; 27 | PVector bottom; 28 | int bottomHandle; 29 | int bottomSize; 30 | 31 | PVector wingM; 32 | PVector wingL; 33 | PVector wingR; 34 | int wingHandleDown; 35 | int wingHandlePoint; 36 | int wingHandleShoulder; 37 | int wingHandleM; 38 | 39 | PVector head; 40 | int headV; 41 | int headH; 42 | 43 | PVector antennaL1; 44 | PVector antennaL2; 45 | PVector antennaR1; 46 | PVector antennaR2; 47 | int antennaHandle; 48 | 49 | PVector legC1; 50 | PVector legC2; 51 | PVector legC3; 52 | 53 | int legThickness; 54 | int legLength; 55 | 56 | int legAngleC1; 57 | int legAngleC2; 58 | int legAngleC3; 59 | 60 | int legAngle2C1; 61 | int legAngle2C2; 62 | int legAngle2C3; 63 | 64 | int legAngle3C1; 65 | int legAngle3C2; 66 | int legAngle3C3; 67 | 68 | int nbrFeet; 69 | 70 | boolean colored = true; 71 | 72 | Beetle(boolean colored){ 73 | this.colored = colored; 74 | canvas = createGraphics(500,500); 75 | init(); 76 | draw(); 77 | generateName(); 78 | } 79 | 80 | Beetle(){ 81 | canvas = createGraphics(500,500); 82 | init(); 83 | draw(); 84 | generateName(); 85 | } 86 | 87 | public void generateName(){ 88 | Collections.shuffle(attributes); 89 | Collections.shuffle(colors); 90 | 91 | if(colored){ 92 | name = colors.get(0)+" "; 93 | }else{ 94 | name = ""; 95 | } 96 | if(attributes.size()>0){ 97 | name += attributes.get(0); 98 | } 99 | System.out.println(name); 100 | } 101 | 102 | public PGraphics getImage(){ 103 | return canvas; 104 | } 105 | 106 | public void saveImage(String name){ 107 | canvas.save(name+".png"); 108 | } 109 | 110 | public void draw(){ 111 | canvas.beginDraw(); 112 | canvas.strokeWeight(4); 113 | canvas.fill(feetC); 114 | drawLegs(); 115 | canvas.noFill(); 116 | drawAntenna(); 117 | canvas.fill(headC); 118 | drawHead(); 119 | canvas.fill(mainC); 120 | drawBody(); 121 | 122 | drawWing(); 123 | canvas.endDraw(); 124 | } 125 | 126 | public void printAttributes(){ 127 | for(String s:attributes){ 128 | System.out.println(s); 129 | } 130 | } 131 | 132 | public void init(){ 133 | colorMode(HSB, 360, 100, 100); 134 | if(colored){ 135 | int mainr = int(random(0,360)); 136 | colors.add(getColorName(mainr)); 137 | mainC = color(mainr, int(random(0,100)), 80); 138 | headC = color(mainr, int(random(0,100)), 70); 139 | feetC = color(mainr, int(random(0,100)), 50); 140 | 141 | int wingr = mainr+int(random(0,80))-40; 142 | wingsC1 = color(wingr, int(random(0,100)), 100); 143 | colors.add(getColorName(wingr)+"-winged"); 144 | wingsC2 = color(wingr+int(random(0,150))-75, int(random(0,100)), 90); 145 | }else{ 146 | mainC = color(0,0,100); 147 | headC = color(0,0,100); 148 | feetC = color(0,0,100); 149 | wingsC1 = color(0,0,100); 150 | wingsC2 = color(0,0,100); 151 | } 152 | 153 | 154 | neck = new PVector(500/2,100); 155 | int neckoffX = round(random(5,70)); 156 | int neckoffY = round(random(20,70)); 157 | 158 | shoulderR = new PVector(neck.x+neckoffX,neck.y+neckoffY); 159 | shoulderL = new PVector(neck.x-neckoffX,neck.y+neckoffY); 160 | int bottomSize = round(random(150,350)); 161 | bottom = new PVector(neck.x,neck.y+bottomSize); 162 | 163 | neckHandle = round(random(20,neckoffX)); 164 | bottomHandle = round(random(20,100)); 165 | 166 | 167 | head = new PVector(neck.x,neck.y); 168 | headV = round(random(30,neckoffX)); 169 | headH = round(random(10,50)); 170 | 171 | int wingoff = round(random(0,neckoffY)); 172 | wingM = new PVector(neck.x,shoulderL.y+wingoff); 173 | int wingSize = round(random(50,350)); 174 | int wingoffX = round(random(0,neckoffX*2)-neckoffX); 175 | wingL = new PVector(shoulderL.x+wingoffX,shoulderL.y+wingSize); 176 | wingR = new PVector(shoulderR.x-wingoffX,shoulderR.y+wingSize); 177 | 178 | wingHandleDown = round(random(5,60)); 179 | wingHandlePoint = round(random(5,neckoffX)); 180 | wingHandleShoulder = round(random(5,60)); 181 | wingHandleM = round(random(10,neckoffX)); 182 | 183 | if(wingL.y-bottom.y>70){ 184 | attributes.add("long-winged"); 185 | } 186 | if(bottom.y-wingL.y>30){ 187 | attributes.add("short-winged"); 188 | } 189 | if(bottom.y>400){ 190 | attributes.add("large"); 191 | } 192 | if(bottom.y<300 && neckoffX>30 && wingL.y<300){ 193 | attributes.add("plump"); 194 | attributes.add("small"); 195 | } 196 | if(neckoffX<15 && bottomHandle<60){ 197 | attributes.add("narrow"); 198 | } 199 | 200 | 201 | int antoffX = round(random(30,125)); 202 | int antoffY = round(random(10,head.y-20)); 203 | int antoffX2 = round(random(125,240)); 204 | int antoffY2 = round(random(10,250)); 205 | 206 | antennaL1 = new PVector(head.x-antoffX,antoffY); 207 | antennaL2 = new PVector(head.x-antoffX2,antoffY2); 208 | 209 | antennaR1 = new PVector(head.x+antoffX,antoffY); 210 | antennaR2 = new PVector(head.x+antoffX2,antoffY2); 211 | antennaHandle = round(random(20,100)); 212 | 213 | legThickness = int(random(7,15)); 214 | legLength = int(random(50,100)); 215 | 216 | legAngleC1 = -int(random(15,45)); 217 | legAngleC2 = int(random(0,25)); 218 | legAngleC3 = int(random(30,50)); 219 | 220 | legAngle2C1 = int(random(30,80)); 221 | legAngle2C2 = int(random(30,80)); 222 | legAngle2C3 = int(random(20,45)); 223 | 224 | legAngle3C1 = -int(random(15,70)); 225 | legAngle3C2 = -int(random(15,70)); 226 | legAngle3C3 = -int(random(15,70)); 227 | 228 | legC1 = new PVector(neck.x, shoulderL.y); 229 | legC2 = new PVector(neck.x, wingM.y); 230 | legC3 = new PVector(neck.x, bottom.y - (bottom.y-shoulderL.y)/2); 231 | 232 | nbrFeet = int(random(2,6)); 233 | if(nbrFeet>4){ 234 | attributes.add("long-legged"); 235 | } 236 | 237 | } 238 | 239 | public void drawPattern(){ 240 | wingPattern = createGraphics(500,500); 241 | wingPattern.beginDraw(); 242 | wingPattern.background(wingsC1); 243 | wingPattern.noStroke(); 244 | 245 | int choose = int(random(0,11)); 246 | 247 | if(choose<1){ 248 | int tmp; 249 | int diff = int(random(30,200)); 250 | 251 | for(int r = 700; r>30; r-=diff){ 252 | wingPattern.fill(wingsC1); 253 | wingPattern.ellipse(wingM.x,wingM.y,r,r); 254 | tmp = wingsC1; 255 | wingsC1 = wingsC2; 256 | wingsC2 = tmp; 257 | } 258 | attributes.add("ringed"); 259 | }else if(choose<2){ 260 | wingPattern.fill(wingsC2); 261 | int r = int(random(5,40)); 262 | int nbr = int(random(100,500)); 263 | for(int i = 0; i=1){ 304 | canvas.bezier(antennaL1.x, antennaL1.y, antennaL1.x-antennaHandle, antennaL1.y, antennaL2.x, antennaL2.y, antennaL2.x, antennaL2.y); 305 | canvas.bezier(antennaR1.x, antennaR1.y, antennaR1.x+antennaHandle, antennaR1.y, antennaR2.x, antennaR2.y, antennaR2.x, antennaR2.y); 306 | 307 | switch(end){ 308 | case 1: 309 | canvas.ellipse(antennaR2.x,antennaR2.y,param*2,param*2); 310 | canvas.ellipse(antennaL2.x,antennaL2.y,param*2,param*2); 311 | break; 312 | case 2: 313 | for(int i = 1; i<=param; i++){ 314 | float x = bezierPoint(antennaR1.x, antennaR1.x+antennaHandle, antennaR2.x, antennaR2.x, 1-(i*0.05f)); 315 | float y = bezierPoint(antennaR1.y, antennaR1.y, antennaR2.y, antennaR2.y, 1-(i*0.05f)); 316 | float tx = bezierTangent(antennaR1.x, antennaR1.x+antennaHandle, antennaR2.x, antennaR2.x, 1-(i*0.05f)); 317 | float ty = bezierTangent(antennaR1.y, antennaR1.y, antennaR2.y, antennaR2.y, 1-(i*0.05f)); 318 | float a = atan2(ty, tx); 319 | a -= HALF_PI; 320 | canvas.line(x, y, cos(a)*len + x, sin(a)*len + y); 321 | 322 | 323 | 324 | x = bezierPoint(antennaL1.x, antennaL1.x-antennaHandle, antennaL2.x, antennaL2.x, 1-(i*0.05f)); 325 | y = bezierPoint(antennaL1.y, antennaL1.y, antennaL2.y, antennaL2.y, 1-(i*0.05f)); 326 | tx = bezierTangent(antennaL1.x, antennaL1.x-antennaHandle, antennaL2.x, antennaL2.x, 1-(i*0.05f)); 327 | ty = bezierTangent(antennaL1.y, antennaL1.y, antennaL2.y, antennaL2.y, 1-(i*0.05f)); 328 | a = atan2(ty, tx); 329 | a -= HALF_PI; 330 | canvas.line(x, y, -cos(a)*len + x, -sin(a)*len + y); 331 | } 332 | break; 333 | } 334 | }else{ 335 | switch(end){ 336 | case 1: 337 | canvas.ellipse(antennaR1.x,antennaR1.y,param,param); 338 | canvas.ellipse(antennaL1.x,antennaL1.y,param,param); 339 | break; 340 | case 2: 341 | for(int i = 1; i<=param; i++){ 342 | float x = bezierPoint(head.x+(headV/4), head.x+(headV/4), antennaR1.x-antennaHandle, antennaR1.x, 1-(i*0.05f)); 343 | float y = bezierPoint(head.y, head.y-30, antennaR1.y, antennaR1.y, 1-(i*0.05f)); 344 | float tx = bezierTangent(head.x+(headV/4), head.x+(headV/4), antennaR1.x-antennaHandle, antennaR1.x, 1-(i*0.05f)); 345 | float ty = bezierTangent(head.y, head.y-30, antennaR1.y, antennaR1.y, 1-(i*0.05f)); 346 | float a = atan2(ty, tx); 347 | a -= HALF_PI; 348 | canvas.line(x, y, cos(a)*len + x, sin(a)*len + y); 349 | 350 | x = bezierPoint(head.x-(headV/4), head.x-(headV/4), antennaL1.x+antennaHandle, antennaL1.x, 1-(i*0.05f)); 351 | y = bezierPoint(head.y, head.y-30, antennaL1.y, antennaL1.y, 1-(i*0.05f)); 352 | tx = bezierTangent(head.x-(headV/4), head.x-(headV/4), antennaL1.x+antennaHandle, antennaL1.x, 1-(i*0.05f)); 353 | ty = bezierTangent(head.y, head.y-30, antennaL1.y, antennaL1.y, 1-(i*0.05f)); 354 | a = atan2(ty, tx); 355 | a -= HALF_PI; 356 | canvas.line(x, y, -cos(a)*len + x, -sin(a)*len + y); 357 | attributes.add("bristle feeler"); 358 | } 359 | break; 360 | } 361 | } 362 | } 363 | 364 | public void drawHead(){ 365 | canvas.ellipse(head.x,head.y,headV,headH); 366 | } 367 | 368 | public void drawBody(){ 369 | canvas.beginShape(); 370 | canvas.vertex(neck.x, neck.y); 371 | canvas.bezierVertex(neck.x+neckHandle, neck.y, shoulderR.x,shoulderR.y , shoulderR.x, shoulderR.y); 372 | canvas.bezierVertex(shoulderR.x,shoulderR.y , bottom.x+bottomHandle,bottom.y, bottom.x, bottom.y); 373 | canvas.bezierVertex(bottom.x-bottomHandle,bottom.y , shoulderL.x, shoulderL.y, shoulderL.x, shoulderL.y); 374 | canvas.bezierVertex(shoulderL.x,shoulderL.y,neck.x-neckHandle, neck.y, neck.x, neck.y); 375 | canvas.endShape(); 376 | } 377 | 378 | public PImage getReversePImage( PImage image ) { 379 | PImage reverse = new PImage( image.width, image.height ); 380 | for( int i=0; i < image.width; i++ ){ 381 | for(int j=0; j < image.height; j++){ 382 | reverse.set( image.width - 1 - i, j, image.get(i, j) ); 383 | } 384 | } 385 | return reverse; 386 | } 387 | 388 | public void drawWing(){ 389 | if(colored){ 390 | drawPattern(); 391 | 392 | wingMaskL = createGraphics(500,500); 393 | wingMaskL.beginDraw(); 394 | wingMaskL.beginShape(); 395 | wingMaskL.vertex(shoulderL.x, shoulderL.y); 396 | wingMaskL.bezierVertex(shoulderL.x, shoulderL.y, wingM.x-wingHandleM,wingM.y , wingM.x, wingM.y); 397 | wingMaskL.bezierVertex(wingM.x, wingM.y+wingHandleDown, wingL.x+wingHandlePoint, wingL.y, wingL.x, wingL.y); 398 | wingMaskL.bezierVertex(wingL.x-wingHandlePoint, wingL.y, shoulderL.x-wingHandleShoulder, shoulderL.y+wingHandleShoulder,shoulderL.x, shoulderL.y); 399 | wingMaskL.endShape(); 400 | wingMaskL.endDraw(); 401 | 402 | PImage pattern = wingPattern.get(); 403 | PImage mask = wingMaskL.get(); 404 | pattern.mask(mask); 405 | canvas.image(pattern,0,0); 406 | 407 | wingMaskR = createGraphics(500,500); 408 | wingMaskR.beginDraw(); 409 | wingMaskR.beginShape(); 410 | wingMaskR.vertex(shoulderR.x, shoulderR.y); 411 | wingMaskR.bezierVertex(shoulderR.x, shoulderR.y, wingM.x+wingHandleM,wingM.y , wingM.x, wingM.y); 412 | wingMaskR.bezierVertex(wingM.x, wingM.y+wingHandleDown, wingR.x-wingHandlePoint, wingR.y, wingR.x, wingR.y); 413 | wingMaskR.bezierVertex(wingR.x+wingHandlePoint, wingR.y, shoulderR.x+wingHandleShoulder, shoulderR.y+wingHandleShoulder,shoulderR.x, shoulderR.y); 414 | wingMaskR.endShape(); 415 | wingMaskR.endDraw(); 416 | 417 | pattern = getReversePImage(pattern); 418 | mask = wingMaskR.get(); 419 | pattern.mask(mask); 420 | canvas.image(pattern,0,0); 421 | 422 | canvas.noFill(); 423 | } 424 | 425 | 426 | canvas.beginShape(); 427 | canvas.vertex(shoulderL.x, shoulderL.y); 428 | canvas.bezierVertex(shoulderL.x, shoulderL.y, wingM.x-wingHandleM,wingM.y , wingM.x, wingM.y); 429 | canvas.bezierVertex(wingM.x, wingM.y+wingHandleDown, wingL.x+wingHandlePoint, wingL.y, wingL.x, wingL.y); 430 | canvas.bezierVertex(wingL.x-wingHandlePoint, wingL.y, shoulderL.x-wingHandleShoulder, shoulderL.y+wingHandleShoulder,shoulderL.x, shoulderL.y); 431 | canvas.endShape(); 432 | 433 | canvas.beginShape(); 434 | canvas.vertex(shoulderR.x, shoulderR.y); 435 | canvas.bezierVertex(shoulderR.x, shoulderR.y, wingM.x+wingHandleM,wingM.y , wingM.x, wingM.y); 436 | canvas.bezierVertex(wingM.x, wingM.y+wingHandleDown, wingR.x-wingHandlePoint, wingR.y, wingR.x, wingR.y); 437 | canvas.bezierVertex(wingR.x+wingHandlePoint, wingR.y, shoulderR.x+wingHandleShoulder, shoulderR.y+wingHandleShoulder,shoulderR.x, shoulderR.y); 438 | canvas.endShape(); 439 | } 440 | 441 | public void drawLegs(){ 442 | canvas.pushMatrix(); 443 | canvas.translate(legC1.x,legC1.y); 444 | canvas.rotate(radians(legAngleC1)); 445 | canvas.rect(0,0,legLength, legThickness); 446 | 447 | canvas.translate(legLength,0); 448 | canvas.rotate(radians(legAngle2C1)); 449 | canvas.rect(0,0,legLength/2, legThickness); 450 | 451 | canvas.translate(legLength/2,legThickness/2); 452 | canvas.rotate(radians(legAngle3C1)); 453 | for(int i = 0; i