116

Optical illusions are fun, so I thought it would be a good idea to have a list of optical illusions designed using MetaPost, or PGF/TikZ, or PS-Tricks, or Asymptote. Each entry should display one optical illusion and the code necessary to produce it.

3
  • 3
    +1 for MP examples, but I still don't see why questions like this should be CW. I plan on asking a meta question about this, but for now read The Future of community Wiki. Aug 20, 2013 at 20:03
  • Besides some lines that do not appear to be straight or parallel or of equal length but in fact are, the Spinning Dancer would be an interesting project. Aug 20, 2013 at 21:10
  • @Qrrbrbirlbel indeed. Go for it! Aug 20, 2013 at 22:09

22 Answers 22

108

Don't stare at this one for too long.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
  \fill[color=black!40!white] (-6,-6) rectangle (6,6);
  \foreach \n/\r/\twist in {70/5/12,56/4/-12,42/3/12,28/2/-12}{
    \foreach \m in {1,3,...,\n}
      \draw [thick,color=white,shift={(360/\n*\m:\r)},rotate=\twist+360/\n*\m]
        (-.15,-.15) rectangle (.15,.15);
    \foreach \m in {2,4,...,\n}
      \draw [thick,color=black,shift={(360/\n*\m:\r)},rotate=\twist+360/\n*\m]
        (-.15,-.15) rectangle (.15,.15);
    }
\end{tikzpicture}

\end{document}

enter image description here

8
  • 25
    That's ridiculously deceiving...
    – Werner
    Aug 20, 2013 at 23:37
  • 5
    I tried counting the circles. My brain refused, even though I know how many there are.
    – naught101
    Aug 21, 2013 at 5:53
  • Circles? Isn't it a spiral? :-)
    – mhelvens
    Aug 21, 2013 at 6:22
  • 6
    @naught101 Why would you count them? This is a mathematics site, just draw a line across the drawing and count the intersections :p
    – Thomas
    Aug 21, 2013 at 10:12
  • @Thomas That's clever!
    – Jeel Shah
    Aug 21, 2013 at 14:25
52

The following graphics are shamelessly copied from the MetaFun manual and coded by Hans Hagen. The title is: Manupulating contrast by changing spatial configuration. The graphics originate from the psychologist Kurt Koffka.

result

\starttext

\startuseMPgraphic{first}
  numeric height, width, radius, gap ; gap := 1mm ;
  height = 2.5cm ; width := height/2 ; radius := height/2.5 ;
  color mainshade, leftshade, rightshade, centershade ;
  mainshade   := \MPcolor{lightblue} ;
  leftshade := .9mainshade ; rightshade := .5mainshade ;
  centershade := .5[leftshade,rightshade] ;
  fill unitsquare xyscaled ( width,height) withcolor leftshade ;
  fill unitsquare xyscaled (-width,height) withcolor rightshade ;
  draw (fullcircle scaled radius) shifted (0,height/2)
  withpen pencircle scaled (radius/2) withcolor centershade ;
\stopuseMPgraphic

\startuseMPgraphic{second}
  \includeMPgraphic{first}
  interim linecap := butt ; pickup pencircle scaled gap ;
  draw (0,0) -- (0,height) withcolor white ;
\stopuseMPgraphic


\startuseMPgraphic{third}
  \includeMPgraphic{first}
  picture p, q ; p := q := currentpicture ;
  clip p to unitsquare xscaled width yscaled height ;
  clip q to unitsquare xscaled -width yscaled height ;
  currentpicture := p ;
  addto currentpicture also q shifted (0,radius/2) ;
\stopuseMPgraphic

\useMPgraphic{first}
\useMPgraphic{second}
\useMPgraphic{third}

\stoptext
7
  • 2
    What is the illusion?
    – gerrit
    Aug 21, 2013 at 11:37
  • 8
    When the circle is taken apart and shifted, the right half of the circle appears to be darker than the left half. But the circle has one uniform colour.
    – Marco
    Aug 21, 2013 at 11:42
  • 1
    Hm. They look the same colour to me.
    – gerrit
    Aug 21, 2013 at 11:46
  • 5
    Most people perceive both halfs to be different shades, maybe you are not affected. A psychologist may be able to draw interesting conclusions from this. ;)
    – Marco
    Aug 21, 2013 at 11:56
  • How do you compile this? I tried using context <file_name>, but all I get is a log and a tuc file.
    – A.Ellett
    Sep 5, 2013 at 4:29
46

The radius of both orange circles is the same- this is Ebbinghaus' illusion

enter image description here

% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[baseline=(X.base)]
    \node[circle,fill=orange,draw=orange,minimum size=2cm] (X) at (0,0) {};
    \foreach \i in {0,60,...,330}{
        \filldraw[blue!50!white]  (\i:3.4) circle (1.6);}
\end{tikzpicture}
\hspace{1cm}
\begin{tikzpicture}[baseline=(X.base)]
    \node[circle,fill=orange,draw=orange,minimum size=2cm] (X) at (0,0) {};
    \foreach \i in {0,45,...,360}{
        \filldraw[blue!50!white]  (\i:1.5)  circle (.4);}
