├── output ├── nuts.png ├── rays.png ├── barber.png ├── fever.png ├── lemons.png ├── maccha.png ├── roller.png ├── shijo.png ├── tiger.png ├── tires.png ├── bulge02c.png ├── candies.png ├── gatmago.png ├── joro-gumo.png ├── montage.jpg ├── omikuji.png ├── red_mist.png ├── rollers.png ├── snake_1.png ├── turtles.png ├── ferryboats.png ├── negajo_2011.png ├── persimmons.png ├── red_spiral.png ├── staircases.png ├── autumn_color.png ├── barber_spirals.png ├── bavarian_cream.png ├── candies_rev2.png ├── chestnut_grove.png ├── dragon_scales.png ├── floating_heart.png ├── green_spiral.png ├── kids_of_seals.png ├── makudonarudo.png ├── neural_network.png ├── petit_tomatoes.png ├── primroses_hill.png ├── roller_torus.png ├── rotating_rays.png ├── uzummaki_ampan.png ├── neural_circuits.png ├── packed_cherries.png ├── primroses_field.png ├── rotating_snakes.png ├── wedding_in_japan.png ├── aproaching_asteroid.png ├── autumn_color_swamp.png ├── autumn_color_wave.png ├── primroses_spirals.png └── primroses_circulation.png ├── make_montage ├── data │ └── HelveticaNeue-Light-18.vlw └── make_montage.pyde ├── README.md ├── staircases └── staircases.pyde ├── approaching_asteroid └── approaching_asteroid.pyde ├── red_mist └── red_mist.pyde ├── wedding_in_japan └── wedding_in_japan.pyde ├── joro_gumo └── joro_gumo.pyde ├── barber └── barber.pyde ├── autumn_color └── autumn_color.pyde ├── chestnut_grove └── chestnut_grove.pyde ├── uzammaki └── uzammaki.pyde ├── barber_spirals └── barber_spirals.pyde ├── floating_heart └── floating_heart.pyde ├── omikuji └── omikuji.pyde ├── maccha └── maccha.pyde ├── autumn_color_wave └── autumn_color_wave.pyde ├── gatamago └── gatamago.pyde ├── tires └── tires.pyde ├── fever └── fever.pyde ├── roller └── roller.pyde ├── lemons └── lemons.pyde ├── primroses_field └── primroses_field.pyde ├── rollers └── rollers.pyde ├── kids_of_seals └── kids_of_seals.pyde ├── spiral_1 └── spiral_1.pyde ├── neural_circuits └── neural_circuits.pyde ├── primroses_hill └── primroses_hill.pyde ├── primroses_circulation └── primroses_circulation.pyde ├── turtles └── turtles.pyde ├── dragon_scales └── dragon_scales.pyde ├── makudonarudo └── makudonarudo.pyde ├── autumn_color_swamp └── autumn_color_swamp.pyde ├── primroses_spirals └── primroses_spirals.pyde ├── bulge └── bulge.pyde ├── snake_1 └── snake_1.pyde ├── nuts └── nuts.pyde ├── packed_cherries └── packed_cherries.pyde ├── rotating_rays └── rotating_rays.pyde ├── neural_network └── neural_network.pyde ├── rays └── rays.pyde ├── persimmons └── persimmons.pyde ├── tiger └── tiger.pyde ├── rotating_snakes └── rotating_snakes.pyde ├── petit_tomatoes └── petit_tomatoes.pyde ├── ferryboats └── ferryboats.pyde ├── shijo └── shijo.pyde ├── bavarian_cream └── bavarian_cream.pyde ├── candies └── candies.pyde ├── roller_torus └── roller_torus.pyde └── negajo_2011 └── negajo_2011.pyde /output/nuts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/nuts.png -------------------------------------------------------------------------------- /output/rays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/rays.png -------------------------------------------------------------------------------- /output/barber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/barber.png -------------------------------------------------------------------------------- /output/fever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/fever.png -------------------------------------------------------------------------------- /output/lemons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/lemons.png -------------------------------------------------------------------------------- /output/maccha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/maccha.png -------------------------------------------------------------------------------- /output/roller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/roller.png -------------------------------------------------------------------------------- /output/shijo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/shijo.png -------------------------------------------------------------------------------- /output/tiger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/tiger.png -------------------------------------------------------------------------------- /output/tires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/tires.png -------------------------------------------------------------------------------- /output/bulge02c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/bulge02c.png -------------------------------------------------------------------------------- /output/candies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/candies.png -------------------------------------------------------------------------------- /output/gatmago.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/gatmago.png -------------------------------------------------------------------------------- /output/joro-gumo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/joro-gumo.png -------------------------------------------------------------------------------- /output/montage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/montage.jpg -------------------------------------------------------------------------------- /output/omikuji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/omikuji.png -------------------------------------------------------------------------------- /output/red_mist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/red_mist.png -------------------------------------------------------------------------------- /output/rollers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/rollers.png -------------------------------------------------------------------------------- /output/snake_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/snake_1.png -------------------------------------------------------------------------------- /output/turtles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/turtles.png -------------------------------------------------------------------------------- /output/ferryboats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/ferryboats.png -------------------------------------------------------------------------------- /output/negajo_2011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/negajo_2011.png -------------------------------------------------------------------------------- /output/persimmons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/persimmons.png -------------------------------------------------------------------------------- /output/red_spiral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/red_spiral.png -------------------------------------------------------------------------------- /output/staircases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/staircases.png -------------------------------------------------------------------------------- /output/autumn_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/autumn_color.png -------------------------------------------------------------------------------- /output/barber_spirals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/barber_spirals.png -------------------------------------------------------------------------------- /output/bavarian_cream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/bavarian_cream.png -------------------------------------------------------------------------------- /output/candies_rev2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/candies_rev2.png -------------------------------------------------------------------------------- /output/chestnut_grove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/chestnut_grove.png -------------------------------------------------------------------------------- /output/dragon_scales.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/dragon_scales.png -------------------------------------------------------------------------------- /output/floating_heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/floating_heart.png -------------------------------------------------------------------------------- /output/green_spiral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/green_spiral.png -------------------------------------------------------------------------------- /output/kids_of_seals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/kids_of_seals.png -------------------------------------------------------------------------------- /output/makudonarudo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/makudonarudo.png -------------------------------------------------------------------------------- /output/neural_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/neural_network.png -------------------------------------------------------------------------------- /output/petit_tomatoes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/petit_tomatoes.png -------------------------------------------------------------------------------- /output/primroses_hill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/primroses_hill.png -------------------------------------------------------------------------------- /output/roller_torus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/roller_torus.png -------------------------------------------------------------------------------- /output/rotating_rays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/rotating_rays.png -------------------------------------------------------------------------------- /output/uzummaki_ampan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/uzummaki_ampan.png -------------------------------------------------------------------------------- /output/neural_circuits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/neural_circuits.png -------------------------------------------------------------------------------- /output/packed_cherries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/packed_cherries.png -------------------------------------------------------------------------------- /output/primroses_field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/primroses_field.png -------------------------------------------------------------------------------- /output/rotating_snakes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/rotating_snakes.png -------------------------------------------------------------------------------- /output/wedding_in_japan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/wedding_in_japan.png -------------------------------------------------------------------------------- /output/aproaching_asteroid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/aproaching_asteroid.png -------------------------------------------------------------------------------- /output/autumn_color_swamp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/autumn_color_swamp.png -------------------------------------------------------------------------------- /output/autumn_color_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/autumn_color_wave.png -------------------------------------------------------------------------------- /output/primroses_spirals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/primroses_spirals.png -------------------------------------------------------------------------------- /output/primroses_circulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/output/primroses_circulation.png -------------------------------------------------------------------------------- /make_montage/data/HelveticaNeue-Light-18.vlw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbum/kitaoka_illusions/HEAD/make_montage/data/HelveticaNeue-Light-18.vlw -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Optical Illusions by Akiyoshi Kitaoka, Professor, Department of Psychology, Ritsumeikan University, Kyoto, Japan 2 | 3 | http://www.ritsumei.ac.jp/~akitaoka/index-e.html 4 | 5 | https://twitter.com/AkiyoshiKitaoka/ 6 | 7 | These are reconstructions based on images published by Professor Kitaoka in his books and on his website. The goal is to eventually reconstruct most of the full-page illustrations from the 2002 book "Trick Eyes" as well as a number of notable images from Kitaoka's website. 8 | 9 | All of these images are programmed in the Python dialect of Processing. 10 | 11 | ![Kitaoka Illusions](https://github.com/jbum/kitaoka_illusions/blob/master/output/montage.jpg "Kitaoka Illusions") 12 | 13 | 14 | -------------------------------------------------------------------------------- /staircases/staircases.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Staircases" motion/stereopsis/lightness illusion, appears on page 49 4 | # no reference image used 5 | # 6 | # same as background of joro-gumo 7 | 8 | 9 | output_name = "staircases" 10 | 11 | subsquares = 48 12 | 13 | scolors = [color(0),color(255)] 14 | 15 | def setup(): 16 | size(1024,1024) 17 | noLoop() 18 | 19 | def draw(): 20 | tw = width/float(subsquares) 21 | background(0) 22 | strokeWeight(1) 23 | for y in range(subsquares): 24 | for x in range(subsquares): 25 | if x < 12 or y < 12 or x >= subsquares-12 or y >= subsquares-12: 26 | ctr = ((1+x+y*5) % 6)/3 27 | else: 28 | ctr = ((2+x+y) % 6)/3 29 | fill(scolors[ctr]) 30 | stroke(scolors[ctr]) 31 | rect(x*tw,y*tw,tw,tw) 32 | 33 | saveFrame("../output/" + output_name + ".png") 34 | -------------------------------------------------------------------------------- /make_montage/make_montage.pyde: -------------------------------------------------------------------------------- 1 | import glob, re 2 | 3 | cw,ch = (178,178) 4 | gw,gh = (5,10) 5 | 6 | def setup(): 7 | size(890,1780) # cw*gw, ch*gh 8 | noLoop() 9 | textFont(loadFont("HelveticaNeue-Light-18.vlw"),18) 10 | textAlign(CENTER,CENTER) 11 | 12 | def draw(): 13 | global gw,gh,cw,ch 14 | background(255) 15 | for n,fname in enumerate(glob.glob(sketchPath()+'/../output/*.png')): 16 | pimg = loadImage(fname) 17 | x = n%gw 18 | y = n/gw 19 | sc = float(cw)/pimg.width 20 | pushMatrix() 21 | translate(x*cw+cw/2.0,y*ch+ch/2.0) 22 | scale(sc) 23 | image(pimg,-pimg.width/2,-pimg.height/2) 24 | popMatrix() 25 | 26 | for n,fname in enumerate(glob.glob(sketchPath()+'/../output/*.png')): 27 | x = n%gw 28 | y = n/gw 29 | m = re.search(".*/([\w\-]+)\.png",fname) 30 | if m: 31 | txt = m.group(1) 32 | fill(255,200) 33 | noStroke() 34 | rect(x*cw,y*ch+ch-24,cw,24) 35 | fill(20) 36 | text(txt, x*cw+cw/2,y*ch+ch-14) 37 | 38 | saveFrame("../output/montage.jpg") -------------------------------------------------------------------------------- /approaching_asteroid/approaching_asteroid.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "An Approaching Asteroid" motionr illusion, color illusion appears on page 6 4 | # no online reference image found: similar to http://www.psy.ritsumei.ac.jp/~akitaoka/showaku12s.jpg 5 | 6 | 7 | output_name = "aproaching_asteroid" 8 | bg_color = color(255) 9 | outer_colors = [color(0),color(255)] 10 | inner_colors = [color(0),color(29,0,253)] 11 | ring_color = color(0) 12 | 13 | orad_ratio = 110/151.0 14 | irad_ratio = 93/151.0 15 | 16 | density = 128 17 | 18 | def setup(): 19 | size(1024,1024) 20 | noLoop() 21 | 22 | def draw(): 23 | cw = width/float(density) 24 | noStroke() 25 | for y in xrange(density): 26 | for x in xrange(density): 27 | d = dist(density/2.0,density/2.0,x,y) 28 | if d < irad_ratio*density*0.5: 29 | fill(inner_colors[int(random(2))]) 30 | elif d > orad_ratio*density*0.5: 31 | fill(outer_colors[int(random(2))]) 32 | else: 33 | fill(ring_color) 34 | rect(x*cw,y*cw,cw,cw) 35 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /red_mist/red_mist.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Red Mist" perceptual transparency appearson page 36 4 | # no online reference imagefound 5 | 6 | output_name = "red_mist" 7 | 8 | c_colors = [color(255,255,0),color(0,0,255)] 9 | mist_color = color(255,0,0) 10 | bg_color = color(255) 11 | checkers = 8 12 | 13 | def setup(): 14 | size(1024,1024) # intentionally a multiple of gw+margin_checkers*2 for sharp pixel boundaries 15 | noLoop() 16 | 17 | def draw(): 18 | 19 | cw = width/float(checkers) 20 | 21 | background(bg_color) 22 | pushMatrix() 23 | 24 | # draw checkers 25 | for y in xrange(checkers): 26 | for x in xrange(checkers): 27 | fill(c_colors[(x+y) % 2]) 28 | noStroke() 29 | rect(x*cw,y*cw,cw,cw) 30 | 31 | # draw red mist 32 | for i in xrange(width): 33 | ang = (i % (cw*2))/float(cw*2) 34 | alfa = 1-sin(ang*PI) 35 | stroke(255,0,0,255*alfa) 36 | line(i,0,i+width,height) 37 | line(0,i,height,i+height) 38 | line(width-i,0,width-i-width,height) 39 | line(width,i,0,i+height) 40 | 41 | popMatrix() 42 | 43 | 44 | saveFrame("../output/" + output_name + ".png") 45 | 46 | -------------------------------------------------------------------------------- /wedding_in_japan/wedding_in_japan.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Wedding in Japan" motion illusion / geometrical illusion appears on page 15 4 | # no reference image found 5 | 6 | output_name = "wedding_in_japan" 7 | 8 | nbr_bg_checks = 7 9 | 10 | bg_color = color(255) 11 | bg_check_color = color(102,121,67) 12 | fg_check_colors = [color(255),color(0),color(255,20,20,),color(255)] 13 | pattern = (0,1,0,1,1,0,1,0) 14 | 15 | def setup(): 16 | size(1024,1024) 17 | noLoop() 18 | 19 | def draw(): 20 | gw = (nbr_bg_checks*2-1) 21 | background(bg_color) 22 | 23 | tw = width/float(gw) 24 | noStroke() 25 | for y in xrange(gw): 26 | for x in xrange(gw): 27 | if (x+y)%2 == 0: 28 | fill(bg_check_color) 29 | rect(x*tw,y*tw,tw,tw) 30 | mw = tw*2/3 31 | mr = mw/2.0 32 | strokeWeight(width*1/640.0) 33 | for y in xrange(1,gw): 34 | for x in xrange(1,gw): 35 | pat = pattern[(y*7+x)%len(pattern)] 36 | if y == 1: 37 | print (y*7+x)%len(pattern) 38 | fill(fg_check_colors[2*pat]) 39 | stroke(fg_check_colors[1+2*pat]) 40 | rect(x*tw-mr,y*tw-mr,mw,mw) 41 | saveFrame("../output/" + output_name + ".png") 42 | -------------------------------------------------------------------------------- /joro_gumo/joro_gumo.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Joro-gumo" motion illusion, geometrical illusion appears on page 19 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/jorogumo.gif 5 | 6 | output_name = "joro-gumo" 7 | 8 | subsquares = 48 9 | orig_meas_width = 384 10 | 11 | scolors = [color(0),color(255,255,25)] 12 | lcolors = [color(255,20,20),color(128)] 13 | 14 | 15 | def setup(): 16 | size(1024,1024) 17 | noLoop() 18 | 19 | def draw(): 20 | tw = width/float(subsquares) 21 | background(0) 22 | strokeWeight(1) 23 | for y in range(subsquares): 24 | for x in range(subsquares): 25 | if x < 12 or y < 12 or x >= subsquares-12 or y >= subsquares-12: 26 | ctr = ((1+x+y*5) % 6)/3 27 | else: 28 | ctr = ((2+x+y) % 6)/3 29 | fill(scolors[ctr]) 30 | stroke(scolors[ctr]) 31 | rect(x*tw,y*tw,tw,tw) 32 | noFill() 33 | strokeWeight(width*1/float(orig_meas_width)) 34 | stroke(lcolors[0]) 35 | for x in xrange(1,subsquares,2): 36 | line(x*tw,0,x*tw,height) 37 | stroke(lcolors[1]) 38 | for y in xrange(1,subsquares,2): 39 | line(0,y*tw,width,y*tw) 40 | 41 | 42 | saveFrame("../output/" + output_name + ".png") 43 | -------------------------------------------------------------------------------- /barber/barber.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "The Barber" rotational illusion appears on page 25 4 | # no online reference image found 5 | 6 | output_name = "barber" 7 | bg_color = color(109,162,183) 8 | 9 | # this effect is actually stronger if you just use red,white,blue instead of the 4 colors in the original 10 | # s_colors = (color(0,0,255),color(255),color(255,0,0)) 11 | s_colors = (color(0,0,255),color(255),color(255,0,0),color(255)) 12 | rad_factors = (52/76.0, 66.5/76.0) 13 | 14 | def setup(): 15 | size(1024,1024) 16 | noLoop() 17 | 18 | stripes = 120 19 | stripe_len = TWO_PI/(stripes/2) 20 | 21 | def draw(): 22 | background(bg_color) 23 | 24 | pushMatrix() 25 | translate(width/2,height/2) 26 | strokeWeight(width*2/760.0) 27 | ring_width = width*3/760 28 | for n,rf in enumerate(rad_factors): 29 | rad = rf*width/2.0 30 | for i in xrange(stripes): 31 | a1 = i*TWO_PI/stripes 32 | a2 = a1 + stripe_len*(-1 if n == 0 else 1) 33 | r1 = rad-ring_width/2.0 34 | r2 = rad+ring_width/2.0 35 | stroke(s_colors[(i + (len(s_colors)-1)*n) % len(s_colors)]) 36 | line(cos(a1)*r1,sin(a1)*r1,cos(a2)*r2,sin(a2)*r2) 37 | popMatrix() 38 | 39 | saveFrame("../output/" + output_name + ".png") 40 | 41 | 42 | -------------------------------------------------------------------------------- /autumn_color/autumn_color.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Autumn Color" geometrical illusion appears on page 44 4 | # no online reference image found, note "chestnut grove" uses the same algorithm 5 | 6 | output_name = "autumn_color" 7 | 8 | checkers = 21 9 | 10 | ccolors = [ 11 | color(255),color(255,255,20),color(255,205,20),color(255,128,20),color(255,20,20),color(0), 12 | ] 13 | 14 | o_color = color(255,20,20) 15 | bg_color = color(255) 16 | 17 | orig_width = 512 18 | 19 | def setup(): 20 | size(1024,1024) 21 | noLoop() 22 | 23 | def base_ctr(i): 24 | im = i % 10 25 | return (im % 5) if im < 5 else 5-(im % 5) 26 | 27 | def draw(): 28 | margin = 8*width/float(orig_width) 29 | tw = (width-margin*2)/float(checkers) 30 | background(bg_color) 31 | 32 | strokeWeight(width*1/float(orig_width)) 33 | pushMatrix() 34 | translate(margin,margin) 35 | for y in xrange(checkers): 36 | y_ctr = base_ctr(y) 37 | for x in xrange(checkers): 38 | x_ctr = base_ctr(x) 39 | py = y*tw 40 | px = x*tw 41 | stroke(o_color) 42 | ctr = abs(y_ctr - x_ctr) 43 | fill(ccolors[ctr]) 44 | rect(px,py,tw,tw) 45 | popMatrix() 46 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /chestnut_grove/chestnut_grove.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "A Chestnut Grove" geometrical illusion appears on page 45 4 | # no online reference image found, note "autumn color" uses the same algorithm 5 | 6 | 7 | output_name = "chestnut_grove" 8 | 9 | checkers = 21 10 | ccolors = [color(255),color(231,231,219),color(218,180,160),color(187,148,62),color(104,15,26),color(0)] 11 | o_color = color(187,211,141) 12 | bg_color = color(255) 13 | 14 | orig_width = 512 15 | 16 | def setup(): 17 | size(1024,1024) 18 | noLoop() 19 | ccolors = [] 20 | 21 | 22 | def base_ctr(i): 23 | im = i % 10 24 | return (im % 5) if im < 5 else 5-(im % 5) 25 | 26 | def draw(): 27 | margin = 8*width/float(orig_width) 28 | tw = (width-margin*2)/float(checkers) 29 | background(bg_color) 30 | 31 | strokeWeight(width*1/float(orig_width)) 32 | pushMatrix() 33 | translate(margin,margin) 34 | for y in xrange(checkers): 35 | y_ctr = base_ctr(y) 36 | for x in xrange(checkers): 37 | x_ctr = base_ctr(x) 38 | py = y*tw 39 | px = x*tw 40 | stroke(o_color) 41 | ctr = abs(y_ctr - x_ctr) 42 | fill(ccolors[ctr]) 43 | rect(px,py,tw,tw) 44 | popMatrix() 45 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /uzammaki/uzammaki.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of optical illusions by Akiyoshi Kitaoka 2 | 3 | # "uzummaki ampan" spiral illusion appears on website 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/uzuampan2011b.jpg 5 | 6 | orig_width = 300.0 7 | orig_rad = 145.0 8 | output_name = "uzummaki_ampan" 9 | bg_color = color(255) 10 | cen_color = color(128) 11 | ring_color = color(176) 12 | spokes = 36 13 | rings = 17 14 | 15 | lim = sum([sin(map(i+1,0,rings,0,PI))**2 for i in xrange(rings)]) # 9.5143 16 | 17 | def setup(): 18 | size(800,800) 19 | print "limit",lim 20 | noLoop() 21 | 22 | def draw(): 23 | ellipseMode(RADIUS) 24 | 25 | background(bg_color) 26 | pushMatrix() 27 | translate(width/2,height/2) 28 | 29 | rad = width*orig_rad/orig_width 30 | crad = rad 31 | s_ang = TWO_PI/spokes 32 | strokeWeight(width*1.0/orig_width) 33 | for i in xrange(rings): 34 | noStroke() 35 | if i == rings-1: 36 | fill(cen_color) 37 | ellipse(0,0,crad,crad) 38 | else: 39 | for s in xrange(spokes): 40 | a1 = s_ang*i/2.0+map(s,0,spokes,0,TWO_PI) 41 | a2 = s_ang*i/2.0+map(s+1,0,spokes,0,TWO_PI) 42 | fill(255*(s & 1)) 43 | arc(0,0,crad,crad,a1,a2) 44 | stroke(ring_color) 45 | noFill() 46 | ellipse(0,0,crad,crad) 47 | crad -= rad*sin(map(i+1,0,rings,0,PI))**2/lim 48 | 49 | popMatrix() 50 | saveFrame("../output/" + output_name + ".png") 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /barber_spirals/barber_spirals.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Barber Spirals" spiral illusion appears on page 30 4 | # no online reference image found, but similar in concept to http://www.psy.ritsumei.ac.jp/~akitaoka/cafewallspiral.jpg 5 | 6 | stripes = 40 7 | 8 | output_name = "barber_spirals" 9 | s_colors = [color(20,120,200), color(255),color(200,70,100),color(255)] 10 | bg_color = color(255) 11 | 12 | radius_ratio = 0.471 13 | ring_side_ratio = 1.1 14 | 15 | stripes = 36*2 16 | 17 | def setup(): 18 | size(1024,1024) 19 | noLoop() 20 | 21 | def draw(): 22 | ellipseMode(RADIUS) 23 | background(bg_color) 24 | noStroke() 25 | 26 | pushMatrix() 27 | translate(width/2,height/2) 28 | 29 | rad = width*radius_ratio 30 | 31 | n = 0 32 | s_ang = TWO_PI/stripes 33 | while rad > 1: 34 | circ = TWO_PI*rad 35 | side = circ/float(stripes) 36 | rad2 = rad-side*ring_side_ratio 37 | noStroke() 38 | for i in xrange(stripes): 39 | pushMatrix() 40 | rotate(-n*s_ang/2-i*s_ang) 41 | ctr = i%4 42 | fill(s_colors[ctr]) 43 | stroke(s_colors[ctr]) 44 | quad(cos(0)*rad2, sin(0)*rad2, 45 | cos(-s_ang)*rad2,sin(-s_ang)*rad2, 46 | cos(-s_ang)*rad,sin(-s_ang)*rad, 47 | cos(0)*rad, sin(0)*rad) 48 | popMatrix() 49 | noFill() 50 | strokeWeight(.07*TWO_PI*rad/stripes) 51 | stroke(192) 52 | ellipse(0,0,rad,rad) 53 | rad = rad2 54 | n += 1 55 | popMatrix() 56 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /floating_heart/floating_heart.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "The Floating Heart" color illusion / motion illusion appears on page 14 4 | # reference image here: http://www.ritsumei.ac.jp/~akitaoka/heart-u.gif 5 | 6 | output_name = "floating_heart" 7 | 8 | pat = ''' 9 | .*.*.*.*.*.*.*.*.*.*.*. 10 | *.*.*.*.*.*.*.*.*.*.*.* 11 | .*.*.*.*.*.*.*.*.*.*.*. 12 | *.*.*.....*.*.....*.*.* 13 | .*.*..+.+..*..+.+..*.*. 14 | *.*..+.+.+...+.+.+..*.* 15 | .*..+.+.+.+.+.+.+.+..*. 16 | *..+.+.+.+.+.+.+.+.+..* 17 | .*..+.+.+.+.+.+.+.+..*. 18 | *..+.+.+.+.+.+.+.+.+..* 19 | .*..+.+.+.+.+.+.+.+..*. 20 | *.*..+.+.+.+.+.+.+..*.* 21 | .*.*..+.+.+.+.+.+..*.*. 22 | *.*.*..+.+.+.+.+..*.*.* 23 | .*.*.*..+.+.+.+..*.*.*. 24 | *.*.*.*..+.+.+..*.*.*.* 25 | .*.*.*.*..+.+..*.*.*.*. 26 | *.*.*.*.*..+..*.*.*.*.* 27 | .*.*.*.*.*...*.*.*.*.*. 28 | *.*.*.*.*.*.*.*.*.*.*.* 29 | .*.*.*.*.*.*.*.*.*.*.*. 30 | ''' 31 | 32 | bg_color = color(255,20,20) 33 | check_color = color(20,255,20) 34 | heart_color = color(0) 35 | 36 | # pattern is 23 x 21 37 | def setup(): 38 | size(1012,924) 39 | noLoop() 40 | 41 | def draw(): 42 | background(bg_color) 43 | noStroke() 44 | lines = pat.lstrip().rstrip().split('\n') 45 | checksize = width/float(len(lines[0])) 46 | for y,line in enumerate(lines): 47 | for x,ch in enumerate(line): 48 | if ch == '+': 49 | fill(heart_color) 50 | elif ch == '*': 51 | fill(check_color) 52 | else: 53 | continue 54 | rect(x*checksize,y*checksize,checksize,checksize) 55 | saveFrame("../output/" + output_name + ".png") 56 | -------------------------------------------------------------------------------- /omikuji/omikuji.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Omikuji" op effect, motion illusion appears on page 34 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/shijo.gif 5 | 6 | output_name = "omikuji" 7 | 8 | c_colors = [color(254,19,18),color(0),color(254,154,20),color(255)] 9 | bg_color = color(255) 10 | checkers = 11 11 | orig_width = 339 12 | 13 | def setup(): 14 | size(1024,1024) # intentionally a multiple of gw+margin_checkers*2 for sharp pixel boundaries 15 | noLoop() 16 | 17 | def draw(): 18 | margin = width*5.0/orig_width 19 | 20 | cw = (width-margin*2)/checkers 21 | 22 | background(bg_color) 23 | pushMatrix() 24 | translate(margin,margin) 25 | 26 | # draw checkers 27 | for y in xrange(checkers): 28 | for x in xrange(checkers): 29 | c_idx = ((x+y)%2)*2 30 | fill(c_colors[c_idx]) 31 | noStroke() 32 | rect(x*cw,y*cw,cw,cw) 33 | 34 | translate(cw,cw) 35 | for y in xrange(checkers-1): 36 | for x in xrange(checkers-1): 37 | d = dist(4.5,4.5,x,y) 38 | if d < 5: 39 | c_idx = (x+y)%2 # !! 40 | if (x < 5) != (y < 5): 41 | c_idx = 1-c_idx 42 | c_idx *= 2 43 | fill(c_colors[c_idx]) 44 | rect(x*cw-cw*11/30.0,y*cw-cw*11/30.0,cw*22/30.0,cw*22/30.0) 45 | fill(c_colors[c_idx+1]) 46 | rect(x*cw-cw*9/30.0,y*cw-cw*9/30.0,cw*18/30.0,cw*18/30.0) 47 | 48 | pushMatrix() 49 | 50 | 51 | popMatrix() 52 | 53 | 54 | saveFrame("../output/" + output_name + ".png") 55 | 56 | -------------------------------------------------------------------------------- /maccha/maccha.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Maccha" motion illusion appears on page 8 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/macchacircleplastics.jpg 5 | 6 | output_name = "maccha" 7 | background_color = color(149,202,12) 8 | dark_green_color = color(0,100,2) 9 | white_color = color(255) 10 | gray_color = color(192) 11 | dot_rad_ratio = .005 12 | 13 | def setup(): 14 | size(1024,1024) 15 | noLoop() 16 | 17 | def draw(): 18 | stripes = 16 19 | nbr_samples = 20 20 | amp = 1.2*width/stripes 21 | margin = height/8.0 22 | background(background_color) 23 | for i in xrange(stripes): 24 | strokeWeight(0.65*(width-margin*2)/float(stripes)) 25 | strokeCap(SQUARE) 26 | stroke(dark_green_color if i % 2 == 0 else white_color) 27 | noFill() 28 | beginShape() 29 | xc = map(i,0,stripes-1,margin,width-margin) 30 | # vertex(margin,xc) 31 | for y in xrange(-2,nbr_samples+2): 32 | py = map(y,0,nbr_samples-1,margin,height-margin) 33 | ang = map(y,0,nbr_samples-1,0,TWO_PI*2) 34 | px = xc - sin(ang)*amp 35 | curveVertex(px,py) 36 | # vertex(height-margin,xc) 37 | endShape() 38 | nbr_dot_rows = 5 39 | ellipseMode(RADIUS) 40 | fill(gray_color) 41 | noStroke() 42 | dot_rad = width*dot_rad_ratio 43 | for i in xrange(stripes): 44 | px = map(i,0,stripes-1,margin,width-margin) 45 | yd = (height-margin*2)*0.25 46 | for i in xrange(5): 47 | py = margin+yd*i 48 | ellipse(px,py,dot_rad,dot_rad) 49 | saveFrame("../output/" + output_name + ".png") 50 | 51 | 52 | -------------------------------------------------------------------------------- /autumn_color_wave/autumn_color_wave.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Waves of Autumn Color" motion illusion, geometrical illusion appears on page 20 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/koyowave.jpg 5 | 6 | output_name = "autumn_color_wave" 7 | 8 | checkers_h = 21 9 | checkers_v = 13 10 | cmargin = 9 11 | 12 | ccolors = [color(255,220,144), 13 | color(255,170,20)] 14 | scolors = [color(253,255,178), 15 | color(203,13,14)] 16 | 17 | pattern = (0,1,1,0,1,0,0,1) 18 | 19 | def setup(): 20 | size(1092,676) 21 | noLoop() 22 | 23 | debug = False 24 | 25 | def quadstar(dsize): 26 | beginShape() 27 | vertex(0,-dsize) 28 | quadraticVertex(0,0,dsize,0) 29 | quadraticVertex(0,0,0,dsize) 30 | quadraticVertex(0,0,-dsize,0) 31 | quadraticVertex(0,0,0,-dsize) 32 | endShape() 33 | 34 | def draw(): 35 | csize_h = width/float(checkers_h) 36 | csize_v = height/float(checkers_v) 37 | 38 | noStroke() 39 | for y in xrange(checkers_v): 40 | for x in xrange(checkers_h): 41 | ctr = (x+y) % 2 42 | fill(ccolors[ctr]) 43 | px = x*csize_h 44 | py = y*csize_v 45 | rect(px,py,csize_h,csize_v) 46 | 47 | dsize = csize_h*.25 48 | noStroke() 49 | for y in xrange(1,checkers_v): 50 | for x in xrange(1,checkers_h): 51 | ctr = (x+y*7) % 8 52 | fill(scolors[pattern[ctr]]) 53 | px = x*csize_h 54 | py = y*csize_v 55 | pushMatrix() 56 | translate(px,py) 57 | quadstar(dsize) 58 | popMatrix() 59 | 60 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /gatamago/gatamago.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Eggs of a Moth" geometrical illusion appears on page 40 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/gatamago.gif 5 | 6 | output_name = "gatmago" 7 | 8 | c_colors = [color(158,128,128),color(212,192,192)] 9 | d_colors = [color(0),color(255)] 10 | bg_color = color(255) 11 | checkers = 11 12 | orig_width = 361 13 | 14 | def setup(): 15 | size(800,800) # intentionally a multiple of gw+margin_checkers*2 for sharp pixel boundaries 16 | noLoop() 17 | 18 | def draw(): 19 | ellipseMode(RADIUS) 20 | margin = width*4.0/orig_width 21 | 22 | cw = (width-margin*2)/checkers 23 | 24 | background(bg_color) 25 | pushMatrix() 26 | translate(margin,margin) 27 | 28 | # draw checkers 29 | for y in xrange(checkers): 30 | for x in xrange(checkers): 31 | c_idx = (x+y) % 2 32 | fill(c_colors[c_idx]) 33 | noStroke() 34 | rect(x*cw,y*cw,cw,cw) 35 | 36 | translate(cw*2,cw*2) 37 | cw2 = cw/2.0 38 | for y in xrange(checkers*2-7): 39 | for x in xrange(checkers*2-7): 40 | if ((x+y)%2) > 0: 41 | continue 42 | ix = x%8 43 | invert = (x < 8) != (y < 8) 44 | if invert: 45 | c_idx = 1-((ix/2+7*y/2)%2) 46 | else: 47 | c_idx = (ix/2+y/2)%2 48 | fill(d_colors[c_idx]) 49 | ellipse(x*cw2,y*cw2,cw/4.0,cw/4.0) 50 | fill(d_colors[1-c_idx]) 51 | ellipse(x*cw2,y*cw2,cw/20.0,cw/20.0) 52 | 53 | pushMatrix() 54 | 55 | 56 | popMatrix() 57 | 58 | 59 | saveFrame("../output/" + output_name + ".png") 60 | 61 | -------------------------------------------------------------------------------- /tires/tires.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Tires" rotating illusion appears on page 50 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/tire.gif 5 | # 6 | 7 | # 8 | output_name = "tires" 9 | 10 | orig_width = 572 11 | r_ratios = (211.0/orig_width,264.0/orig_width) 12 | a1_angles = (-PI/4,-3*PI/4) 13 | a2_angles = (3*PI/4,PI/4) 14 | nbr_treads = 9*4 15 | tread_ratio1 = 2/7.0 16 | tread_ratio2 = 1/4.75 17 | bg_color = color(255) 18 | fg_color = color(0) 19 | 20 | def setup(): 21 | size(1024, 1024) 22 | noLoop() 23 | 24 | def draw(): 25 | strokeWeight(width*2.5/float(orig_width)) 26 | strokeCap(SQUARE) 27 | strokeJoin(ROUND) 28 | background(bg_color) 29 | stroke(fg_color) 30 | 31 | pushMatrix() 32 | translate(width/2, height/2) 33 | 34 | crad = width*13.5/orig_width 35 | line(-crad,0,crad,0) 36 | line(0,-crad,0,crad) 37 | 38 | 39 | 40 | for ri in xrange(2): 41 | rad = r_ratios[ri]*width 42 | circ = TWO_PI*rad/nbr_treads 43 | a1 = a1_angles[ri] 44 | a2 = a2_angles[ri] 45 | for t in xrange(nbr_treads): 46 | pushMatrix() 47 | rotate(t*TWO_PI/nbr_treads) 48 | pushMatrix() 49 | translate(rad,0) 50 | beginShape() 51 | vertex(0+cos(a1)*circ*tread_ratio2,-circ*tread_ratio1+sin(a1)*circ*tread_ratio2) 52 | vertex(0,-circ*tread_ratio1) 53 | vertex(0, circ*tread_ratio1) 54 | vertex(0+cos(a2)*circ*tread_ratio2, circ*tread_ratio1+sin(a2)*circ*tread_ratio2) 55 | endShape() 56 | popMatrix() 57 | popMatrix() 58 | 59 | popMatrix() 60 | saveFrame("../output/" + output_name + ".png") 61 | -------------------------------------------------------------------------------- /fever/fever.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Fever" rotation illusion on page 33 (also appears on cover) 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/fever.jpg 5 | 6 | stripes = 36*2 7 | 8 | output_name = "fever" 9 | dk_stripe_color= color(251,18,53) 10 | lt_stripe_color = color(226,199,19) 11 | s_colors = [dk_stripe_color, lt_stripe_color] 12 | white_dot_color = color(255,255,255) 13 | blue_dot_color = color(30,0,250) 14 | d_colors = [white_dot_color, blue_dot_color] 15 | background_color = color(255,255,255) 16 | 17 | def setup(): 18 | size(1024,1024) 19 | noLoop() 20 | 21 | def draw(): 22 | rad = width*.48 23 | rad1 = rad*.642 24 | rad2 = rad*.800 25 | ellipseMode(RADIUS) 26 | background(background_color) 27 | fill(dk_stripe_color) 28 | noStroke() 29 | pushMatrix() 30 | translate(width/2,height/2) 31 | for i in xrange(stripes): 32 | a1 = i*TWO_PI/stripes 33 | a2 = (i+1)*TWO_PI/stripes 34 | fill(s_colors[i % 2]) 35 | arc(0,0,rad,rad,a1,a2) 36 | fill(s_colors[(i+1) % 2]) 37 | arc(0,0,rad2,rad2,a1,a2) 38 | fill(s_colors[i % 2]) 39 | arc(0,0,rad1,rad1,a1,a2) 40 | for i in xrange(stripes): 41 | a1 = i*TWO_PI/stripes 42 | a2 = (i+1)*TWO_PI/stripes 43 | r1 = TWO_PI*rad1/(stripes*4) 44 | r2 = TWO_PI*rad2/(stripes*4) 45 | r1i = r1/3.5 46 | r2i = r2/3.5 47 | fill(d_colors[i % 2]) 48 | ellipse(cos(a1)*rad1,sin(a1)*rad1,r1,r1) 49 | ellipse(cos(a1)*rad2,sin(a1)*rad2,r2,r2) 50 | fill(d_colors[(i+1) % 2]) 51 | ellipse(cos(a1)*rad1,sin(a1)*rad1,r1i,r1i) 52 | ellipse(cos(a1)*rad2,sin(a1)*rad2,r2i,r2i) 53 | popMatrix() 54 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /roller/roller.pyde: -------------------------------------------------------------------------------- 1 | # Roller 2 | # based on variation by Beau Deeley http://www.horntorus.com/illustration/extern/BeauDeeley_01.jpg 3 | # based on pattern at http://www.psy.ritsumei.ac.jp/~akitaoka/rollersstrong3plastic.jpg 4 | 5 | output_name = "roller" 6 | rad = .99; 7 | freq = 30; 8 | shrink = 0.8 9 | lm = 20 10 | tm = 20 11 | 12 | bg_color = color(27,40,225) 13 | circ_color = color(244,114,2) 14 | light_color = color(255,255,255) 15 | dark_color = color(0,0,0) 16 | 17 | def setup(): 18 | global opart_shader, ographics 19 | size(1024,1024) 20 | 21 | ellipseMode(RADIUS) 22 | noLoop() 23 | 24 | 25 | def draw_circle_pattern(cx,cy,rad): 26 | sNbr = 0 27 | shrink = 0.8 28 | noStroke() 29 | tm = 0 # millis()*.001 30 | while rad > 20: 31 | irad = rad*shrink 32 | stripes = 42 33 | pushMatrix() 34 | translate(cx,cy) 35 | # rotate(PI/stripes) 36 | crad = (rad-irad)*.7*.39 37 | bord_scale = 0.8 # 0.8 38 | # draw checkers 39 | for s in range(stripes): 40 | pushMatrix() 41 | rotate(s*TWO_PI/stripes) 42 | pushMatrix() 43 | translate((irad+rad)/2.0,0) 44 | rotate(-tm*1.1) 45 | fill(dark_color) 46 | arc(0,0,crad,crad,0,PI) 47 | fill(light_color) 48 | arc(0,0,crad,crad,PI,TWO_PI) 49 | fill(circ_color) 50 | ellipse(0,0,crad*bord_scale,crad*bord_scale) 51 | popMatrix() 52 | # draw edges 53 | 54 | popMatrix() 55 | 56 | popMatrix() 57 | rad = irad 58 | sNbr += 1 59 | # draw ovals 60 | 61 | def draw(): 62 | global lm,tm 63 | background(bg_color) 64 | rad = (width-lm*2)/8 65 | draw_circle_pattern(width/2,height/2,width*.49) 66 | saveFrame("../output/" + output_name + ".png") 67 | -------------------------------------------------------------------------------- /lemons/lemons.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of optical illusions by Akiyoshi Kitaoka 2 | 3 | # "Lemons" rotation illusion appears on website 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/rotlemons.jpg 5 | 6 | output_name = "lemons" 7 | 8 | c_colors = [color(0),color(255)] 9 | l_color = color(213,244,20) 10 | s_color = color(104,118,254) 11 | bg_color = color(255) 12 | orig_width = 980 13 | orig_height = 733 14 | nbr_seeds = 12 15 | 16 | def setup(): 17 | size(980,733) 18 | noLoop() 19 | 20 | def draw(): 21 | ellipseMode(RADIUS) 22 | background(bg_color) 23 | hmargin = 13.0*width/float(orig_width) 24 | vmargin = 9.0*width/float(orig_width) 25 | cw = (width-hmargin*2)/4 26 | s_offset = cw*87/238.0 27 | r1 = 0.5*cw*42/238.0 28 | r2 = 0.5*cw*27/238.0 29 | 30 | pushMatrix() 31 | translate(hmargin,vmargin) 32 | for y in xrange(3): 33 | for x in xrange(4): 34 | pushMatrix() 35 | translate(x*cw+cw/2.0,y*cw+cw/2.0) 36 | noStroke() 37 | fill(l_color) 38 | ellipse(0,0,cw/2.0,cw/2.0) 39 | for i in xrange(nbr_seeds): 40 | pushMatrix() 41 | rotate(map(i,0,nbr_seeds,0,TWO_PI)) 42 | translate(s_offset,0) 43 | fill(s_color) 44 | noStroke() 45 | ellipse(0,0,r1,r2) 46 | noFill() 47 | strokeWeight(4*width/float(orig_width)) 48 | strokeCap(SQUARE) 49 | ctr = (x+y)%2 50 | stroke(255*ctr) 51 | arc(0,0,r1,r2,0,PI) 52 | stroke(255*(1-ctr)) 53 | arc(0,0,r1,r2,PI,TWO_PI) 54 | 55 | popMatrix() 56 | popMatrix() 57 | popMatrix() 58 | 59 | saveFrame("../output/" + output_name + ".png") 60 | 61 | 62 | -------------------------------------------------------------------------------- /primroses_field/primroses_field.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Primrose's Field" waving motion illusion appears on page 22 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/sakurasfs.jpg 5 | 6 | output_name = "primroses_field" 7 | 8 | checkers = 17 9 | color1 = color(79,187,129) 10 | color2 = color(159,215,55) 11 | color3 = color(255,255,255) 12 | color4 = color(205,5,152) 13 | 14 | def setup(): 15 | size(1024,1024, P2D) 16 | noLoop() 17 | 18 | smooth(8) 19 | ellipseMode(RADIUS) 20 | 21 | def clover(px,py,dwidth): 22 | for d in xrange(4): 23 | pushMatrix() 24 | translate(px,py) 25 | rotate(d*TWO_PI/4) 26 | beginShape() 27 | vertex(0,0) 28 | vertex(dwidth/2.0,-dwidth*1/3.0) 29 | vertex(dwidth,0) 30 | vertex(dwidth/2.0,dwidth*1/3.0) 31 | endShape(CLOSE) 32 | popMatrix() 33 | 34 | def draw(): 35 | csize = width/checkers 36 | 37 | background(255) 38 | scramble = [False,True,True,False,True,False,False,True] 39 | for y in range(checkers): 40 | for x in range(checkers): 41 | fill(color1 if (y^x)%2 > 0 else color2) 42 | noStroke() 43 | rect(csize*x,csize*y,csize,csize) 44 | for y in range(checkers-1): 45 | for x in range(checkers-1): 46 | ct = (y*7 + x) % 8 47 | fill(color4 if scramble[ct] else color3) 48 | noStroke() 49 | px = csize*(x+1) 50 | py = csize*(y+1) 51 | dwidth = csize*1/4.0 52 | clover(px,py,dwidth) 53 | # alternates... 54 | # ellipse(px+4,py,3,3) 55 | # ellipse(px-4,py,3,3) 56 | # ellipse(px,py+4,3,3) 57 | # ellipse(px,py-4,3,3) 58 | # ellipse(px,py,6,6) 59 | # quad(px-6,py,px,py+6,px+6,py,px,py-6) 60 | 61 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /rollers/rollers.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of optical illusions by Akiyoshi Kitaoka 2 | 3 | # "Rollers" rotation illusion appears on website 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/rollers.jpg 5 | 6 | # this one isn't quite accurate, might be better to model as 3D cylinders... 7 | 8 | output_name = "rollers" 9 | orig_width,orig_height = (903.0,638.0) 10 | bg_color = color(208,210,18) 11 | r_color = color(28,98,254) 12 | bars = 3 13 | nbr_rollers_h,nbr_rollers_v = (8,8) 14 | 15 | def setup(): 16 | size(903,638) 17 | noLoop() 18 | 19 | def draw(): 20 | ellipseMode(RADIUS) 21 | background(bg_color) 22 | 23 | bar_width = width*267/orig_width 24 | bar_height = height*550/orig_height 25 | margin_h = (width-bar_width*3)/2.0 26 | margin_v = (height-bar_height)/2.0 27 | r_ratio_h,r_ratio_v = (0.9,0.75) 28 | rx_adjust_scale = 0.985 29 | r_width = rx_adjust_scale*(r_ratio_h*bar_width/nbr_rollers_h) 30 | r_height = r_ratio_v*bar_height/nbr_rollers_v 31 | noStroke() 32 | for b in xrange(bars): 33 | pushMatrix() 34 | translate(margin_h+bar_width*b,margin_v) 35 | for y in xrange(nbr_rollers_v): 36 | py = y*r_height/r_ratio_v+r_height/2.0 37 | px = 0 38 | for x in xrange(nbr_rollers_h): 39 | sc = sin(map(x,-1,nbr_rollers_h,0,PI)) 40 | rw = sc*r_width 41 | px += rw/r_ratio_h + rw/2.0 42 | noStroke() 43 | fill(r_color) 44 | ellipse(px,py,sc*0.9*r_width/2.0,0.9*r_height/2.0) 45 | noFill() 46 | strokeCap(SQUARE) 47 | strokeWeight(width*3.5/orig_width) 48 | stroke(255*((b%2)==0)) 49 | arc(px,py,sc*r_width/2.0,r_height/2.0,-PI/2,PI/2) 50 | stroke(255*((b%2)==1)) 51 | arc(px,py,sc*r_width/2.0,r_height/2.0,PI/2,3*PI/2) 52 | popMatrix() 53 | 54 | 55 | saveFrame("../output/" + output_name + ".png") 56 | -------------------------------------------------------------------------------- /kids_of_seals/kids_of_seals.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Kids of Seals" spiral color illusion appears on page 28 4 | # no online reference image found 5 | 6 | 7 | output_name = "kids_of_seals" 8 | s_colors = [color(0,0,192),color(255,255,0),color(192,0,0),color(255)] 9 | d_colors = [color(255),color(0),color(255),color(0)] 10 | bg_color = color(255) 11 | 12 | nbr_seals = 80 13 | 14 | rad_ratio = 12.5/14.2 15 | 16 | def setup(): 17 | size(1024,1024) 18 | ellipseMode(RADIUS) 19 | # noLoop() 20 | 21 | def draw(): 22 | rad = width*.45 23 | n = 0 24 | 25 | rad_ratio = .9 # map(mouseX,0,width,.8,.99) 26 | # rad_ratio = map(mouseX,0,width,.8,.99) 27 | # print rad_ratio 28 | 29 | escale = 0.25 # map(mouseX,0,width,1/12.0,1/2.0) 30 | dscale = 1/12.0 31 | # print escale 32 | 33 | background(bg_color) 34 | 35 | pushMatrix() 36 | translate(width/2,height/2) 37 | noStroke() 38 | 39 | s_ang = TWO_PI/nbr_seals 40 | 41 | while rad > 1: 42 | rad2 = rad*rad_ratio 43 | 44 | for i in xrange(nbr_seals): 45 | pushMatrix() 46 | rotate(-i*s_ang) 47 | fill(s_colors[(i+n)%4]) 48 | quad(cos(0)*rad2, sin(0)*rad2, 49 | cos(-s_ang)*rad2,sin(-s_ang)*rad2, 50 | cos(-s_ang)*rad,sin(-s_ang)*rad, 51 | cos(0)*rad, sin(0)*rad) 52 | popMatrix() 53 | 54 | for i in xrange(nbr_seals): 55 | pushMatrix() 56 | rotate(-i*s_ang) 57 | fill(s_colors[(i+n)%4]) 58 | ellipse(cos(0)*rad, sin(0)*rad,(rad/rad_ratio-rad2)/4,(TWO_PI*rad/nbr_seals)*escale) 59 | fill(d_colors[(i+n)%4]) 60 | ellipse(cos(0)*rad, sin(0)*rad,(rad-rad2)*dscale,(rad-rad2)*dscale) 61 | popMatrix() 62 | rad = rad2 63 | n += 1 64 | popMatrix() 65 | saveFrame("../output/" + output_name + ".png") 66 | -------------------------------------------------------------------------------- /spiral_1/spiral_1.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Red Spiral" spiral color illusion appears on page 26 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/redspiral.gif 5 | 6 | # "Green Spiral" spiral color illusion appears on page 27 - exact same thing with red->green 7 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/grnspiral.gif 8 | 9 | output_name = "red_spiral" 10 | s_colors = [color(0,0,255),color(255,0,0),color(255,255,0)] 11 | 12 | # output_name = "green_spiral" 13 | # s_colors = [color(0,0,255),color(0,255,0),color(255,255,0)] 14 | 15 | stripes = 30 16 | band_ratio = 17/64.0 17 | r1_ratio = 240/400.0 18 | r2_ratio = 320/400.0 19 | r_inc_ratio = .0005 20 | a_inc_ratio = 1/80.0 21 | 22 | stripes = [[0,2],[1,2],[0,2],[0,1]] 23 | 24 | 25 | ctr_max = 11 26 | 27 | def setup(): 28 | size(1024,1024) 29 | noLoop() 30 | 31 | myscale = 2 # oddly, higher scales look worse... 32 | 33 | to_stripes = 4 34 | fro_stripes = 120 35 | to_scale = 25.2 36 | fro_scale = 100 37 | 38 | def draw(): 39 | imap = createGraphics(width*myscale,height*myscale) 40 | imap.beginDraw() 41 | imap.loadPixels() 42 | n = 0 43 | sc1 = to_scale 44 | sc2 = fro_scale 45 | for y in xrange(imap.height): 46 | yf = map(y,0,imap.height,-1,1) 47 | for x in xrange(imap.width): 48 | xf = map(x,0,imap.width,-1,1) 49 | d = dist(0,0,xf,yf) 50 | a1 = (atan2(xf,yf)+PI)*to_stripes 51 | a2 = (atan2(yf,xf)+PI)*fro_stripes 52 | ctr4 = int((a1+log(d*sc1*TWO_PI+.01)*sc1)/TWO_PI) % 4 53 | ctr2 = int((a2+log(d*sc2*TWO_PI+.01)*sc2)/TWO_PI) % 2 54 | ctr = stripes[ctr4][ctr2] 55 | # imap.pixels[n] = s_colors[int((a1+log(d*sc1*TWO_PI+.01)*sc1)/TWO_PI) % 4] works 56 | imap.pixels[n] = s_colors[ctr] 57 | n += 1 58 | imap.updatePixels() 59 | imap.endDraw() 60 | image(imap,0,0,width,height) 61 | saveFrame("../output/" + output_name + ".png") 62 | 63 | -------------------------------------------------------------------------------- /neural_circuits/neural_circuits.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Neural Circuits" rotation illusion, geometrical illusion appears on page 24 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/neuralc2.gif 5 | # 'plastic version': http://www.psy.ritsumei.ac.jp/~akitaoka/rotneuralcplastic.jpg 6 | 7 | stripes = 36*2 8 | 9 | output_name = "neural_circuits" 10 | s_colors = [color(218,221,19), color(142,153,9), ] 11 | d_colors = [color(255), color(152,7,5), color(255), color(59,42,254)] 12 | background_color = color(255) 13 | 14 | def setup(): 15 | size(1024,1024) 16 | noLoop() 17 | 18 | def quadstar(dsize,x,y,a): 19 | pushMatrix() 20 | translate(x,y) 21 | rotate(a) 22 | beginShape() 23 | vertex(0,-dsize) 24 | quadraticVertex(0,0,dsize,0) 25 | quadraticVertex(0,0,0,dsize) 26 | quadraticVertex(0,0,-dsize,0) 27 | quadraticVertex(0,0,0,-dsize) 28 | endShape() 29 | popMatrix() 30 | 31 | 32 | def draw(): 33 | rad = width*.48 34 | rad1 = rad*.642 35 | rad2 = rad*.800 36 | ellipseMode(RADIUS) 37 | background(background_color) 38 | noStroke() 39 | pushMatrix() 40 | translate(width/2,height/2) 41 | for i in xrange(stripes): 42 | blendMode(DARKEST) # helps reduce artifacts in center 43 | a1 = i*TWO_PI/stripes 44 | a2 = (i+1)*TWO_PI/stripes 45 | fill(s_colors[i % 2]) 46 | arc(0,0,rad,rad,a1,a2) 47 | # fill(color(255) if i%2 > 0 else color(0)) 48 | blendMode(BLEND) 49 | fill(s_colors[(i+1) % 2]) 50 | arc(0,0,rad1,rad1,a1,a2) 51 | fill(s_colors[i % 2]) 52 | arc(0,0,rad2,rad2,a1,a2) 53 | drat = 0.5/float(stripes) 54 | for i in xrange(stripes): 55 | a1 = i*TWO_PI/stripes 56 | fill(d_colors[i % 4]) 57 | quadstar(TWO_PI*rad1*drat,cos(a1)*rad1,sin(a1)*rad1,a1) 58 | fill(d_colors[(i*3) % 4]) 59 | quadstar(TWO_PI*rad2*drat,cos(a1)*rad2,sin(a1)*rad2,a1) 60 | popMatrix() 61 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /primroses_hill/primroses_hill.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Primrose's Hill" motion illusion, geometrical illusion appears on page 21 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/babaroa.gif 5 | 6 | # tweaked a bit from 'primroses_field' and 'bavarian_cream' 7 | 8 | output_name = "primroses_hill" 9 | 10 | checkers_h = 13 11 | checkers_v = 13 12 | cmargin = 9 13 | 14 | ccolors = [color(159,215,55), 15 | color(79,187,129)] 16 | scolors = [color(205,5,152), 17 | color(255)] 18 | 19 | pattern = (0,1,1,0,1,0,0,1) 20 | bulge = (0,2,4,5,5,6,6,6,6,5,5,4,2,0) 21 | 22 | def setup(): 23 | size(1024,1024) 24 | noLoop() 25 | 26 | debug = False 27 | 28 | def clover(px,py,dwidth): 29 | for d in xrange(4): 30 | pushMatrix() 31 | translate(px,py) 32 | rotate(d*TWO_PI/4) 33 | beginShape() 34 | vertex(0,0) 35 | vertex(dwidth/2.0,-dwidth*1/3.0) 36 | vertex(dwidth,0) 37 | vertex(dwidth/2.0,dwidth*1/3.0) 38 | endShape(CLOSE) 39 | popMatrix() 40 | 41 | def draw(): 42 | csize_h = width/float(checkers_h) 43 | csize_v = height/float(checkers_v) 44 | 45 | noStroke() 46 | for y in xrange(checkers_v): 47 | for x in xrange(checkers_h): 48 | ctr = (x+y) % 2 49 | fill(ccolors[ctr]) 50 | px = x*csize_h 51 | py = y*csize_v 52 | rect(px,py,csize_h,csize_v) 53 | 54 | dsize = csize_h*.25 55 | noStroke() 56 | for y in xrange(1,checkers_v): 57 | for x in xrange(1,checkers_h): 58 | dx = abs(x-6.5) 59 | dy = abs(y-6.5) 60 | if dx <= bulge[y] and dy <= bulge[x]: 61 | polarity = (x < 6.5) != (y < 6.5) 62 | ctr = (x+y+polarity) % 2 63 | fill(scolors[pattern[ctr]]) 64 | px = x*csize_h 65 | py = y*csize_v 66 | dwidth = csize_h/4.50 67 | clover(px,py,dwidth) 68 | 69 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /primroses_circulation/primroses_circulation.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Primrose's Circulation" rotation illusion appears on page 32 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/rotsaku.gif 5 | 6 | stripes = 9*4 7 | 8 | output_name = "primroses_circulation" 9 | s_colors = [color(62,190,130),color(160,221,15)] 10 | c_colors = [color(255), color(204,4,153) ] 11 | background_color = color(255) 12 | rad_ratio = .5*596/616.0 13 | rad1_ratio = 475/596.0 14 | rad2_ratio = 335/596.0 15 | 16 | def setup(): 17 | size(1024,1024) 18 | noLoop() 19 | 20 | def clover(px,py,dwidth): 21 | for d in xrange(4): 22 | pushMatrix() 23 | translate(px,py) 24 | rotate(d*TWO_PI/4) 25 | beginShape() 26 | vertex(0,0) 27 | vertex(dwidth/2.0,-dwidth*1/3.5) 28 | vertex(dwidth,0) 29 | vertex(dwidth/2.0,dwidth*1/3.5) 30 | endShape(CLOSE) 31 | popMatrix() 32 | 33 | 34 | def draw(): 35 | rad = width * rad_ratio 36 | rad1 = rad * rad1_ratio 37 | rad2 = rad * rad2_ratio 38 | 39 | ellipseMode(RADIUS) 40 | background(background_color) 41 | noStroke() 42 | pushMatrix() 43 | translate(width/2,height/2) 44 | for i in xrange(stripes): 45 | blendMode(DARKEST) # helps reduce artifacts in center 46 | a1 = i*TWO_PI/stripes 47 | a2 = (i+1)*TWO_PI/stripes 48 | fill(s_colors[i % 2]) 49 | arc(0,0,rad,rad,a1,a2) 50 | blendMode(BLEND) 51 | fill(s_colors[(i+1) % 2]) 52 | arc(0,0,rad1,rad1,a1,a2) 53 | 54 | fill(s_colors[i % 2]) 55 | arc(0,0,rad2,rad2,a1,a2) 56 | 57 | drat = 0.5/float(stripes) 58 | for i in xrange(stripes): 59 | a1 = i*TWO_PI/stripes 60 | fill(c_colors[i % 2]) 61 | side1 = TWO_PI*rad1/stripes 62 | side2 = TWO_PI*rad2/stripes 63 | clover(cos(a1)*rad1,sin(a1)*rad1, side1/3.5) 64 | fill(c_colors[(i*1) % 2]) 65 | clover(cos(a1)*rad2,sin(a1)*rad2, side2/3.5) 66 | popMatrix() 67 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /turtles/turtles.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Turtles" geometrical illusion appears on page 52 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/kame.jpg 5 | 6 | output_name = "turtles" 7 | 8 | checkers = 11 9 | orig_width = 366 10 | bg_color = color(255) 11 | fg_color = color(0) 12 | 13 | def setup(): 14 | size(1024,1024) 15 | noLoop() 16 | 17 | def draw_turtle(f1,f2,f3,f4): 18 | global cw,crad 19 | beginShape() 20 | 21 | # top-left 22 | vertex(0,crad*2) 23 | vertex(-crad if f1 else crad,crad) 24 | vertex(0,0) 25 | vertex(crad,crad if f1 else -crad) 26 | vertex(crad*2,0) 27 | 28 | # top-right 29 | vertex(cw-crad*2,0) 30 | vertex(cw-crad,-crad if f2 else crad) 31 | vertex(cw,0) 32 | vertex(cw-crad if f2 else cw+crad,crad) 33 | vertex(cw,crad*2) 34 | 35 | # bot-right 36 | vertex(cw, cw-crad*2) 37 | vertex(cw+crad if f3 else cw-crad,cw-crad) 38 | vertex(cw,cw) 39 | vertex(cw-crad,cw-crad if f3 else cw+crad) 40 | vertex(cw-crad*2,cw) 41 | 42 | # bot-left 43 | vertex(crad*2,cw) 44 | vertex(crad,cw+crad if f4 else cw-crad) 45 | vertex(0,cw) 46 | vertex(crad if f4 else -crad,cw-crad) 47 | vertex(0,cw-crad*2) 48 | 49 | endShape(CLOSE) 50 | 51 | def draw(): 52 | global cw,crad 53 | margin = width*7.0/orig_width 54 | background(bg_color) 55 | fill(fg_color) 56 | noStroke() 57 | 58 | pushMatrix() 59 | translate(margin,margin) 60 | 61 | cw = (width-margin*2)/checkers 62 | crad = width*4.0/orig_width 63 | 64 | 65 | for y in xrange(checkers): 66 | for x in xrange(checkers): 67 | if (x+y)%2 > 0: 68 | continue 69 | pushMatrix() 70 | translate(x*cw,y*cw) 71 | draw_turtle((x<6)==(y<6), 72 | (x<5)==(y<6), 73 | (x<5)==(y<5), 74 | (x<6)==(y<5)) 75 | popMatrix() 76 | 77 | popMatrix() 78 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /dragon_scales/dragon_scales.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Scales of a Dragon" depth/shading illusion appears on page 47 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/ryuuroko.gif 5 | 6 | output_name = "dragon_scales" 7 | orig_width = 393 8 | bg_color = color(255) 9 | checkers = 8 10 | 11 | def setup(): 12 | size(1024,1024) 13 | noLoop() 14 | 15 | def draw(): 16 | background(bg_color) 17 | margin = width*4/float(orig_width) 18 | pushMatrix() 19 | translate(margin,margin) 20 | cw = int((width-margin*2)/float(checkers)) 21 | 22 | # scale 1 23 | pimg1 = createGraphics(cw,cw) 24 | pimg1.beginDraw() 25 | pimg1.loadPixels() 26 | H_PI = PI/2.0 27 | for y in xrange(cw): 28 | ry = y/float(cw) 29 | c1 = color(0) 30 | c2 = color(255,255,0) 31 | for x in xrange(cw): 32 | rx = x/float(cw) 33 | a = H_PI+rx*H_PI-ry*H_PI 34 | pimg1.pixels[y*cw+x] = lerpColor(c1,c2,sin(a)) 35 | pimg1.updatePixels() 36 | pimg1.endDraw() 37 | 38 | # scale 2 39 | pimg2 = createGraphics(cw,cw) 40 | pimg2.beginDraw() 41 | pimg2.loadPixels() 42 | for y in xrange(cw): 43 | ry = y/float(cw) 44 | c1 = color(0) 45 | c2 = color(255) 46 | for x in xrange(cw): 47 | rx = x/float(cw) 48 | a = rx*H_PI+ry*H_PI 49 | pimg2.pixels[y*cw+x] = lerpColor(c1,c2,sin(a)) 50 | pimg2.updatePixels() 51 | pimg2.endDraw() 52 | 53 | for y in xrange(checkers): 54 | for x in xrange(checkers): 55 | px = x*cw 56 | py = y*cw 57 | image(pimg1 if (x < checkers/2) == (y < checkers/2) else pimg2, px, py) 58 | 59 | strokeWeight(width*1/float(orig_width)) 60 | strokeCap(SQUARE) 61 | stroke(color(0)) 62 | noFill() 63 | 64 | for i in xrange(checkers+1): 65 | line(0,i*cw,cw*checkers,i*cw) 66 | line(i*cw,0,i*cw,cw*checkers) 67 | 68 | 69 | popMatrix() 70 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /makudonarudo/makudonarudo.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Majudonarudo" (McDonald's) motion illusion / geometrical illusion appears on page 13 4 | # reference image here: http://www.psy.ritsumei.ac.jp/~akitaoka/mcdonaldb.jpg 5 | 6 | output_name = "makudonarudo" 7 | stripes = 31 8 | stripe_colors = [color(255,20,20),color(255,150,150)] 9 | boat_colors = [color(150,150,10),color(255,255,25)] 10 | dot_colors = [color(0),color(150),color(255),color(150)] 11 | 12 | def setup(): 13 | size(969,551) 14 | ellipseMode(RADIUS) 15 | noLoop() 16 | 17 | def draw_cherry(ctr,x,y): 18 | global dot_rad 19 | fill(dot_colors[(ctr%2)*2]) 20 | ellipse(x,y,dot_rad,dot_rad) 21 | fill(dot_colors[(ctr%2)*2+1]) 22 | ellipse(x,y,dot_rad*.3,dot_rad*.3) 23 | 24 | def draw(): 25 | global dot_rad 26 | sheight = height/float(stripes) 27 | bwidth = width*36/969.0 28 | background(0) 29 | noStroke() 30 | for i in xrange(stripes): 31 | fill(stripe_colors[i % 2]) 32 | py = sheight*i 33 | rect(0,py,width,sheight) 34 | 35 | dot_rad = sheight*.25 36 | top_x = width*31/969.0 37 | bot_x = width*155/969.0 38 | 39 | seams = (width*258/969.0,width*712/969.0) 40 | for seam in seams: 41 | for y in xrange(1,stripes-1): 42 | x1 = map(y,1,stripes-2,top_x,bot_x) 43 | x2 = map(y+1,1,stripes-2,top_x,bot_x) 44 | y1 = y*sheight 45 | y2 = (y+1)*sheight 46 | for sgn in (-1,1): 47 | fill(boat_colors[(y-1)%2]) 48 | px1 = seam+(x1)*sgn 49 | px2 = seam+(x1+bwidth)*sgn 50 | px3 = seam+(x2+bwidth)*sgn 51 | px4 = seam+(x2)*sgn 52 | py1 = y1 53 | py2 = y2 54 | quad(px1,y1, px2,y1, px3,y2, px4,y2) 55 | if y > 1: 56 | draw_cherry(y,px1,py1) 57 | draw_cherry(y+1,px2,py1) 58 | 59 | 60 | saveFrame("../output/" + output_name + ".png") 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /autumn_color_swamp/autumn_color_swamp.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Autumn Color Swamp" motion illusion appears on page 10 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/ACswamp.jpg 5 | 6 | output_name = "autumn_color_swamp" 7 | 8 | checkers = 37 9 | cmargin = 9 10 | 11 | ccolors = [color(255,20,20), 12 | color(255,128,20), 13 | color(255,205,20), 14 | color(255,128,20)] 15 | white = color(255) 16 | black = color(0) 17 | 18 | def setup(): 19 | size(1024,1024) 20 | noLoop() 21 | 22 | debug = False 23 | 24 | def quadstar(dsize): 25 | beginShape() 26 | vertex(0,-dsize) 27 | quadraticVertex(0,0,dsize,0) 28 | quadraticVertex(0,0,0,dsize) 29 | quadraticVertex(0,0,-dsize,0) 30 | quadraticVertex(0,0,0,-dsize) 31 | endShape() 32 | 33 | def draw(): 34 | csize = width/float(checkers) 35 | 36 | noStroke() 37 | for y in xrange(checkers): 38 | for x in xrange(checkers): 39 | inverted = y >= cmargin and y < checkers-cmargin and x >= cmargin and x < checkers-cmargin 40 | ctr = (x + y*3) % 4 if not inverted else (x + y) % 4 41 | fill(ccolors[ctr]) 42 | px = x*csize 43 | py = y*csize 44 | rect(px,py,csize,csize) 45 | if debug: 46 | stroke(255) 47 | noFill() 48 | rect(cmargin*csize,cmargin*csize,19*csize,19*csize) 49 | # draw dividers 50 | noStroke() 51 | dsize = csize*.45 52 | for y in xrange(1,checkers-1): 53 | for x in xrange(1,checkers-1): 54 | inverted = y >= cmargin and y <= checkers-cmargin and x >= cmargin and x <= checkers-cmargin 55 | ctr = (x + y*3) % 4 if not inverted else (3+(x + y)) % 4 56 | if ctr == 0 or ctr == 2: 57 | fill(white if ctr < 2 else black) 58 | px = x*csize 59 | py = y*csize 60 | pushMatrix() 61 | translate(px,py) 62 | quadstar(dsize) 63 | popMatrix() 64 | 65 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /primroses_spirals/primroses_spirals.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Primrose's Spirals" spiral illusion, rotating illusion appears on page 31 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/uzusaku.gif 5 | 6 | stripes = 9*4 7 | 8 | output_name = "primroses_spirals" 9 | s_colors = [color(62,190,130),color(160,221,15)] 10 | c_colors = [color(255), color(204,4,153) ] 11 | 12 | bg_color = color(255) 13 | radius_ratio = 0.466 14 | quadstar_ratio = 0.4 15 | quadstar_dot_ratio = 0.15 16 | quadstar_ang_ratio = 0.9 17 | 18 | ring_side_ratio = 0.86 19 | 20 | def setup(): 21 | size(1024,1024) 22 | noLoop() 23 | 24 | def clover(px,py,dwidth): 25 | for d in xrange(4): 26 | pushMatrix() 27 | translate(px,py) 28 | rotate(d*TWO_PI/4) 29 | beginShape() 30 | vertex(0,0) 31 | vertex(dwidth/2.0,-dwidth*1/3.5) 32 | vertex(dwidth,0) 33 | vertex(dwidth/2.0,dwidth*1/3.5) 34 | endShape(CLOSE) 35 | popMatrix() 36 | 37 | def draw(): 38 | background(bg_color) 39 | noStroke() 40 | 41 | pushMatrix() 42 | translate(width/2,height/2) 43 | 44 | rad = width*radius_ratio 45 | 46 | n = 0 47 | s_ang = TWO_PI/stripes 48 | while rad > 1: 49 | circ = TWO_PI*rad 50 | side = circ/float(stripes) 51 | rad2 = rad-side * ring_side_ratio 52 | 53 | for i in xrange(stripes): 54 | pushMatrix() 55 | rotate(-i*s_ang) 56 | fill(s_colors[(i+n)%2]) 57 | stroke(s_colors[(i+n)%2]) 58 | quad(cos(0)*rad2, sin(0)*rad2, 59 | cos(-s_ang)*rad2,sin(-s_ang)*rad2, 60 | cos(-s_ang)*rad,sin(-s_ang)*rad, 61 | cos(0)*rad, sin(0)*rad) 62 | popMatrix() 63 | noStroke() 64 | for i in xrange(stripes): 65 | pushMatrix() 66 | rotate(-i*s_ang) 67 | fill(c_colors[(i+n)%2]) 68 | px,py = (cos(0)*rad,sin(0)*rad) 69 | clover(px,py,side/3.5) 70 | popMatrix() 71 | 72 | rad = rad2 73 | n += 1 74 | 75 | popMatrix() 76 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /bulge/bulge.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of optical illusions by Akiyoshi Kitaoka 2 | 3 | # "Bulge02c" geometrical illusion appears on website 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/Bulge02c.jpg 5 | 6 | output_name = "bulge02c" 7 | 8 | c_colors = [color(0),color(255)] 9 | bg_color = color(255) 10 | checkers = 15 11 | orig_width = 574 12 | 13 | flags = [ 14 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15 | 0, 0, 0, 0, 0, 0, 9, 10, 6, 0, 0, 0, 0, 0, 0, 16 | 0, 0, 0, 0, 9, 9, 9, 10, 6, 6, 6, 0, 0, 0, 0, 17 | 0, 0, 0, 9, 9, 9, 9, 10, 6, 6, 6, 6, 0, 0, 0, 18 | 0, 0, 9, 9, 9, 9, 9, 10, 6, 6, 6, 6, 6, 0, 0, 19 | 0, 0, 9, 9, 9, 9, 9, 10, 6, 6, 6, 6, 6, 0, 0, 20 | 0, 9, 9, 9, 9, 9, 9, 10, 6, 6, 6, 6, 6, 6, 0, 21 | 0, 3, 3, 3, 3, 3, 3, 0, 12,12,12,12,12,12, 0, 22 | 0, 6, 6, 6, 6, 6, 6, 5, 9, 9, 9, 9, 9, 9, 0, 23 | 0, 0, 6, 6, 6, 6, 6, 5, 9, 9, 9, 9, 9, 0, 0, 24 | 0, 0, 6, 6, 6, 6, 6, 5, 9, 9, 9, 9, 9, 0, 0, 25 | 0, 0, 0, 6, 6, 6, 6, 5, 9, 9, 9, 9, 0, 0, 0, 26 | 0, 0, 0, 0, 6, 6, 6, 5, 9, 9, 9, 0, 0, 0, 0, 27 | 0, 0, 0, 0, 0, 0, 6, 5, 9, 0, 0, 0, 0, 0, 0, 28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 29 | 30 | xd = [1,1,-1,-1] 31 | yd = [-1,1,-1,1] 32 | 33 | def setup(): 34 | size(800,800) # intentionally a multiple of gw+margin_checkers*2 for sharp pixel boundaries 35 | noLoop() 36 | 37 | def draw(): 38 | ellipseMode(RADIUS) 39 | margin = width*16.0/orig_width 40 | 41 | cw = (width-margin*2)/checkers 42 | 43 | background(bg_color) 44 | pushMatrix() 45 | translate(margin,margin) 46 | 47 | cwo = cw*10/35.0 48 | cww = cw*10/35.0 49 | 50 | # draw checkers 51 | for y in xrange(checkers): 52 | for x in xrange(checkers): 53 | c_idx = (x+y) % 2 54 | fill(c_colors[c_idx]) 55 | noStroke() 56 | pushMatrix() 57 | translate(x*cw+cw/2,y*cw+cw/2) 58 | rect(-cw/2,-cw/2,cw,cw) 59 | fill(c_colors[1-c_idx]) 60 | for q in xrange(4): 61 | if (flags[y*checkers+x] & (1 << q)) > 0: 62 | rect(xd[q]*cwo-cww/2,yd[q]*cwo-cww/2,cww,cww) 63 | popMatrix() 64 | popMatrix() 65 | 66 | saveFrame("../output/" + output_name + ".png") 67 | 68 | -------------------------------------------------------------------------------- /snake_1/snake_1.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "A Snake" spiral illusion appears on page 9 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/hebis.jpg 5 | 6 | output_name = "snake_1" 7 | irad_1_ratio = 37/312.0 8 | orad_1_ratio = 47.5/312.0 9 | detail = 4 10 | stripes = 18*2*detail 11 | red_color = color(151,4,102) 12 | white_color = color(255) 13 | bg_color = color(200) 14 | 15 | def setup(): 16 | size(1024,1024) 17 | noLoop() 18 | 19 | def draw(): 20 | background(bg_color) 21 | nbr_rings = 0 22 | irad = width*irad_1_ratio*0.5 23 | orad = width*orad_1_ratio*0.5 24 | pushMatrix() 25 | translate(width/2,height/2) 26 | noStroke() 27 | while nbr_rings < 5: 28 | nbr_rings += 1 29 | # draw stuff 30 | strokeWeight(1) 31 | for s in xrange(stripes): 32 | fill(red_color if s/detail % 2 > 0 else white_color) 33 | stroke(red_color if s/detail % 2 > 0 else white_color) 34 | # noStroke() 35 | ang1 = s*TWO_PI/stripes 36 | ang2 = (s+1)*TWO_PI/stripes 37 | beginShape() 38 | vertex(cos(ang1)*irad,sin(ang1)*irad) 39 | vertex(cos(ang1)*orad,sin(ang1)*orad) 40 | vertex(cos(ang2)*orad,sin(ang2)*orad) 41 | vertex(cos(ang2)*irad,sin(ang2)*irad) 42 | endShape(CLOSE) 43 | noFill() 44 | sweight = width*2.5/624.0 45 | strokeWeight(sweight) 46 | strokeCap(PROJECT) 47 | for s in xrange(stripes): 48 | stroke(red_color if s/detail % 2 > 0 else white_color) 49 | aoffset = detail*PI/stripes 50 | ang1 = s*TWO_PI/stripes 51 | ang2 = (s+1)*TWO_PI/stripes 52 | irad2 = irad+sweight*.4 53 | orad2 = orad-sweight*.4 54 | line(cos(ang1+aoffset)*irad2,sin(ang1+aoffset)*irad2,cos(ang2+aoffset)*irad2,sin(ang2+aoffset)*irad2) 55 | line(cos(ang1-aoffset)*orad2,sin(ang1-aoffset)*orad2,cos(ang2-aoffset)*orad2,sin(ang2-aoffset)*orad2) 56 | 57 | irad = orad+(orad-irad) 58 | orad = irad*orad_1_ratio/irad_1_ratio 59 | popMatrix() 60 | saveFrame("../output/" + output_name + ".png") 61 | 62 | -------------------------------------------------------------------------------- /nuts/nuts.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Nuts" motion illusion / geometrical illusion appears on page 11 4 | # reference image found under the name "cherries": http://www.ritsumei.ac.jp/~akitaoka/sakuranb.gif 5 | 6 | output_name = "nuts" 7 | 8 | checkers = 25 9 | cmargin = 5 10 | 11 | check_colors = [color(202,204,17), 12 | color(203,154,15)] 13 | dot_colors = [color(253,255,24), 14 | color(204,255,204), 15 | color(179,9,9), 16 | color(253,205,21)] 17 | 18 | white = color(255) 19 | black = color(0) 20 | 21 | def setup(): 22 | size(1024,1024) 23 | ellipseMode(RADIUS) 24 | noLoop() 25 | 26 | debug = False 27 | 28 | def idiamond(dsize): 29 | beginShape() 30 | vertex(0,-dsize) 31 | quadraticVertex(0,0,dsize,0) 32 | quadraticVertex(0,0,0,dsize) 33 | quadraticVertex(0,0,-dsize,0) 34 | quadraticVertex(0,0,0,-dsize) 35 | endShape() 36 | 37 | def draw(): 38 | csize = width/float(checkers) 39 | 40 | noStroke() 41 | for y in xrange(checkers): 42 | for x in xrange(checkers): 43 | ctr = (x + y) % 2 44 | fill(check_colors[ctr]) 45 | px = x*csize 46 | py = y*csize 47 | rect(px,py,csize,csize) 48 | if debug: 49 | stroke(255) 50 | noFill() 51 | rect(cmargin*csize,cmargin*csize,19*csize,19*csize) 52 | # draw dividers 53 | noStroke() 54 | dsize = csize*.13 55 | hsize = dsize*.3 56 | for y in xrange(1,checkers): 57 | for x in xrange(1,checkers): 58 | inverted = y > cmargin and y < checkers-cmargin and x > cmargin and x < checkers-cmargin 59 | centered = y > cmargin+1 and y < checkers-(cmargin+1) and x > cmargin+1 and x < checkers-(cmargin+1) 60 | if not inverted or centered: 61 | ctr = (x + y + (1 if centered else 0)) % 2 62 | fill(dot_colors[ctr*2]) 63 | px = x*csize 64 | py = y*csize 65 | pushMatrix() 66 | translate(px,py) 67 | ellipse(0,0,dsize,dsize) 68 | fill(dot_colors[ctr*2+1]) 69 | ellipse(0,0,hsize,hsize) 70 | popMatrix() 71 | 72 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /packed_cherries/packed_cherries.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Packed Cherries" motion illusion appears on cover page 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/sakuran2.gif 5 | 6 | output_name = "packed_cherries" 7 | 8 | dark_maroon = color(199,12,11) 9 | light_maroon = color(254,19,18) 10 | white = color(255,255,255) 11 | gw,gh = (15,15) 12 | gw2,gh2 = (6,6) 13 | drad_ratio = .4375 14 | strokeweight_ratio = .125 15 | imargin_ratio = .015 16 | 17 | def setup(): 18 | size(1024,1024) 19 | noLoop() 20 | 21 | 22 | def draw(): 23 | margin = 0 24 | background(white) 25 | fill(dark_maroon) 26 | noStroke() 27 | pushMatrix() 28 | translate(margin,margin) 29 | rwidth, rheight = (width-margin*2,height-margin*2) 30 | rect(0,0,rwidth, rheight) 31 | imargin = rwidth*imargin_ratio 32 | pushMatrix() 33 | translate(imargin,imargin) 34 | fill(0) 35 | irwidth, irheight = (rwidth-imargin*2,rheight-imargin*2) 36 | # rect(0,0,irwidth, irheight) 37 | ellipseMode(RADIUS) 38 | tw,th = (irwidth/float(gw),irheight/float(gh)) 39 | drad = tw*drad_ratio 40 | strokeWeight(tw*strokeweight_ratio) 41 | strokeCap(PROJECT) 42 | stroke(white) 43 | noFill() 44 | 45 | # outer lines 46 | for y in xrange(gh): 47 | for x in xrange(gw): 48 | if x > 3 and x < 11 and y > 3 and y < 11: 49 | continue 50 | line(x*tw,y*th,(x+1)*tw,(y+1)*th) 51 | 52 | 53 | # back lines 54 | for y in xrange(4,4+6): 55 | for x in xrange(4,4+6): 56 | line(irwidth-(x+.5)*tw,(y+.5)*th,irwidth-(x+1.5)*tw,(y+1.5)*th) 57 | 58 | noStroke() 59 | for y in xrange(gh): 60 | for x in xrange(gw): 61 | if x > 3 and x < 11 and y > 3 and y < 11: 62 | continue 63 | fill(light_maroon) 64 | px = x*tw+tw/2 65 | py = y*th+th/2 66 | ellipse(px,py,drad,drad) 67 | 68 | for y in xrange(gh2): 69 | for x in xrange(gw2): 70 | fill(light_maroon) 71 | px = 4.5*tw + x*tw+tw/2 72 | py = 4.5*th + y*th+th/2 73 | ellipse(px,py,drad,drad) 74 | 75 | popMatrix() 76 | pushMatrix() 77 | saveFrame("../output/" + output_name + ".png") 78 | 79 | -------------------------------------------------------------------------------- /rotating_rays/rotating_rays.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of optical illusions by Akiyoshi Kitaoka 2 | 3 | # "rotating_rays" rotation illusion appears on website 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/rotrays.gif 5 | 6 | output_name = "rotating_rays" 7 | 8 | g_colors = [color(30,200,255),color(19,239,216)] 9 | r_color = color(200,12,12) 10 | bg_color = color(255) 11 | orig_width = 689.0 12 | orig_crad = 280 13 | nbr_seeds = 12 14 | rings = 3 15 | bands = 2 16 | nbr_rays = 6*4 17 | 18 | def setup(): 19 | size(1024,1024) 20 | noLoop() 21 | 22 | def draw(): 23 | ellipseMode(RADIUS) 24 | background(bg_color) 25 | rad = 0.5*width*652/orig_width 26 | subrad_ratios = [280/orig_width,127/orig_width] 27 | s_ang = TWO_PI/nbr_rays 28 | 29 | pushMatrix() 30 | translate(width/2,height/2) 31 | 32 | # radial gradient background 33 | noFill() 34 | strokeWeight(2) 35 | for i in xrange(1,int(rad)+1): 36 | stroke(lerpColor(g_colors[0],g_colors[1],map(i,1,rad,0,1))) 37 | ellipse(0,0,i,i) 38 | 39 | for b in xrange(bands): 40 | crad = width*subrad_ratios[b] 41 | for r in xrange(rings): 42 | radw = TWO_PI*crad/nbr_rays 43 | for i in xrange(nbr_rays): 44 | pushMatrix() 45 | rotate(s_ang*(i + 0.5*(r%2))) 46 | translate(crad,0) 47 | dr = radw*.9*0.5 48 | fill(r_color) 49 | noStroke() 50 | quad(-dr,0,0,-dr,dr,0,0,dr) 51 | strokeWeight(width*3.5/orig_width) # note: strokeWeight does not diminish with ray size.. 52 | stroke(255*b) 53 | # upper 54 | line(-dr,0,0,-dr) 55 | line(0,-dr,dr,0) 56 | stroke(255*(1-b)) 57 | line(dr,0,0,dr) 58 | line(0,dr,-dr,0) 59 | fill(0) 60 | noStroke() 61 | eye_ofsty = dr*0.4*(-1 if b else 1) 62 | eye_dist = crad*5/orig_crad 63 | eye_vr = crad*5/orig_crad 64 | eye_hr = eye_vr/2.0 65 | ellipse(-eye_dist,eye_ofsty,eye_hr,eye_vr) 66 | ellipse(+eye_dist,eye_ofsty,eye_hr,eye_vr) 67 | # lower 68 | popMatrix() 69 | crad = crad-radw*0.75 70 | 71 | popMatrix() 72 | 73 | saveFrame("../output/" + output_name + ".png") 74 | 75 | 76 | -------------------------------------------------------------------------------- /neural_network/neural_network.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Neural Network" spral illusion, spiral illusion, appears on page 29 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/neuralcircuitspirals.jpg 5 | 6 | stripes = 40 7 | 8 | output_name = "neural_network" 9 | s_colors = [color(163,165,12), color(208,210,18)] 10 | d_colors = [color(152,5,5), color(255), color(59,44,254), color(255)] 11 | dit_color = color(178) 12 | 13 | bg_color = color(255) 14 | radius_ratio = 0.471 15 | quadstar_ratio = 0.4 16 | quadstar_dot_ratio = 0.15 17 | quadstar_ang_ratio = 0.9 18 | 19 | ring_side_ratio = 0.95 20 | 21 | def setup(): 22 | size(1024,1024) 23 | noLoop() 24 | 25 | def quadstarr(dsize,rad): 26 | ang = (PI/stripes)*quadstar_ang_ratio 27 | x,y = (cos(0)*rad,sin(0)*rad) 28 | pushMatrix() 29 | beginShape() 30 | vertex(cos(-ang)*rad,sin(-ang)*rad) 31 | quadraticVertex(x,y,x+dsize,y) 32 | quadraticVertex(x,y,cos(ang)*rad,sin(ang)*rad) # sin(ang)*rad 33 | quadraticVertex(x,y,x-dsize,y) 34 | quadraticVertex(x,y,cos(-ang)*rad,sin(-ang)*rad) 35 | endShape() 36 | popMatrix() 37 | 38 | 39 | def draw(): 40 | background(bg_color) 41 | noStroke() 42 | 43 | pushMatrix() 44 | translate(width/2,height/2) 45 | 46 | rad = width*radius_ratio 47 | 48 | n = 0 49 | s_ang = TWO_PI/stripes 50 | while rad > 1: 51 | circ = TWO_PI*rad 52 | side = circ/float(stripes) 53 | rad2 = rad-side * ring_side_ratio 54 | 55 | for i in xrange(stripes): 56 | pushMatrix() 57 | rotate(-i*s_ang) 58 | fill(s_colors[(i+n)%2]) 59 | stroke(s_colors[(i+n)%2]) 60 | quad(cos(0)*rad2, sin(0)*rad2, 61 | cos(-s_ang)*rad2,sin(-s_ang)*rad2, 62 | cos(-s_ang)*rad,sin(-s_ang)*rad, 63 | cos(0)*rad, sin(0)*rad) 64 | popMatrix() 65 | noStroke() 66 | for i in xrange(stripes): 67 | pushMatrix() 68 | rotate(-i*s_ang) 69 | fill(d_colors[(i+n*3)%4]) 70 | px,py = (cos(0)*rad,sin(0)*rad) 71 | quadstarr(side*quadstar_ratio,rad) 72 | fill(dit_color) 73 | ellipse(px,py,side * quadstar_dot_ratio,side * quadstar_dot_ratio) 74 | popMatrix() 75 | 76 | rad = rad2 77 | n += 1 78 | 79 | popMatrix() 80 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /rays/rays.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Rays" motion illusion appears on page 16 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/ei.gif 5 | 6 | output_name = "rays" 7 | 8 | nbr_bg_checks = 7 9 | 10 | bg_colors = [color(11,204,180),color(19,205,220),color(24,174,230),color(24,146,230),color(19,87,200)] 11 | ray_color = color(140,75,75) 12 | black_color = color(0) 13 | 14 | orig_meas_width = 508.0 15 | orig_meas_margin = 14.0 16 | 17 | def setup(): 18 | size(1024,1024) 19 | noLoop() 20 | 21 | def draw(): 22 | # gradient 23 | diag = dist(0,0,width,height) 24 | cx = 0 25 | cy = 0 26 | for d in xrange(diag): 27 | r = d/float(diag) 28 | r4 = int(r*4) 29 | r = (r-r4*.25)/0.25 30 | strokeWeight(2) 31 | stroke(lerpColor(bg_colors[r4],bg_colors[r4+1],r)) 32 | line(d-width,d+width,d+width,d-width) 33 | margin = width*orig_meas_margin/orig_meas_width 34 | checkers = 16 35 | tw = (width-margin*2)/checkers 36 | lg_d = tw*0.35 37 | sm_d = tw*0.25 38 | e_dist = width*2/orig_meas_width 39 | e_bot = sm_d*.8 40 | e_top = sm_d*.98 41 | pushMatrix() 42 | translate(margin,margin) 43 | stroke(black_color) 44 | strokeWeight(width/orig_meas_width) 45 | fill(ray_color) 46 | for y in xrange(checkers): 47 | for x in xrange(checkers): 48 | cx = x*tw+tw/2 49 | cy = y*tw+tw/2 50 | if x <= 3 or x >= 12 or y <= 3 or y >= 12: 51 | quad(cx-lg_d,cy-lg_d, 52 | cx+sm_d,cy-sm_d, 53 | cx+lg_d,cy+lg_d, 54 | cx-sm_d,cy+sm_d) 55 | pushMatrix() 56 | translate(cx,cy) 57 | rotate(-PI/4) 58 | line(e_bot,-e_dist,e_top,-e_dist) 59 | line(e_bot,+e_dist,e_top,+e_dist) 60 | popMatrix() 61 | elif x > 4 and x < 11 and y > 4 and y < 11: 62 | quad(cx-sm_d,cy-sm_d, 63 | cx+lg_d,cy-lg_d, 64 | cx+sm_d,cy+sm_d, 65 | cx-lg_d,cy+lg_d) 66 | pushMatrix() 67 | translate(cx,cy) 68 | rotate(-(3*PI/4)) 69 | line(e_bot,-e_dist,e_top,-e_dist) 70 | line(e_bot,+e_dist,e_top,+e_dist) 71 | popMatrix() 72 | 73 | popMatrix() 74 | saveFrame("../output/" + output_name + ".png") 75 | -------------------------------------------------------------------------------- /persimmons/persimmons.pyde: -------------------------------------------------------------------------------- 1 | # persimmons 2 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 3 | 4 | # "Persimmons" motion/geometrical illusion appears on page 48 5 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/kaki.gif 6 | 7 | output_name = "persimmons" 8 | orig_width = 305 9 | 10 | bg_color = color(255) 11 | checkers = 9 12 | 13 | def setup(): 14 | size(1024,1024) 15 | noLoop() 16 | 17 | def quadstar(dsize): 18 | beginShape() 19 | vertex(0,-dsize) 20 | quadraticVertex(0,0,dsize,0) 21 | quadraticVertex(0,0,0,dsize) 22 | quadraticVertex(0,0,-dsize,0) 23 | quadraticVertex(0,0,0,-dsize) 24 | endShape() 25 | 26 | 27 | def draw(): 28 | background(bg_color) 29 | margin = width*9/float(orig_width) 30 | pushMatrix() 31 | translate(margin,margin) 32 | cw = int((width-margin*2)/float(checkers)) 33 | 34 | # scale 1 35 | pimg1 = createGraphics(cw,cw) 36 | pimg1.beginDraw() 37 | pimg1.loadPixels() 38 | H_PI = PI/2.0 39 | for y in xrange(cw): 40 | for x in xrange(cw): 41 | pimg1.pixels[y*cw+x] = color(53,153,52) 42 | pimg1.updatePixels() 43 | pimg1.endDraw() 44 | 45 | # scale 2 46 | pimg2 = createGraphics(cw,cw) 47 | pimg2.beginDraw() 48 | pimg2.loadPixels() 49 | for y in xrange(cw): 50 | ry = y/float(cw) 51 | c1 = color(200,127,16) 52 | c2 = color(255,160,32) 53 | for x in xrange(cw): 54 | rx = x/float(cw) 55 | pimg2.pixels[y*cw+x] = lerpColor(c1,c2,2*max(abs(0.5-ry),abs(0.5-rx))) 56 | pimg2.updatePixels() 57 | pimg2.endDraw() 58 | 59 | for y in xrange(checkers): 60 | for x in xrange(checkers): 61 | px = x*cw 62 | py = y*cw 63 | image(pimg1 if (x+y) % 2 == 0 else pimg2, px, py) 64 | 65 | noStroke() 66 | for y in xrange(0,checkers+1): 67 | for x in xrange(0,checkers+1): 68 | px = x*cw 69 | py = y*cw 70 | pushMatrix() 71 | if x == 0 or y == 0 or x == checkers or y == checkers: 72 | fill(255) 73 | else: 74 | cx = x + (x > 4) + (y > 4) 75 | fill(255 if (cx+y) % 2 == 0 else 0) 76 | translate(px,py) 77 | quadstar(cw/3.0) 78 | popMatrix() 79 | 80 | 81 | 82 | 83 | popMatrix() 84 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /tiger/tiger.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Tiger" rotational illusion appears on page 7 4 | # reference image: http://www.psy.ritsumei.ac.jp/~akitaoka/yellowOuchib.jpg 5 | 6 | output_name = "tiger" 7 | yellow_color = color(255,255,24) 8 | black_color = color(0,0,0) 9 | stripes = 30 10 | band_ratio = 17/64.0 11 | r1_ratio = 240/400.0 12 | r2_ratio = 320/400.0 13 | r_inc_ratio = .0005 14 | a_inc_ratio = 1/80.0 15 | 16 | ctr_max = 11 17 | 18 | def setup(): 19 | size(1024,1024) 20 | noLoop() 21 | 22 | myscale = 2 # oddly, higher scales look worse... 23 | def draw(): 24 | imap = createGraphics(width*myscale,height*myscale) 25 | imap.beginDraw() 26 | imap.loadPixels() 27 | n = 0 28 | for y in xrange(imap.height): 29 | yf = map(y,0,imap.height,-1,1) 30 | for x in xrange(imap.width): 31 | xf = map(x,0,imap.width,-1,1) 32 | d = dist(0,0,xf,yf) 33 | inverse = d > r1_ratio and d < r2_ratio 34 | if inverse: 35 | xf = -xf 36 | a = atan2(yf,xf)+PI 37 | colors = (yellow_color,black_color) if sin(a*.5*stripes-log(d)*PI*6) > 0 else (black_color,yellow_color) 38 | # pixels[n] = yellow_color if sin(a*.5*stripes-log(d)*PI*6) > 0 else black_color 39 | imap.pixels[n] = colors[0] if sin(a*2*stripes+log(d)*PI*22) > 0 else colors[1] 40 | n += 1 41 | imap.updatePixels() 42 | imap.endDraw() 43 | image(imap,0,0,width,height) 44 | saveFrame("../output/" + output_name + ".png") 45 | 46 | def old_draw(): 47 | mrad = dist(0,0,width/2,height/2) 48 | a_offset = 0 49 | pushMatrix() 50 | translate(width/2,height/2) 51 | ctr = 0 52 | y_stripe = 0 53 | r = 1 54 | strokeCap(SQUARE) 55 | while r < mrad: 56 | strokeWeight(TWO_PI*r*r_inc_ratio*2) 57 | inverse = r > width*r1_ratio and r < width*r2_ratio 58 | for s in xrange(stripes): 59 | a1 = a_offset + s*TWO_PI/stripes 60 | a2 = a_offset + (s+1)*TWO_PI/stripes 61 | if inverse: 62 | x1,y1 = (-cos(a1)*r,sin(a1)*r) 63 | x2,y2 = (-cos(a2)*r,sin(a2)*r) 64 | else: 65 | x1,y1 = (cos(a1)*r,sin(a1)*r) 66 | x2,y2 = (cos(a2)*r,sin(a2)*r) 67 | stroke(yellow_color if (s ^ y_stripe) % 2 > 0 else black_color) 68 | line(x1,y1,x2,y2) 69 | ctr += 1 70 | if ctr > ctr_max: 71 | y_stripe += 1 72 | ctr = 0 73 | a_offset += a_inc_ratio * TWO_PI/(stripes) 74 | r += TWO_PI*r*r_inc_ratio 75 | 76 | -------------------------------------------------------------------------------- /rotating_snakes/rotating_snakes.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Rotating Snakes" rotating spiral illusion (does not appear in the 2002 book) 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/rotsnake.gif 5 | 6 | color1 = color(209,211,18) 7 | color2 = color(29,99,254) 8 | # color1 = color(0,255,255) 9 | # color2 = color(255,0,0) 10 | # color1 = color(255,0,255) 11 | # color2 = color(0,255,0) 12 | # color1 = color(200,200,200) 13 | # color2 = color(100,100,100) 14 | 15 | 16 | rad = .99; 17 | freq = 42; 18 | shrink = 0.8 19 | lm = 20 20 | tm = 20 21 | output_name = "rotating_snakes" 22 | 23 | def setup(): 24 | size(1024,772) 25 | ellipseMode(RADIUS) 26 | noLoop() 27 | 28 | def draw_circle_pattern(cx,cy,rad,sign): 29 | print cx,cy,sign 30 | sNbr = 0 31 | shrink = 0.8 32 | noStroke() 33 | while rad > 5: 34 | irad = rad*shrink 35 | stripes = 42 36 | pushMatrix() 37 | translate(cx,cy) 38 | rotate(PI/stripes) 39 | aColor,bColor = (255,0) 40 | cColor = color2 if sign > 0 else color1 41 | dColor = color1 if sign > 0 else color2 42 | if sNbr % 2 > 0: 43 | rotate(2*PI/stripes) 44 | # draw checkers 45 | for s in range(stripes): 46 | a1 = s*TWO_PI/stripes 47 | a2 = (s+1)*TWO_PI/stripes 48 | fill(aColor if s % 2 > 0 else bColor) 49 | quad(cos(a1)*irad, sin(a1)*irad, 50 | cos(a2)*irad, sin(a2)*irad, 51 | cos(a2)*rad, sin(a2)*rad, 52 | cos(a1)*rad, sin(a1)*rad) 53 | oWidth = (rad-irad)/4.0 54 | oHeight = (rad-irad)/2.0 55 | for s in range(stripes): 56 | pushMatrix() 57 | rotate(s*TWO_PI/stripes) 58 | fill(cColor if s % 2 > 0 else dColor) 59 | ellipse((irad+rad)/2.0,0, 60 | oHeight,oWidth) 61 | popMatrix() 62 | 63 | popMatrix() 64 | rad = irad 65 | sNbr += 1 66 | # draw ovals 67 | 68 | def draw(): 69 | global lm,tm 70 | background(255) 71 | rad = (width-lm*2)/8 72 | 73 | for y in range(3): 74 | for x in range(4): 75 | cx = lm + rad + rad*2*x 76 | cy = tm + rad + rad*2*y 77 | draw_circle_pattern(cx,cy,rad,1 if (y ^ x) % 2 > 0 else -1) 78 | 79 | for y in range(2): 80 | for x in range(3): 81 | cx = lm+rad*2 + rad*2*x 82 | cy = tm+rad*2 + rad*2*y 83 | draw_circle_pattern(cx,cy,rad,1 if (y ^ x) % 2 > 0 else -1) 84 | 85 | saveFrame("../output/" + output_name + ".png") 86 | -------------------------------------------------------------------------------- /petit_tomatoes/petit_tomatoes.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Petit Tomatoes" motion illusion appears on page 17 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/tomato1.gif 5 | 6 | output_name = "petit_tomatoes" 7 | 8 | check_colors = [color(255,20,20),color(255,148,20)] 9 | star_colors = [color(0,150,20),color(255)] 10 | 11 | def setup(): 12 | size(1024,1024) 13 | noLoop() 14 | 15 | def quadstar(dsize): 16 | beginShape() 17 | vertex(0,-dsize) 18 | quadraticVertex(0,0,dsize,0) 19 | quadraticVertex(0,0,0,dsize) 20 | quadraticVertex(0,0,-dsize,0) 21 | quadraticVertex(0,0,0,-dsize) 22 | endShape() 23 | 24 | diag_checkers = 31 25 | wide_checkers = 16 26 | 27 | def draw(): 28 | background(255) 29 | cwidth = dist(0,0,width,height)/diag_checkers 30 | cdiag = width/16.0 # distance(0,0,cwidth,cwidth) should be about the same 31 | noStroke() 32 | dsize = cwidth*.4 33 | for y in range(wide_checkers): 34 | for x in range(wide_checkers): 35 | cx = cdiag/2 + x*cdiag 36 | cy = cdiag/2 + y*cdiag 37 | fill(check_colors[0]) 38 | quad(cx-cdiag/2,cy,cx,cy-cdiag/2,cx+cdiag/2,cy,cx,cy+cdiag/2) 39 | if y < wide_checkers-1 and x < wide_checkers-1: 40 | cx += cdiag/2 41 | cy += cdiag/2 42 | fill(check_colors[1]) 43 | quad(cx-cdiag/2,cy,cx,cy-cdiag/2,cx+cdiag/2,cy,cx,cy+cdiag/2) 44 | for y in range(wide_checkers): 45 | for x in range(wide_checkers): 46 | cx = cdiag/2 + x*cdiag 47 | cy = cdiag/2 + y*cdiag 48 | if y < wide_checkers-1: 49 | pushMatrix() 50 | translate(cx,cy+cdiag/2) 51 | rotate(PI/4) 52 | dx = abs(x-7.5) 53 | dy = abs(y-7) 54 | is_flipped = (dx+dy) < 4 55 | ctr = (0 + is_flipped) % 2 56 | fill(star_colors[ctr]) 57 | quadstar(dsize) 58 | popMatrix() 59 | if y < wide_checkers-1 and x < wide_checkers-1: 60 | cx += cdiag/2 61 | cy += cdiag/2 62 | pushMatrix() 63 | translate(cx,cy+cdiag/2) 64 | rotate(PI/4) 65 | dx = abs(x-7) 66 | dy = abs(y-6.5) 67 | is_flipped = (dx+dy) < 4 68 | ctr = (1 + is_flipped) % 2 69 | fill(star_colors[ctr]) 70 | quadstar(dsize) 71 | popMatrix() 72 | saveFrame("../output/" + output_name + ".png") 73 | 74 | 75 | -------------------------------------------------------------------------------- /ferryboats/ferryboats.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Ferry Boats" motion illusion / geometrical illusion appears on page 12 4 | # reference image found under the name "watashi": http://www.psy.ritsumei.ac.jp/~akitaoka/watashib.jpg 5 | 6 | 7 | 8 | output_name = "ferryboats" 9 | stripes = 31 10 | stripe_colors = [color(106,136,254),color(187,220,255)] 11 | boat_colors = [color(128),color(192)] 12 | dot_colors = [color(0),color(150),color(255),color(150)] 13 | 14 | def setup(): 15 | size(912,517) 16 | ellipseMode(RADIUS) 17 | noLoop() 18 | 19 | def draw_cherry(ctr,x,y): 20 | global cherry_rad 21 | fill(dot_colors[(ctr%2)*2]) 22 | ellipse(x,y,cherry_rad,cherry_rad) 23 | fill(dot_colors[(ctr%2)*2+1]) 24 | ellipse(x,y,cherry_rad*.3,cherry_rad*.3) 25 | 26 | def draw(): 27 | global cherry_rad 28 | sheight = height/float(stripes) 29 | bwidth = sheight * 2 30 | background(0) 31 | noStroke() 32 | for i in xrange(stripes): 33 | fill(stripe_colors[i % 2]) 34 | py = sheight*i 35 | rect(0,py,width,sheight) 36 | 37 | cherry_rad = sheight*.25 38 | 39 | for b in xrange(2): 40 | for y in xrange(1,stripes-1): 41 | px1 = map(y,1,stripes-2,sheight,sheight*8) + b*bwidth*2 42 | px2 = map(y+1,1,stripes-2,sheight,sheight*8) + b*bwidth*2 43 | py1 = y*sheight 44 | py2 = (y+1)*sheight 45 | fill(boat_colors[(y-1)%2]) 46 | quad(px1,py1, px1+bwidth,py1, px2+bwidth,py2,px2,py2) 47 | quad(width-px1,height-py1, width-(px1+bwidth),height-py1, width-(px2+bwidth),height-py2,width-px2,height-py2) 48 | if y > 1: 49 | draw_cherry(y,px1,py1) 50 | draw_cherry(y+1,px1+bwidth,py1) 51 | draw_cherry(y,width-px1,height-py1) 52 | draw_cherry(y+1,width-px1-bwidth,height-py1) 53 | 54 | oy = (9+13)*sheight 55 | ox1 = map(9+13,1,stripes-2,sheight,sheight*8)+bwidth*4 56 | ox2 = map(9+13+13,1,stripes-2,sheight,sheight*8)+bwidth*4 57 | for b in xrange(6): 58 | for y in xrange(13): 59 | fill(boat_colors[y%2]) 60 | px1 = map(y,0,12,ox1,ox2)+b*bwidth*2 61 | px2 = map(y+1,0,12,ox1,ox2)+b*bwidth*2 62 | py1 = (9+13-y)*sheight 63 | py2 = py1 - sheight 64 | quad(px1,py1,px1+bwidth,py1,px2+bwidth,py2,px2,py2) 65 | if y > 0: 66 | draw_cherry(y+1,px1,py1) 67 | draw_cherry(y,px1+bwidth,py1) 68 | 69 | saveFrame("../output/" + output_name + ".png") 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /shijo/shijo.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Shijo-dori Boogie-woogie" op effect, motion illusion appears on page 34 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/shijo.gif 5 | 6 | output_name = "shijo" 7 | 8 | margin_checkers = 2 9 | gw = 16*3 # checkers across 10 | 11 | c_colors = [color(0),color(29,0,254),color(255)] 12 | bg_color = color(255) 13 | 14 | patlen = 12 15 | 16 | def setup(): 17 | size(1040,1040) # intentionally a multiple of gw+margin_checkers*2 for sharp pixel boundaries 18 | noLoop() 19 | ellipseMode(RADIUS) 20 | 21 | def get_pat(x): 22 | return ((x+1)/3) & 0x01 23 | 24 | def get_color_index(x,y): 25 | x = x % (patlen*2) 26 | y = y % (patlen*2) 27 | if (x >= patlen) == (y < patlen): 28 | # invert 29 | x = 11-(x % 12) 30 | return (get_pat((x+y*(patlen-1)) % patlen))+1 31 | else: 32 | return get_pat((x+y*(patlen-1)) % patlen)*2 33 | 34 | 35 | def dashed_line(x1,y1,x2,y2): 36 | line(x1,y1,x2,y2) # needs work 37 | 38 | def dashed_rect(x,y,w,h): 39 | dashed_line(x,y,x+w,y) 40 | dashed_line(x+w,y,x+w,y+h) 41 | dashed_line(x+w,y+h,x,y+h) 42 | dashed_line(x,y+h,x,y) 43 | 44 | def draw(): 45 | 46 | cw = width/float(gw+margin_checkers*2) 47 | 48 | background(bg_color) 49 | pushMatrix() 50 | translate(margin_checkers*cw,margin_checkers*cw) 51 | 52 | # draw checkers 53 | for y in xrange(gw): 54 | for x in xrange(gw): 55 | c_idx = get_color_index(x,y) 56 | fill(c_colors[c_idx]) 57 | noStroke() 58 | rect(x*cw,y*cw,cw,cw) 59 | 60 | # draw red lines 61 | clip(0,0,gw*cw,gw*cw) 62 | cwd = dist(0,0,cw,cw) 63 | noFill() 64 | stroke(255,0,0) 65 | for y in xrange(3): 66 | yo = patlen*cw*y*2 67 | xo = 12*cw 68 | # stroke(0,255,0) 69 | for x in xrange(3): 70 | for r in xrange(1,5): 71 | pushMatrix() 72 | translate(xo+x*24*cw,yo) 73 | rotate(PI/4) 74 | rad = 1.5*r*cwd 75 | dashed_rect(-rad,-rad,rad*2,rad*2) 76 | popMatrix() 77 | 78 | 79 | xo = 0 80 | yo = patlen*cw*(y*2+1) 81 | # stroke(255,0,0) 82 | for x in xrange(3): 83 | for r in xrange(1,5): 84 | pushMatrix() 85 | translate(xo+x*24*cw,yo) 86 | rotate(PI/4) 87 | rad = 1.5*r*cwd 88 | dashed_rect(-rad,-rad,rad*2,rad*2) 89 | popMatrix() 90 | 91 | noClip() 92 | popMatrix() 93 | 94 | 95 | saveFrame("../output/" + output_name + ".png") 96 | 97 | -------------------------------------------------------------------------------- /bavarian_cream/bavarian_cream.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka and other publications 2 | 3 | # "Bavarian Cream" motion illusion, geometrical illusion appears on page 21 4 | # reference image: http://www.ritsumei.ac.jp/~akitaoka/babaroa.gif 5 | # and http://www.psy.ritsumei.ac.jp/~akitaoka/babaroa.jpg (remake) 6 | 7 | # tweaked a bit from 'autumn_color_waves' 8 | 9 | output_name = "bavarian_cream" 10 | 11 | checkers_h = 13 12 | checkers_v = 13 13 | cmargin = 9 14 | 15 | ccolors = [color(255,220,144), 16 | color(255,170,20)] 17 | scolors = [color(203,13,14), 18 | color(253,255,178)] 19 | 20 | pattern = (0,1,1,0,1,0,0,1) 21 | bulge = (0,1,4,5,5,5,6,6,5,5,5,4,1,0) 22 | 23 | def setup(): 24 | size(1024,1024) 25 | noLoop() 26 | 27 | debug = False 28 | 29 | def quadstar(dsize): 30 | beginShape() 31 | vertex(0,-dsize) 32 | quadraticVertex(0,0,dsize,0) 33 | quadraticVertex(0,0,0,dsize) 34 | quadraticVertex(0,0,-dsize,0) 35 | quadraticVertex(0,0,0,-dsize) 36 | endShape() 37 | 38 | def draw(): 39 | csize_h = width/float(checkers_h) 40 | csize_v = height/float(checkers_v) 41 | 42 | noStroke() 43 | for y in xrange(checkers_v): 44 | for x in xrange(checkers_h): 45 | ctr = (x+y) % 2 46 | fill(ccolors[ctr]) 47 | px = x*csize_h 48 | py = y*csize_v 49 | rect(px,py,csize_h,csize_v) 50 | 51 | dsize = csize_h*.25 52 | noStroke() 53 | for y in xrange(1,checkers_v): 54 | for x in xrange(1,checkers_h): 55 | dx = abs(x-6.5) 56 | dy = abs(y-6.5) 57 | if dx <= bulge[y] and dy <= bulge[x]: 58 | polarity = (x < 6.5) != (y < 6.5) 59 | ctr = (x+y+polarity) % 2 60 | fill(scolors[pattern[ctr]]) 61 | px = x*csize_h 62 | py = y*csize_v 63 | pushMatrix() 64 | translate(px,py) 65 | quadstar(dsize) 66 | popMatrix() 67 | 68 | # draw dividers 69 | # noStroke() 70 | # dsize = csize*.45 71 | # for y in xrange(1,checkers-1): 72 | # for x in xrange(1,checkers-1): 73 | # inverted = y >= cmargin and y <= checkers-cmargin and x >= cmargin and x <= checkers-cmargin 74 | # ctr = (x + y*3) % 4 if not inverted else (3+(x + y)) % 4 75 | # if ctr == 0 or ctr == 2: 76 | # fill(white if ctr < 2 else black) 77 | # px = x*csize 78 | # py = y*csize 79 | # pushMatrix() 80 | # translate(px,py) 81 | # quadstar(dsize) 82 | # popMatrix() 83 | 84 | saveFrame("../output/" + output_name + ".png") -------------------------------------------------------------------------------- /candies/candies.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Candy" rotation illusion on page 1 4 | # reference: http://www.psy.ritsumei.ac.jp/~akitaoka/candy2.gif 5 | # rev 2 reference: http://www.psy.ritsumei.ac.jp/~akitaoka/candyrevision2.gif 6 | 7 | output_name1 = "candies" # original: flat background 8 | output_name2 = "candies_rev2" # rev 2: gradient background 9 | 10 | background_color = color(200,12,11) 11 | candy_color = color(255,19,18) 12 | white = color(255,255,255) 13 | 14 | rad1_ratio = .585 15 | rad2_ratio = .773 16 | nbr_candies = 9*4 17 | strokeweight_ratio = .3 18 | diagonal_ratio = 1.5 19 | crosshair_ratio = .05 20 | crosshair_thick_ratio = .2 21 | 22 | def setup(): 23 | size(1024,1024) 24 | noLoop() 25 | 26 | 27 | def draw_candies(mode): 28 | 29 | rwidth,rheight = (width,height) 30 | rad1 = rwidth*.5*rad1_ratio 31 | rad2 = rwidth*.5*rad2_ratio 32 | dot1_rad = (TWO_PI*rad1/nbr_candies)*.33 33 | dot2_rad = (TWO_PI*rad2/nbr_candies)*.33 34 | ellipseMode(RADIUS) 35 | 36 | background(white) 37 | fill(background_color) 38 | noStroke() 39 | 40 | if mode == 0: 41 | rect(0,0,rwidth, rheight) 42 | else: 43 | # radial gradient from 90,0,0 228,15,15 44 | # blendMode(DARKEST) 45 | grad = dist(width/2,height/2,0,0) 46 | for r in xrange(1,grad): 47 | strokeWeight(2) 48 | noFill() 49 | stroke(lerpColor(color( 228,15,15),color(90,0,0),r/float(grad))) 50 | ellipse(width/2,height/2,r,r) 51 | 52 | pushMatrix() 53 | translate(width/2,height/2) 54 | 55 | # draw lines 56 | stroke(white) 57 | strokeCap(PROJECT) 58 | for i in xrange(nbr_candies): 59 | a = i*TWO_PI/nbr_candies 60 | a2 = i*TWO_PI/nbr_candies - PI*.25 61 | x = cos(a)*rad1 62 | y = sin(a)*rad1 63 | strokeWeight(dot1_rad*strokeweight_ratio) 64 | line(x+cos(a2)*dot1_rad*diagonal_ratio, y+sin(a2)*dot1_rad*diagonal_ratio, 65 | x+cos(a2+PI)*dot1_rad*diagonal_ratio, y+sin(a2+PI)*dot1_rad*diagonal_ratio) 66 | a2 = i*TWO_PI/nbr_candies + PI*.25 67 | x = cos(a)*rad2 68 | y = sin(a)*rad2 69 | strokeWeight(dot2_rad*strokeweight_ratio) 70 | line(x+cos(a2)*dot2_rad*diagonal_ratio, y+sin(a2)*dot2_rad*diagonal_ratio, 71 | x+cos(a2+PI)*dot2_rad*diagonal_ratio, y+sin(a2+PI)*dot2_rad*diagonal_ratio) 72 | 73 | # draw candies 74 | noStroke() 75 | fill(candy_color) 76 | for i in xrange(nbr_candies): 77 | a = i*TWO_PI/nbr_candies 78 | x = cos(a)*rad1 79 | y = sin(a)*rad1 80 | ellipse(x,y,dot1_rad,dot1_rad) 81 | x = cos(a)*rad2 82 | y = sin(a)*rad2 83 | ellipse(x,y,dot2_rad,dot2_rad) 84 | 85 | crosshair_rad = rwidth*crosshair_ratio*0.5 86 | crosshair_thick = crosshair_rad * crosshair_thick_ratio 87 | strokeWeight(crosshair_thick) 88 | strokeCap(SQUARE) 89 | stroke(0) 90 | noFill() 91 | line(-crosshair_rad,0,crosshair_rad,0) 92 | line(0,-crosshair_rad,0,crosshair_rad) 93 | 94 | popMatrix() 95 | 96 | def draw(): 97 | 98 | draw_candies(0) 99 | saveFrame("../output/" + output_name1 + ".png") 100 | 101 | draw_candies(1) 102 | saveFrame("../output/" + output_name2 + ".png") 103 | 104 | -------------------------------------------------------------------------------- /roller_torus/roller_torus.pyde: -------------------------------------------------------------------------------- 1 | # Roller Torus 2 | 3 | # based on variation by Beau Deeley http://www.horntorus.com/illustration/extern/BeauDeeley_01.jpg 4 | # based on pattern at http://www.psy.ritsumei.ac.jp/~akitaoka/rollersstrong3plastic.jpg 5 | 6 | output_name = "roller_torus" 7 | rad = .99; 8 | freq = 30; 9 | shrink = 0.8 10 | lm = 20 11 | tm = 20 12 | stripes = 32 13 | 14 | bg_color = color(27,40,225) 15 | circ_color = color(244,114,2) 16 | light_color = color(255,255,255) 17 | dark_color = color(0,0,0) 18 | 19 | ribs = 240 20 | detail = 120*2 21 | texture_width = 1024 22 | texture_height = int(texture_width*32.0/42.0) 23 | 24 | def setup(): 25 | global tMap 26 | size(1200,800, P3D) 27 | 28 | tMap = createGraphics(texture_width,texture_height, P2D) 29 | draw_circle_pattern(tMap, texture_width/2, texture_height/2, texture_width*.49) 30 | fov = PI*0.5 31 | cameraZ = (height/2.0) / tan(fov/2.0) 32 | perspective(fov, float(width)/float(height), 33 | cameraZ/10.0, cameraZ*10.0) 34 | textureMode(NORMAL) 35 | textureWrap(REPEAT) 36 | smooth(8) 37 | noLoop() 38 | 39 | def draw_circle_pattern(tMap, cx,cy,rad): 40 | sNbr = 0 41 | shrink = 0.8 42 | tMap.beginDraw() 43 | tMap.smooth(8) 44 | tMap.ellipseMode(RADIUS) 45 | tMap.noStroke() 46 | tMap.background(bg_color) 47 | stripes = 24 48 | crad = texture_width*0.5*0.66 49 | bord_scale = 0.8 50 | tMap.pushMatrix() 51 | tMap.translate(texture_width/2, texture_height/2) 52 | tMap.rotate(PI/2) 53 | tMap.fill(dark_color) 54 | tMap.arc(0,0,crad,crad,0,PI) 55 | tMap.fill(light_color) 56 | tMap.arc(0,0,crad,crad,PI,TWO_PI) 57 | tMap.fill(circ_color) 58 | tMap.ellipse(0,0,crad*bord_scale,crad*bord_scale) 59 | tMap.popMatrix() 60 | tMap.filter(BLUR) 61 | tMap.endDraw() 62 | 63 | # tube_rad is width of circle cross-section of donut 64 | # mid-point between outer/inner radius 65 | def torus(inner_radius, outer_radius, ribs,detail, textureMap,invert=False): 66 | global t 67 | tube_rad = (outer_radius-inner_radius)/2.0 68 | cx = (inner_radius+outer_radius)/2.0 69 | cy = 0 70 | texture_inc = stripes / float(ribs) 71 | for r in xrange(ribs): 72 | pushMatrix() 73 | # rotateX(PI*.3) 74 | rotateY(r*TWO_PI/ribs) 75 | beginShape(QUAD_STRIP) 76 | texture(textureMap) 77 | for d in xrange(detail+1): 78 | x = cx + cos(d*TWO_PI/detail)*tube_rad 79 | y = cy + sin(d*TWO_PI/detail)*tube_rad # * tube_aspect 80 | # tx = r/float(ribs) 81 | tx = r*stripes/float(ribs) 82 | ty = d*stripes*1.3125/float(detail) 83 | # circumfrence of circle at this x coordinate 84 | x_circ = TWO_PI*x 85 | rib_rad = (x_circ/ribs)*0.5 86 | vertex(x,y,-rib_rad,tx,ty) 87 | vertex(x,y,rib_rad,tx-texture_inc,ty) 88 | endShape() 89 | popMatrix() 90 | 91 | 92 | def draw(): 93 | global t, tMap 94 | background(255) 95 | noStroke() 96 | pushMatrix() 97 | t = 0 # millis()*0.0002 98 | camera(0,-height*0.5,-width*.5, # eye 99 | 0,height,0, # target 100 | 0,1,0) 101 | 102 | v = 80 # ; // map(mouseY,height,0,0,255); 103 | cx = width/2 104 | ambientLight(v,v,v) 105 | v1 = 128 + sin(-PI/4)*128 106 | v2 = 128 + cos(-PI/4)*128 107 | pointLight(v1,v1,v1,cx*0.1,0,cx) # backlight 108 | pointLight(v2,v2,v2,cx*0.1,0,-cx) # frontlight 109 | 110 | 111 | # translate(width/2,height/2,-500) 112 | # rotateX(-TWO_PI*.05) 113 | # rotateZ(TWO_PI/60) 114 | # rotateX(PI/2) 115 | 116 | # apply lighting here... 117 | 118 | # for r in range(200,800,200): 119 | # torus(r-200,r+20,ribs,detail,tMap,r%2==0) 120 | 121 | torus(66, width, ribs, detail, tMap) 122 | 123 | popMatrix() 124 | # image(tMap,0,0) 125 | saveFrame("../output/" + output_name + ".png") 126 | -------------------------------------------------------------------------------- /negajo_2011/negajo_2011.pyde: -------------------------------------------------------------------------------- 1 | # Selected reproductions of full page illustrations from the book "Trick Eyes" (2002) by Akiyoshi Kitaoka 2 | 3 | # "Snakes, the Eto of 2001" rotation illusion appears on page 18 4 | # Reference Image: http://www.psy.ritsumei.ac.jp/~akitaoka/hebi2001.gif 5 | 6 | output_name = "negajo_2011" 7 | bg_color = color(178) 8 | c_colors = (color(0),color(255)) 9 | tongue_color = color(254,19,18) 10 | eye_color = color(255) 11 | 12 | orig_width = 417 13 | orig_height = 484 14 | 15 | 16 | def setup(): 17 | size(1024,1188) # orig is 417 x 484 18 | noLoop() 19 | 20 | def snake_tail(px,py,ang,fg_color): 21 | global cw 22 | pushMatrix() 23 | translate(px,py) 24 | rotate(ang) 25 | fill(fg_color) 26 | strokeWeight(1) 27 | stroke(fg_color) 28 | arc(0,0,cw*2,cw,-PI/2,PI/2) 29 | popMatrix() 30 | 31 | def snake_head(px,py,ang,fg_color,eye_color,sc=1.0): 32 | global cw,sw 33 | pushMatrix() 34 | translate(px,py) 35 | rotate(ang) 36 | scale(sc,1.0) 37 | 38 | # head 39 | fill(fg_color) 40 | strokeWeight(1) 41 | stroke(fg_color) 42 | rect(0,-cw,cw*2,cw*2) 43 | ellipse(cw*2,0,cw,cw) 44 | noStroke() 45 | fill(bg_color) 46 | arc(cw*3,0,cw,cw,0,PI) 47 | fill(eye_color) 48 | ellipse(cw*2,-cw/2,cw*.15,cw*.15) 49 | 50 | # tongue 51 | stroke(tongue_color) 52 | noFill() 53 | strokeWeight(sw) 54 | strokeCap(ROUND) 55 | beginShape() 56 | curveVertex(cw*2+sw,sw) 57 | curveVertex(cw*2+sw,sw) 58 | curveVertex(cw*3,cw*0.5) 59 | curveVertex(cw*4,cw*1-sw) 60 | curveVertex(cw*4,cw*1-sw) 61 | endShape() 62 | beginShape() 63 | curveVertex(cw*2+sw,sw*2) 64 | curveVertex(cw*2+sw,sw) 65 | curveVertex(cw*3,cw*0.4) 66 | curveVertex(cw*4,sw) 67 | curveVertex(cw*4,sw) 68 | endShape() 69 | noStroke() 70 | 71 | 72 | 73 | popMatrix() 74 | 75 | def draw(): 76 | global cw,sw 77 | ellipseMode(RADIUS) 78 | 79 | sw = width*1.5/orig_width 80 | cw = width*10.0/orig_width 81 | lm = width*23.0/orig_width 82 | tm = height*55.0/orig_height 83 | 84 | gw,gh = (32,38) 85 | 86 | background(bg_color) 87 | pushMatrix() 88 | translate(lm,tm) 89 | 90 | # interior 91 | x_ofst = 0 92 | x_ofst_dir = 1 93 | 94 | # top/bot heads/tails 95 | for x in xrange(0,gw,2): 96 | px1 = x*cw+cw 97 | py1 = 0*cw+cw*2 98 | px2 = x*cw+cw 99 | py2 = (gh-2)*cw 100 | ctr = (x/2)%2 101 | noStroke() 102 | fill(c_colors[(x/2) % 2]) 103 | if ctr == 0: 104 | snake_head(px1,py1,-PI/2,c_colors[0],c_colors[1]) 105 | snake_tail(px2,py2,PI/2,c_colors[0]) 106 | else: 107 | snake_tail(px1,py1,-PI/2,c_colors[1]) 108 | snake_head(px2,py2,PI/2,c_colors[1],c_colors[0]) 109 | 110 | # left/right heads/tails 111 | x_ofst = 1 112 | x_ofst_dir = 1 113 | for y in xrange(2,gh-2): 114 | px1 = (x_ofst)*cw+cw 115 | py1 = y*cw 116 | px2 = (x_ofst+gw-2)*cw 117 | py2 = y*cw 118 | if y % 2 == 1: 119 | if (5+y) % 6 != 0: 120 | if x_ofst_dir > 0: 121 | snake_head(px1,py1,-PI,c_colors[0],c_colors[1]) 122 | snake_head(px2,py2,0,c_colors[1],c_colors[0]) 123 | else: 124 | print "!" 125 | snake_head(px1+cw,py1,0,c_colors[0],c_colors[1],sc=-1) 126 | snake_head(px2,py2,-PI,c_colors[1],c_colors[0],sc=-1) 127 | else: 128 | fill(0) 129 | stroke(0) 130 | strokeWeight(1) 131 | rect(px1-cw,py1-cw,cw,cw*2) 132 | fill(255) 133 | stroke(255) 134 | rect(px2+cw,py2-cw,cw,cw*2) 135 | x_ofst += x_ofst_dir 136 | if x_ofst == 6: 137 | x_ofst = 5 138 | x_ofst_dir = -1 139 | elif x_ofst == -1: 140 | x_ofst = 0 141 | x_ofst_dir = 1 142 | 143 | x_ofst = 1 144 | x_ofst_dir = 1 145 | for y in xrange(2,gh-1): 146 | if y < gh-2: 147 | for x in xrange(1,gw-1): 148 | px = (x_ofst+x)*cw 149 | py = y*cw 150 | fill(c_colors[(x/2) % 2]) 151 | stroke(c_colors[(x/2) % 2]) 152 | strokeWeight(1) 153 | rect(px,py,cw,cw) 154 | if (5+y) % 6 != 0: 155 | stroke(bg_color) 156 | strokeWeight(sw) 157 | line(0,y*cw,width,y*cw) 158 | x_ofst += x_ofst_dir 159 | if x_ofst == 6: 160 | x_ofst = 5 161 | x_ofst_dir = -1 162 | elif x_ofst == -1: 163 | x_ofst = 0 164 | x_ofst_dir = 1 165 | 166 | 167 | popMatrix() 168 | saveFrame("../output/" + output_name + ".png") 169 | 170 | --------------------------------------------------------------------------------