12
\$\begingroup\$

So I'd like you to attempt to generate Rorschach images like the below image:

Fake Rorschach Picture

Here is a link to further inspiration.

This is a popularity contest, but I will say that colours are likely to be more popular than black and white, as well as textures.

Rorschach images are created by folding paper with ink on so one criteria is symmetry.

ASCII art is valid, but will be subject to the same criteria as above.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ so which is it, code-golf, or popularity-contest? \$\endgroup\$ Mar 13, 2014 at 15:08
  • 2
    \$\begingroup\$ <quote Richard Feynman>There's a meaningless inkblot, and the others ask you what you think you see, but when you tell them, they start arguing with you!</quote> \$\endgroup\$
    – user80551
    Mar 13, 2014 at 15:32
  • 2
    \$\begingroup\$ Already here :) mathematica.stackexchange.com/a/4224/193 \$\endgroup\$ Mar 13, 2014 at 17:05
  • 1
    \$\begingroup\$ I would love to see a stereogram for this. \$\endgroup\$
    – Justin
    Mar 13, 2014 at 17:37
  • 1
    \$\begingroup\$ It reminded me on a picture I saw recently \$\endgroup\$
    – V-X
    Mar 13, 2014 at 18:07

2 Answers 2

12
\$\begingroup\$

Python

Not quite the best or smoothest, but here's a python solution:

from PIL import Image
import random
import sys

imgsize = (int(sys.argv[1]), int(sys.argv[2]))
color = (0, 0, 0)
img = Image.new("RGB", imgsize, "white")

for j in range(0,int(sys.argv[3])):
    start = (random.randrange(0, imgsize[0]/2), random.randrange(0, imgsize[1]))
    point = start
    img.putpixel(point, color)

    blotsize = random.randrange(0, int(sys.argv[4]))
    for i in range(blotsize):
        directions = [(point[0], point[1]+1), (point[0], point[1]-1), (point[0]+1, point[1]), (point[0]-1, point[1])]
        toremove = []
        for direction in directions:
            if direction[0]>=(imgsize[0]/2) or direction[1]>=imgsize[1] or direction[0]<0 or direction[1]<0:
                toremove.append(direction)
        for d in toremove:
            directions.remove(d)
        point = random.choice(directions)
        img.putpixel(point, color)

cropped = img.crop((0, 0, imgsize[0]/2, imgsize[1]))
img = img.transpose(Image.FLIP_LEFT_RIGHT)
img.paste(cropped, (0, 0, imgsize[0]/2, imgsize[1]))

img.save("blot.png")

It just makes a "wandering path" for a blot, and makes several of those.

An example usage:

py inkblot.py width height blots blotsize
py inkblot.py 512 512 20 10000

And some example images: blot1 blot2

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG! We encourage posters to make a prominent header indicating the language they used. You can use Markdown syntax in the editor to do so, e.g. ## Python \$\endgroup\$ Mar 14, 2014 at 17:57
  • 5
    \$\begingroup\$ Maybe instead of single pixels you can use (random sized) disks. \$\endgroup\$
    – Howard
    Mar 14, 2014 at 18:03
  • 1
    \$\begingroup\$ Welcome! You have some very nice results here. \$\endgroup\$ Mar 15, 2014 at 22:05
11
\$\begingroup\$

Fortran 95

This code is kind of big, but it produces a nice(ish) ASCii result:

program Rorschach
implicit none

integer :: i, j, k, l, N, seed
integer, dimension (24) :: i_zero, j_zero
real :: aux
integer, dimension (17,12) :: matrix_I = 0
character, dimension (17,12) :: matrix_C

! random seed according to system clock
call SYSTEM_CLOCK(count=k)
call RANDOM_SEED(size=N)
allocate(seed(N))
seed=k+37*(/ (i - 1, i = 1, n) /)
call RANDOM_SEED(PUT=seed)