\end{tikzpicture}
\end{document}
6
  • 3
    Maybe are the colors or the distance between the circles that differ from the ones on the wikipedia picture but, the circles look the same to me in this picture. Aug 21, 2013 at 3:50
  • I think it is the size of the surrounding circles around the left circle. They are not as big as in the Wikipedia picture. Aug 21, 2013 at 4:47
  • Maybe put them further apart?
    – naught101
    Aug 21, 2013 at 5:54
  • 3
    @AndresRiofrio yes, probably is the size of the surrounding circles in the left, they should be bigger than the one in the center. Aug 21, 2013 at 9:56
  • 1
    @cmhughes nice, looks more effective now. Aug 21, 2013 at 14:25
46

With PSTricks.

\documentclass[pstricks,border=12pt]{standalone}
\newpsstyle{gridstyle}
{
    gridlabels=0,
    gridwidth=6pt,
    subgriddiv=1,
    gridcolor=gray,
}
\begin{document}
\begin{pspicture}(8,8)
    \psframe*(8,8)
    \psgrid[style=gridstyle]
    \psset{linecolor=white}
    \multips(0,1)(0,1){7}{\multips(1,0)(1,0){7}{\qdisk(0,0){4.242pt}}}
\end{pspicture}
\end{document}

enter image description here

2
  • 3
    Why PSTricks? The picture code would be almost the same ;)
    – yo'
    Sep 5, 2013 at 9:13
  • 4
    @tohecz: There are only two options: with PSTricks or without PSTricks. :-) Sep 5, 2013 at 10:56
41

They are or not parallels?

A very popular one.

The perpendicular lines that do not match row to row create an illusion of the lines between them being not parallel. NetLogo Models Library: Optical Illusions

Parallels

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
    \pagecolor{gray}
    \begin{tikzpicture}
        \pgfmathsetmacro{\offsety}{.05};
        \foreach \y / \offsetx in {0/0.3,1/0.5,2/0.3,3/0,4/0.3,5/0.5,6/0.3,7/0,8/0.3}
            \foreach \x in {0,...,10}{%
                \pgfmathifthenelse{mod(\x,2) == 0}{"black"}{"white"}
                %\ifodd\x \def\squarecolor{white} \else \def\squarecolor{black} \fi %Other way, use \squarecolor inside fill options
                \fill[\pgfmathresult] ($(\x,\y)+(\offsetx,\offsety*\y)$) rectangle +(1,1);
            }
    \end{tikzpicture}
\end{document}
35

Here is one in metapost

path p[],tread[],riser[];
picture pic[];
color treadc;

a:=3;       A:=a; % steps from left to top
b:=8;       B:=a+b; % steps from top to right
c:=b-1;     C:=a+b+c; % steps from right to bottom
d+c=a+b;    D:=a+b+c+d; % steps from bottom to lefttheta:=25;
theta:=25;
u:=1cm;
dy=u*sind(theta)/cosd(theta);
p0:=(0,0)--(u,dy)--(2u,0)--(u,-dy)--cycle;
treadc:=(.8,.75,.7);

beginfig(1)
  % define leftmost corner of each tread, also define riser implicitly
  z0=(0,0) =z[D];
  for i =   1 upto A: z[i]=z[i-1]+( u, dy+riser); endfor;
  for i = A+1 upto B: z[i]=z[i-1]+( u,-dy+riser); endfor;
  for i = B+1 upto C: z[i]=z[i-1]+(-u,-dy+riser); endfor;
  for i = C+1 upto D: z[i]=z[i-1]+(-u, dy+riser); endfor;
  treadht:=.3riser;
  % paths for treads
  for i = 0 upto D-1:
    tread[i]:= p0 shifted z[i];
    fill tread[i] withcolor treadc;
    draw tread[i];
  endfor
  tread[D]=tread[0];
  % points for building
  z0o=point 0 of tread0;        z0i=point 2 of tread0;
  z[A]o=point 1 of tread[a];    z[A]i=point 3 of tread[a];
  z[B]o=point 2 of tread[B];    z[B]i=point 0 of tread[B];
  z[C]o=point 3 of tread[C];    z[C]i=point 1 of tread[C];
  z0l=z0o +(0,-D*dy/2);
  z[C]l=z[C]o + whatever*down = z0l+whatever*(u,-dy);
  z[B]l=z[B]o + whatever*down = z[C]l+whatever*(u,dy);
  % paths for risers
  for i = 0 upto a-1:
    riser[i]:=subpath(1,2) of tread[i] -- subpath(3,4) of tread[i+1] -- cycle;
    fill riser[i] withcolor .6white;
    draw riser[i];
    draw subpath(2,3) of riser[i] shifted (0,-treadht) withcolor .3treadc;
  endfor
  for i = a upto B-1:
    riser[i]:=subpath(2,3) of tread[i] -- subpath(0,1) of tread[i+1] -- cycle;
  endfor
  for i = B upto C-1:
    riser[i]:=subpath(3,4) of tread[i] -- subpath(1,2) of tread[i+1] -- cycle;
  endfor
  for i = C upto D-1:
    riser[i]:=subpath(0,1) of tread[i] -- subpath(2,3) of tread[i+1] -- cycle;
    fill riser[i] withcolor .6white;
    draw riser[i];
    draw subpath(2,3) of riser[i] shifted (0,-treadht) withcolor .3treadc;
  endfor
  % clipping path for inside
  p1:=point 2 of tread0 --
    for i=1 upto a-1:  subpath (3,2) of tread[i] -- endfor
    for i=a+1 upto B-2: subpath(4,3) of tread[i] -- endfor
    (subpath(4,3) of tread[B-1] cutafter tread[B+1]) --
    for i=B+1 upto C-1: (subpath(1,0) of tread[i] cutafter  tread[i+1]) -- endfor
    point 1 of tread[C] --
    for i = C+1 upto D-1: subpath(2,1) of tread[i] -- endfor
    cycle;
  % clipping path for outside
  p2:=for i = B upto C: subpath(2,3) of tread[i] -- endfor
    for i = C upto D: subpath(3,4) of tread[i] -- endfor
    z0l--z[C]l--z[B]l--cycle;
  % inside wall picture
  pic1=image(
    p99:=z0i--(z0i+(a-1)*(u,dy))--(z0i+(a-1)*(u,dy)+(b-1)*(u,-dy));
    p99:=p99--(reverse p99 shifted (0,-riser))--cycle;
    M:=D*dy/riser;
    for i = -B upto M:
      fill p99 shifted (0,-i*riser) withcolor .2[(.5-.6*i/M)*white,if odd(i+B): (.7,.7,.6) else: (.1,.1,0) fi];
      draw p99 shifted (0,-i*riser) withcolor .2white;
    endfor
    draw z[a]i--(z[a]i+D*dy*down);
    );
  fill p1 withcolor treadc;
  clip pic1 to p1;
  pic1:=image(
    draw pic1 shifted (0,-treadht);
    draw p1 shifted (0,-treadht)withcolor .3treadc;
    );
  clip pic1 to p1;
  draw pic1;
  draw p1;
  % outside wall picture
  pic2=image(
    p99:=(0,0)--((d+1)*(u,-dy))--((d+1)*(u,-dy)+(c+1)*(u,dy));
    p99:=p99--(reverse p99 shifted (0,-riser))--cycle;
    M:=D*dy/riser;
    for i = 0 upto M:
      fill p99 shifted (0,-i*riser) withcolor .2[(.7-.6*i/M)*white,if odd(i): (1,1,.8) else: (.2,.2,0) fi];
      draw p99 shifted (0,-i*riser) withcolor .4white;
    endfor
    draw z[C]o--z[C]l;
    );
  fill p2 withcolor treadc;
  clip pic2 to p2;
  pic2:=image(
    draw pic2 shifted (0,-treadht);
    draw p2 shifted (0,-treadht)withcolor .3treadc;
    );
  clip pic2 to p2;
  draw pic2;
  draw p2;
endfig;

bye

enter image description here

33

The following graphic is shamelessly copied from the MetaFun manual and coded by Hans Hagen. The title is: White's illusion.

result

\starttext
  \startMPcode
    interim linecap := butt ; numeric u ; u := 1cm ;
    pickup pencircle scaled .5u ;
    for i=1u step u until 5u :
      draw (0,i) -- (5u,i) ;
    endfor ;
    for i=2u step u until 4u :
      draw (u,i) -- (2u,i) withcolor .5white ;
      draw ((3u,i) -- (4u,i)) shifted (0,-.5u) withcolor .5white ;
    endfor ;
  \stopMPcode
\stoptext
30

Here is an Escher brick and a Penrose triangle; I submitted this code to texample a while back but I've only just seen this question.

enter image description here