! generating 7 random points
do i=1,7
  call RANDOM_NUMBER(aux)
  i_zero(i) = 15 * aux + 2 ! range = 2-16
  call RANDOM_NUMBER(aux)
  j_zero(i) = 11 * aux + 2 ! range = 2-12
enddo

! generating 7 large spots of ink
do i=1,7
  matrix_I(i_zero(i),j_zero(i)) = 3 ! central points have ink value 3
  do k=-1,1
    do l=-1,1
      if (.NOT.((k==0) .AND. (l==0))) then ! immediate neighbours...
        if ( (((i_zero(i)+k)<=17).OR.((i_zero(i)+k)>0)) .AND. (((j_zero(i)+l)<=12).OR.((j_zero(i)+l)>0)) ) then ! ... that are inside the designed area ...
            if (matrix_I(i_zero(i)+k,j_zero(i)+l) < 2) matrix_I(i_zero(i)+k,j_zero(i)+l) = 2 ! ... and that do not have ink value larger than 2 will be attributed as 2
        endif
      endif
    enddo
  enddo
enddo

! generating N little sparkles of ink
call RANDOM_NUMBER(aux)
N = int(11 * aux) + 20 ! N = 20-30

i = 0
do while (i <= N)
  call RANDOM_NUMBER(aux)
  i_zero(i) = 16 * aux + 1 ! range = 1-17
  call RANDOM_NUMBER(aux)
  j_zero(i) = 11 * aux + 1 ! range = 1-12
  if (matrix_I(i_zero(i),j_zero(i)) < 1) then ! if the selected point already has more ink than 1, then cycle the loop
    matrix_I(i_zero(i),j_zero(i)) = 1
    else
      cycle
  endif
  i = i + 1
enddo

! converting matrix of integers into matrix of characters
do i=1,17
  do j=1,12
    select case(matrix_I(i,j))
      case(0)
      matrix_C(i,j) = " "
      case(1)
      matrix_C(i,j) = "."
      case(2)
      matrix_C(i,j) = "+"
      case(3)
      matrix_C(i,j) = "@"      
    end select
  enddo
enddo

! printing it on the screen + its reflection
do i=1,17
  do j=1,12
    write(*,"(A1)",advance="NO") matrix_C(i,j)
  enddo
  do j=12,2,-1
    write(*,"(A1)",advance="NO") matrix_C(i,j)
  enddo
  write(*,"(A1)") matrix_C(i,1)
enddo

end program Rorschach

The code is fully commented, but the basic idea is that it generates a matrix with values between 0 and 3, representing the amount of ink in that spot. There are 7 large spots of ink (a spot with a value 3 surrounded by values 2) and a lot of little "sparkles" (value 1). This matrix is then converted into a character matrix, using the following conversion:

0 =  
1 = .
2 = +
3 = @

Here is a result:

 +++      .  .      +++ 
 +@++++   .  .   ++++@+ 
 ++++@+.        .+@++++ 
   .+++   ++++   +++.   
          +@@+          
. .   . +++@@+++ .   . .
.       +@++++@+       .
     ++++++  ++++++     
     +@+        +@+     
.    ++++      ++++    .
   .  +@+      +@+  .   
  .  .+++.    .+++.  .  
 . .   .        .   . . 
    .    .    .    .    
   .   ..      ..   .   
 .                    . 
\$\endgroup\$
4
  • 1
    \$\begingroup\$ FORTRAN! A personal favourite. \$\endgroup\$ Mar 13, 2014 at 17:00
  • 2
    \$\begingroup\$ Thank you! Usually Fortran + beginner's code don't stand a chance here, but boy, have I been learning a lot about programming since I started participating in this site! \$\endgroup\$ Mar 13, 2014 at 19:56
  • 1
    \$\begingroup\$ !FORTRAN is king of lists in my eyes, and this is just lists so I don't see how you could go wrong. \$\endgroup\$ Mar 13, 2014 at 20:14
  • 1
    \$\begingroup\$ Fortran isn't so hot for brevity, but the performance is on point. \$\endgroup\$ Mar 13, 2014 at 22:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.