\documentclass{article}
\usepackage{tikz}
\begin{document}
  \begin{center}
    \begin{tikzpicture}[scale=4.5, line join=bevel]

      % \a and \b are two macros defining characteristic
      % dimensions of the impossible brick.
      \def\a{0.18}
      \def\b{1.37}

      \tikzset{%
        apply style/.code={\tikzset{#1}},
        brick_edges/.style={thick,draw=black},
        face_colourA/.style={fill=gray!50},
        face_colourB/.style={fill=gray!25},
        face_colourC/.style={fill=gray!90},
      }

      \foreach \theta/\v/\facestyleone/\facestyletwo in {%
        0/0/{brick_edges,face_colourA}/{brick_edges,face_colourC},
        180/-\a/{brick_edges,face_colourB}/{brick_edges,face_colourC}
      }{
      \begin{scope}[rotate=\theta,shift={(\v,0)}]
        \draw[apply style/.expand once=\facestyleone]       
          ({-.5*\b},{1.5*\a}) --
          ++(\b,0)            --
          ++(-\a,-\a)         --
          ++({-\b+2*\a},0)    --
          ++(0,-{2*\a})       --
          ++(\b,0)            --
          ++(-\a,-\a)         --
          ++(-\b,0)           --
          cycle;
        \draw[apply style/.expand once=\facestyletwo] 
          ({.5*\b},{1.5*\a})  --
          ++(0,{-2*\a})       --
          ++(-\a,0)           --
          ++(0,\a)            --
          cycle;
        \end{scope}
      }
    \end{tikzpicture}

    \vspace{1cm}

    \begin{tikzpicture}[scale=1, line join=bevel]

    % \a and \b are two macros defining characteristic
    % dimensions of the Penrose triangle.       
    \def\a{2.5}
    \def\b{0.9}

    \tikzset{%
      apply style/.code     = {\tikzset{#1}},
      triangle_edges/.style = {thick,draw=black}
    }

    \foreach \theta/\facestyle in {%
        0/{triangle_edges, fill = gray!50},
      120/{triangle_edges, fill = gray!25},
      240/{triangle_edges, fill = gray!90}%
    }{
      \begin{scope}[rotate=\theta]
        \draw[apply style/.expand once=\facestyle]
          ({-sqrt(3)/2*\a},{-0.5*\a})                     --
          ++(-\b,0)                                       --
            ({0.5*\b},{\a+3*sqrt(3)/2*\b})                -- % higher point 
            ({sqrt(3)/2*\a+2.5*\b},{-.5*\a-sqrt(3)/2*\b}) -- % rightmost point
          ++({-.5*\b},-{sqrt(3)/2*\b})                    -- % lower point
            ({0.5*\b},{\a+sqrt(3)/2*\b})                  --
          cycle;
        \end{scope}
      } 
      \end{tikzpicture}
  \end{center}
\end{document}
28

enter image description here

Another old illusion with lualatex and METAPOST

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
numeric a,b; path rhomb;
a:=2cm; b:=sqrt(3)/2*a;
rhomb:=(b,0)--(0,a/2)--(-b,0)--(0,-a/2)--cycle;

picture rhombs;
rhombs := image(
  fill rhomb shifted ( b,0);  fill rhomb shifted (0, 3a/2);  
  fill rhomb shifted (-b,0);  fill rhomb shifted (0,-3a/2);
);

draw rhombs withcolor red;
draw rhombs rotated 120 withcolor green;
draw rhombs rotated -120 withcolor blue;

endfig;
end.
\end{mplibcode}
\end{document}
2
28

Another metapost illusion - one of my favourite "local colour" illusions. The three identified points are all of the same colour.

The penumbra code is a bit of a hack, as metapost has no transparency.

picture TeX[],checks[];
path p[],p[]trim[];
color shade[];
transform T[];

%need to draw grids with different light, dark cells, so a function for this
def gridpic(expr wd,ht, light, dark)=
    image(for i = 0 upto wd-1:
        for j = 0 upto ht-1:
            fill unitsquare shifted (i,j) withcolor if odd(i+j): dark else: light fi;
        endfor
    endfor)
    enddef;

% basic shades
shade0=0.3white;
shade1=0.5white;
shade2=0.8white;

% Geometry of shadow: M gradations to penumbra, and each gradation has N offset copies of shadow
M:=10;
N:=36;
shadow_ysc:=1.8;    % stretched y-wise this much
shadow_ysc.blur:=0.15;
shadow_slant:=0.21; % slanted by this ratio
shadow_slant.blur:=0.05;

% set up picture and extract paths
TeX0=btex \bf\TeX etex;
_i:=1;
for $ within TeX0:
    p[_i]=pathpart glyph (textpart $) of (fontpart $) scaled 1/100 shifted llcorner $;
    _i:=_i+1;
endfor

% paths overlap, so extract subpaths to join back together
p1trim0=subpath (-1,length(p1)-2) of p1 cutbefore  p2 cutafter  p2;
p2trim0=subpath (1.1,length(p2)-.1) of p2 cutbefore p3 cutafter (subpath (-1,0) of p1);
p2trim1=subpath (1.1,length(p2)-.1) of p2 cutbefore p1 cutafter p3;
p3trim0=p3 cutafter subpath(1,2) of p2;
p3trim1=(subpath (2,infinity) of cuttings) cutbefore subpath(0,-1) of p2;
p0trim0=p1trim0--p2trim1--p3trim1--p3trim0--p2trim0--cycle;
p0=p0trim0 shifted -llcorner p0trim0 scaled 0.13 shifted (0.12,0.06);

% set up affine transforms for 4 different planes
% T0 maps to top of box and T1 maps to floating text
origin transformed T0=origin transformed T1=origin;
right transformed T0=right transformed T1=5cm*dir(-10);
up transformed T0=3cm*dir(20);
up transformed T1=5cm*up;
% T2 maps to front of box
(0,1) transformed T2=(0,-1) transformed T0;
(1,1) transformed T2=(1,-1) transformed T0;
(0,1) transformed T2=origin transformed T2+.5((up transformed T1)-(origin transformed T1));
% T3 maps to right of box
(0,1) transformed T3=(4,3) transformed T0;
(1,1) transformed T3=(4,2) transformed T0;
(0,1) transformed T3=origin transformed T3+(up transformed T2)-(origin transformed T2);

beginfig(1)
    % first draw grid without shadow
    draw gridpic(4,4,shade2,shade1) shifted (0,-1) transformed T0;
    % then successively darker parts of grid (multiple copies, as penumbra is blurred)
    for j = M-1 downto 1:
        checks0:=gridpic(4,4,(j/M)[shade1,shade2],(j/M)[shade0,shade1]) shifted (0,-1) transformed T0;
        for i = 0 upto N-1:
            checks1:=checks0;
            clip checks1 to
                p0 yscaled (shadow_ysc+shadow_ysc.blur*(j/M)*cosd(i/N*360))
                    slanted (shadow_slant+shadow_slant.blur*(j/M)*sind(i/N*360))
                    transformed T0;
            draw checks1;
        endfor
    endfor
    % finally, the actual shadow
    checks1:=gridpic(4,4,shade1,shade0) shifted (0,-1) transformed T0;
    clip checks1 to (p0 yscaled shadow_ysc slanted shadow_slant transformed T0);
    draw checks1;
    % floating text, repeated a few times to fake 3D
    for i = 3/4 step -1/16 until 0:
        fill p0 transformed T1 shifted ((0,i/10) transformed T0)  withcolor (i if i>0:+.2 fi)[(.8,.9,1),shade0];
    endfor
    % front and side of box
    draw gridpic(4,1,.3[shade2,white],.3[shade1,white]) transformed T2;
    draw gridpic(4,1,shade1,shade0) transformed T3;
    % identify three areas all of color shade1, even if they don't look it
    z0=(2.5,1.5) transformed T0;
    z1=(3.5,-0.5) transformed T0;
    z2=(2.5,0.5) transformed T3;
    for i = 0 upto 2:
        draw fullcircle scaled 6mm shifted z[i] withcolor shade2;
    endfor
%   uncomment this if you are not convinced:
%   fill z0..tension 4..z1..tension 4..z2..tension 4..cycle withcolor shade1;
endfig;

bye

enter image description here

1
  • Very impressive with shadowing effect of MetaPost. Can Asymptote do that?
    – Black Mild
    Apr 14, 2019 at 15:13
26

With PSTricks.

\documentclass[pstricks,border=12pt]{standalone}
\SpecialCoor
\def\Less(#1,#2){\psline[origin={#1,#2}](1;30)(0,0)(1;-30)}
\def\Greater(#1,#2){\psline[origin={#1,#2}](1;150)(0,0)(1;-150)}

\begin{document}
\begin{pspicture}(-4,-3)(4,3)
    \psline(-2,2)(2,2)
    \Less(-2,2)
    \Greater(2,2)
    %
    \psline(-2,-2)(2,-2)
    \Less(2,-2)
    \Greater(-2,-2)
\end{pspicture}
\end{document}

enter image description here

1
  • 3
    I was missing your answer :-) Sep 3, 2013 at 22:49
23

Beautiful curved grid?

A variant and a combination of Hering's and Zöllner's illusion. The red grid is completely straight all the time.

enter image description here

Code

\documentclass[border=10pt,tikz]{standalone}
\pagecolor{gray!5}
\begin{document}
    \begin{tikzpicture}[x=4cm,y=4cm,every rectangle node/.style={draw,thick,red,rotate=45,minimum width=0.707*4cm,minimum height=0.707*4cm}]
        \foreach \y in {1,...,3}
            \foreach \x in {1,...,3}{%
                \foreach \diameter in {1,...,6}
                    \draw[gray,thick] (\x,\y) circle (1/12*\diameter);
                \node[rectangle] at (\x,\y) {};
            }
    \end{tikzpicture}
\end{document}

A great website with optical illusions can be found here.

21

enter image description here

Demonstration of the physiological blind spot in our vision, see wiki for details.

Edit Apparently, the wiki link was not enough, some comments are due. Every eye has a blind spot, which presence can be discovered only with the other eye closed. Demonstration of the blind spot in the wiki uses just two letters, R and L one is used to focus on, the other as an object to disappear from the sight. The image above improves the demonstration and allows to estimate a size of the blind spot, since while the blue ball disappears, the big red ring stays visible.

Instructions: Close one eye and focus the other on the appropriate small green ball. Place your eye a distance from the screen (or maybe better to use a printed version) approximately equal to 3x the distance between the green and the blue ball. Move your eye towards or away from the screen until you see the blue ball inside a red ring disappear. For example, close your right eye, look at the Left eye green ball with your left eye, and the blue ball will disappear from within the big red ring.

% lusion.tex:
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}

\begin{document}
\begin{figure}
\begin{asy}
unitsize(2mm);

real r0,r1,r2,r3;
r0=1;
r1=4;
r2=10;
r3=15;
pair O=(0,0);
pair dotC=(2r3,0);

void ball(pair c,real r1,real r2=0.07r1,pen p1,pen p2){
  radialshade(circle(c,r1), p1,c,r2,p2,c,r1); 
}

ball(O,r3,r2,white,red);
fill(circle(O,r2),white);
ball(O,r1,white,darkblue);

ball(-dotC,r0,lightgreen,darkgreen);
ball(dotC,r0,lightgreen,darkgreen);

defaultpen(fontsize(10pt));
label("Right eye",-dotC,2N);
label("Left eye",dotC,2N);
\end{asy}
\caption{Demonstration of the blind spot}
\end{figure}
\end{document}

% To process it with `latexmk`, create file `latexmkrc`:
% 
%     sub asy {return system("asy '$_[0]'");}
%     add_cus_dep("asy","eps",0,"asy");
%     add_cus_dep("asy","pdf",0,"asy");
%     add_cus_dep("asy","tex",0,"asy");
% 
% and run `latexmk -pdf lusion.tex`.
8
  • 4
    I cannot control my left eye to see the right green ball and my right eye to see the left green ball at the same time. Sep 4, 2013 at 0:54
  • 1
    @PSTikZ: OMG, you tried what?! I haven't heard anything that funny for quite a while, you made my day :) It's my bad, I should add the instructions, I just thought the wiki link would be enough. See the instructions added.
    – g.kov
    Sep 4, 2013 at 9:37
  • 4
    I wasn't able to move my eye towards the screen, since my eye is fixed inside my eye socket. ;)
    – Sverre
    Sep 4, 2013 at 10:13
  • @Sverre: :) It would be more convenient to print the picture (could be B/W, colors are not important here) and move the paper sheet instead.
    – g.kov
    Sep 4, 2013 at 11:08
  • I don't know about that. I could easily find my blind spots by moving my head. Pretty cool.
    – Sverre
    Sep 4, 2013 at 11:33
21

I don't know the name of this illusion but the important thing is that it is about simple harmonic motion of equally-spaced points with equally-spaced phase difference. The same code was posted here.

How to enjoy?

Remove the yellow lines and you see as if the collection of white dots on a wheel roll on inner part of a big circle.

enter image description here

\documentclass[preview,border=12pt,multi]{standalone}
\usepackage{pstricks}

\psset{unit=.3}

% static point
% #1 : half of the number of points
% #2 : ith point
\def\x[#1,#2]{(3*cos(Pi/#1*#2))}
\def\y[#1,#2]{(3*sin(Pi/#1*#2))}

% oscillated point
% #1 : half of the number of points
% #2 : ith point
% #3 : time parameter
\def\X[#1,#2]#3{(\x[#1,#2]*cos(#3+Pi/#1*#2))}
\def\Y[#1,#2]#3{(\y[#1,#2]*cos(#3+Pi/#1*#2))}

% single frame
% #1 : half of the number of points
% #2 : time parameter
\def\Frame#1#2{%
\begin{pspicture}(-3,-3)(3,3)
    \pstVerb{/I2P {AlgParser cvx exec} bind def}%
    \pscircle*{\dimexpr3\psunit+2pt\relax}
    \foreach \i in {1,...,#1}{\psline[linecolor=yellow](!\x[#1,\i] I2P \y[#1,\i] I2P)(!\x[#1,\i] I2P neg \y[#1,\i] I2P neg)}
    \foreach \i in {1,...,#1}{\pscircle*[linecolor=white](!\X[#1,\i]{#2} I2P \Y[#1,\i]{#2} I2P){2pt}}   
\end{pspicture}}

\begin{document}
\foreach \t in {0,...,24}
{   
    \preview
    \Frame{1}{2*Pi*\t/25} \quad \Frame{2}{2*Pi*\t/25} \quad \Frame{3}{2*Pi*\t/25} \quad \Frame{5}{2*Pi*\t/25} \quad \Frame{10}{2*Pi*\t/25}
    \endpreview
}
\end{document}
17

Here is an autostereogram coded in TeX. If you've never heard of autostereograms, be aware that seeing anything other than random glyphs may require some practice on your part :)

Reference: Reinhard Fößmeier's Tugboat article.

enter image description here

\pdfpagewidth=300 true mm
\hsize= 250 true mm
\pdfpageheight=350 true mm
\newcount\alt
\def\Pixel#1{%
    \def\Head##1##2!{##1}%
    \def\Tail##1##2!{##2}%
    \edef\A{\expandafter\Head\Pat!}%
    \edef\Rest{\expandafter\Tail\Pat!}%
    \edef\T{\Rest}%
    \alt=#1
    \loop\ifnum\alt>0
    \edef\A{\expandafter\Head\T!}%
    \edef\T{\expandafter\Tail\T!}%
    \advance\alt -1%
    \repeat%
    \edef\Pat{\Rest\A}%
    \A%
}
\def\Line#1{%
    \if #1;\vskip0pt\else%
        \Pixel#1\Pixel#1%
        \expandafter\Line%
    \fi
}
\def\Dline#1;{%
    \edef\Pat{\StartPattern}%
    \Line#1;\Line#1;%
}
\edef\StartPattern{A-Cel'+MX-/()pd=}
\tt
\Dline 0000000000000000000000000000000000000000000000000000000;
\Dline 0000000000000000000000000000000000000000000000000000000;
\Dline 0000000000000000000001111111111111000000000000000000000;
\Dline 0000000000000000011111111111111111111100000000000000000;
\Dline 0000000000000011111111111111111111111111100000000000000;
\Dline 0000000000001111111111111111111111111111111000000000000;
\Dline 0000000000011111111000001111111100000111111100000000000;
\Dline 0000000000111111110000000111111000000011111110000000000;
\Dline 0000000001111111110000000111111000000011111111000000000;
\Dline 0000000011111111111000001111111100000111111111100000000;
\Dline 0000000011111111111111111111111111111111111111100000000;
\Dline 0000000011111101111111111111111111111111011111100000000;
\Dline 0000000001111100111111111111111111111110011111000000000;
\Dline 0000000000111110011111111111111111111100111110000000000;
\Dline 0000000000011111100111111111111111110011111100000000000;
\Dline 0000000000001111111100011111111110001111111000000000000;
\Dline 0000000000000011111111100000000001111111100000000000000;
\Dline 0000000000000000011111111111111111111100000000000000000;
\Dline 0000000000000000000001111111111111000000000000000000000;
\Dline 0000000000000000000000000000000000000000000000000000000;
\Dline 0000000000000000000000000000000000000000000000000000000;
\bye
2
  • I am losing the left side of the image, as there is depth detail near the edge. Some L/R padding (manual or auto) will probably improve things. Dec 30, 2013 at 6:13
  • @AndrewKepert You're right. See my edit.
    – jub0bs
    Dec 30, 2013 at 10:12
16

Without PSTricks.

I don't know whether or not the following can be regarded as an optical illusion. The extra delay in trying to say the word when it's colored differently is known as the Stroop effect.

\documentclass[preview,border=12pt,varwidth,dvipsnames]{standalone}
\usepackage{xcolor}
\begin{document}
Speak loudly and quickly the color for each item below:
\Huge\bf
\begin{itemize}
    \item \textcolor{red}{Black}
    \item \textcolor{blue}{Red}
    \item \textcolor{yellow}{Green}
    \item \textcolor{green}{Magenta}
    \item \textcolor{cyan}{Pink}
    \item \textcolor{black}{Cyan}
    \item \textcolor{red}{Blue}
    \item \textcolor{yellow}{Maroon}
    \item \textcolor{orange}{Magenta}
    \item \textcolor{red}{Yellow}
\end{itemize}
\end{document}

enter image description here

3
  • 2
    Children who have not learnt reading can speak the color faster than you! So stop underestimating them! Nov 6, 2013 at 16:22
  • 3
    How do you speak laudly?
    – cfr
    May 17, 2016 at 1:32
  • @cfr Probably a mashup of German »laut« and English »loudly«. Jul 15, 2016 at 12:03
16

Shaded (identical) circles on shaded background.

enter image description here

Same circles on white background.

enter image description here

Asymptote code:

// shaded-circles.asy
//
settings.outformat="pdf";
size(8cm);
pen pena=red, penb=yellow;
pair a=plain.SW, b=plain.NE;
picture pic;
axialshade(box((-2,-2),(2,2)), pena, 3a, penb, 3b);
axialshade(pic, unitcircle, pena, 2a, penb, 2b);
add(shift(-1,0)*pic);
add(shift( 1,0)*pic);
14

A four colors illusion (with orange, magenta, light blue and light green)... made with three colors (with orange, magenta and bluegreen).

(other examples are here.)

enter image description here

\documentclass[tikz,margin=0mm]{standalone}

\definecolor{vertbleu}{rgb}{0,1,0.58}
\definecolor{orange}{rgb}{1,0.58,0}
\definecolor{magenta}{rgb}{1,0,1}
\begin{document}
\begin{tikzpicture}
   \def\myh{0.2}
   \def\nblines{30}

   \fill[vertbleu] (0,\myh*2) rectangle +(3,\nblines*\myh*2);
   \fill[vertbleu] (6,\myh*2) rectangle +(3,\nblines*\myh*2);
   \fill[vertbleu] (12,\myh*2) rectangle +(3,\nblines*\myh*2);
   \fill[vertbleu] (18,\myh*2) rectangle +(3,\nblines*\myh*2);

   \foreach \p in {1,...,\nblines}{
     \fill[orange] (0,\p*\myh*2) rectangle +(6,\myh);
     \fill[magenta] (3,\p*\myh*2+\myh) rectangle +(9,\myh);
     \fill[orange] (9,\p*\myh*2) rectangle +(9,\myh);
     \fill[magenta] (15,\p*\myh*2+\myh) rectangle +(6,\myh);
   }
\end{tikzpicture}
5

This was done a while ago, code may need to be updated

http://blancosilva.github.io/post/2011/09/26/opart.html

enter image description here

The following explanations are copied from the website:

Let us start by creating squares with both patterns. Notice that there is actually a single pattern, which is rotated 90º:

\def\squareL#1#2#3{
  \pgfmathparse{#1*8}
  \let\steps\pgfmathresult
  \begin{scope}
    \clip(#2,#3) rectangle (#2+#1,#3+#1);
    \filldraw[white] (#2,#3) rectangle (#2+#1,#3+#1);
    \foreach \step in {0,...,\steps}
      \draw[ultra thick] (#2+0.25*\step,#3) -- (#2,#3+0.25*\step);
  \end{scope}
}
\def\squareR#1#2#3{
  \pgfmathparse{#1*8}
  \let\steps\pgfmathresult
  \begin{scope}
    \clip(#2,#3) rectangle (#2+#1,#3+#1);
    \filldraw[white] (#2,#3) rectangle (#2+#1,#3+#1);
    \foreach \step in {0,...,\steps}
      \draw[ultra thick] (#2-#1+0.25*\step, #3) -- (#2+#1,#3+2*#1-2*#1*\step/\steps);
  \end{scope}
}



\begin{tikzpicture}
  \squareL{5}{0}{0}
\end{tikzpicture}

In both cases, we coded the square as a function of three variables: the size, and the location (as a point (x,y) in the canvas). For example, (inside of a tikzpicture environment) the command \squareL{5}{0}{0} places a square with one of the patterns, and this square will have corners at the origin and the points (0,5),(5,0) and (5,5).

single pattern

Notice how this pattern alone starts producing that optical effect by itself. Let us change the pattern in consecutive steps, including two more concentric squares inside of this one, like so:

\begin{tikzpicture}
  \squareL{5}{0}{0}
  \squareR{3}{1}{1}
  \squareL{1}{2}{2}
\end{tikzpicture}

combined pattern

For a stronger effect, combine several of these in a bigger image, taking advantage of the \foreach command:

\documentclass[tikz]{standalone}

\def\squareL#1#2#3{
  \pgfmathparse{#1*8}
  \let\steps\pgfmathresult
  \begin{scope}
    \clip(#2,#3) rectangle (#2+#1,#3+#1);
    \filldraw[white] (#2,#3) rectangle (#2+#1,#3+#1);
    \foreach \step in {0,...,\steps}
      \draw[ultra thick] (#2+0.25*\step,#3) -- (#2,#3+0.25*\step);
  \end{scope}
}
\def\squareR#1#2#3{
  \pgfmathparse{#1*8}
  \let\steps\pgfmathresult
  \begin{scope}
    \clip(#2,#3) rectangle (#2+#1,#3+#1);
    \filldraw[white] (#2,#3) rectangle (#2+#1,#3+#1);
    \foreach \step in {0,...,\steps}
      \draw[ultra thick] (#2-#1+0.25*\step, #3) -- (#2+#1,#3+2*#1-2*#1*\step/\steps);
  \end{scope}
}
\begin{document}
\begin{tikzpicture}
  \squareL{13}{0}{0}
  \foreach \a in {1,5,9}
  {
    \foreach \b in {1,5,9}
    { \squareR{3}{\a}{\b} }}

  \foreach \a in {2,6,10}
  {
    \foreach \b in {2,6,10}
    { \squareL{1}{\a}{\b} }}
\end{tikzpicture}

\end{document}

strong effect

3
  • 1
    It's beautiful and so is the internet link. Congratulations!
    – AndréC
    Jan 4, 2019 at 11:42
  • 1
    Could you maybe add the code to your answer? This would ensure that the post will still be useful for future users even in case the link goes down. Jan 4, 2019 at 11:52
  • @samcarter I took the liberty of doing it myself, I hope it will not be a problem.
    – AndréC
    Jan 20, 2019 at 9:21
3

Two dancer Illusion

enter image description here

\documentclass[pstricks]{standalone}
\def\right{%
    \rput{30}(5,5){\psparabola(-3,3)(0,0)}
    \qdisk(4.5,6){.4}
    \psbezier(4.5,4.8)(3,0)(7,-2)(7,-6)
    \psarc(7,-7){5.5}{110}{170}}

\begin{document}
\pspicture[linewidth=5pt](-8,-7)(8,10)
\right\psscalebox{-1 1}{\right}
\endpspicture
\end{document}
3
  • 1
    Don't blame this illusion if your mind is dirty. Jan 20, 2019 at 5:32
  • Yes, I like its symmetry....
    – user173875
    Jan 20, 2019 at 7:01
  • 1
    @chishimotoji: You can use this diagram when you teach mathematics about symmetry. Jan 20, 2019 at 7:11
2

I have enhanced @osjerick's response by making the illustration dynamic. You can now adjust the number of squares both vertically and horizontally, along with their heights and widths, and more. I hope you find it appealing.

The result

The code

\documentclass[tikz]{standalone}

\begin{document}

\def\ncolumns{6}
\def\nrows{9}
\def\width{1}
\def\height{1}
\def\phaseShift{4}
\pgfmathsetmacro\offset{2/\phaseShift} % Tweaking might
                % be necessary to achieve a good result.
\definecolor{customgray}{HTML}{808080}

\begin{tikzpicture}
  \filldraw[color=customgray]
  (-\offset/2+\width*2,{\height*(\nrows+1)}) rectangle (\offset/2+2*\width,\height);
  \filldraw[color=customgray] (-\offset/2+\width*2*\ncolumns+\width,\height)
    rectangle (\offset/2+\width*2*\ncolumns+\width,{\height*(\nrows+1)});

    \foreach \y in {1,2,...,\nrows}
    {
        \pgfmathsetmacro\X{sin(2.5*36*(\y-1))/\phaseShift}
        \foreach \x in {1,2,...,\ncolumns}
        {
            \filldraw (\width*2*\x+\X, \y*\height)
            rectangle +(\width, \height);
        }
        \ifnum\y=1
        \else
        \draw[
          color=customgray,
          line width = \height * 0.25 mm
          ] 
          (-\offset/2+2*\width,\y*\height) -- (\offset/2+\width*2*\ncolumns+\width,
            \y*\height);
        \fi
    }
\end{tikzpicture}

\end{document}
1

Accidentally run into this 3d flip-flop illusion:

enter image description here

// 
// curvedIllusion.asy 
// 
// run 
//   asy -f png -noprc -render=4 curvedIllusion.asy
// to get a standalone curvedIllusion.png
// 
import three;
size(200,0);
currentprojection=
  orthographic(camera=(7,-70,20),zoom=0.8);
guide g=(0, 0){dir(45)}..(1, 1){dir( 0)}
      ..(3,-1){dir( 0)}..(4, 0){dir(45)};
surface s=extrude(g,3*Z);
draw(s,lightgreen,meshpen=nullpen,render(merge=true));

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .