How do you achieve this optical illusion of a picture?

In MSE by a similar problem about the optical illusion, but I feel that the solution ideas of other problems can not be applied to the following diagram, I would like to ask you how to draw this kind of diagram? I don't have any ideas.

• Welcome to Mathematica StackExchange! It is expected that you show some work of your own when posting a question. For example, looking at this image, you can see that it is composed of: (1) blue background, (2) pink heart, (3) rectangular grid, which has alternated black and white diagonals, (4) small half-white-half-black squares, rotated by 45 degrees. All of this can be produced in Mathematica. Take a look at Graphics and Rectangle. Oct 20, 2023 at 15:25
• @Abel: Can you provide the source of your image and what is the name of the illusion or who is the author? Oct 21, 2023 at 12:31
• I'm sorry about this one, but I stumbled upon it earlier by brushing up on a social media platform and saved it because I thought it was more interesting and didn't pay attention to the author's source.@azerbajdzan
– Abel
Oct 22, 2023 at 13:49
• What is the illusion? I don't see any. The only thing sort of "illusiony" is that scrolling over the images using the standard scrollbars seem to sort of move it around, but it's not particularly pronounced.
– DRF
Oct 22, 2023 at 19:09
• For me personally I can feel some movement in the pink heart, maybe that's the 'optical illusion' of the title? @DRF Oct 23, 2023 at 13:02

The image in blue and pink has been overlayed with small boxes in black and white. At the cordners of each box protrudes a line with same color as the corner half way to the next box. Every second box in x and y direction is rotated by 180° and in addition in the pink area by another 90°.

im = Image[ImagePad[Binarize[
], 50, 1], ImageResolution -> 72];

ClearAll[box]
box[x_, y_, d_:1, s_:0.17] := Translate[{
Black,
Polygon[(Plus[d])*{{0, s}, {s, 0}, {s, -s}/2, {-s, s}/2}],
Line[d*{{0, s}, {0, 0.5}}],
Line[d*{{s, 0}, {0.5, 0}}],
White,
Polygon[(-d)*{{0, s}, {s, 0}, {s, -s}/2, {-s, s}/2}],
Line[(-d)*{{0, s}, {0, 0.5}}],
Line[(-d)*{{s, 0}, {0.5, 0}}]
}, {x, y}]

dat = Transpose[Reverse[ImageData[im]]];
{px, py} = Dimensions[dat]
n = 20;

boxes = Table[Module[{
x = (i - 1) / (n - 1) * px,
y = (j - 1) / (n - 1) * py
},
phi = Pi/2 +
Pi * Mod[i + j, 2] +
Pi / 2 *dat[[Round[i * px / n],Round[j * py / n]]];
Rotate[box[x, y, px / (n - 1)], phi]
], {i, n}, {j, n}];

Graphics[{
ColorReplace[im, {
0 -> RGBColor[1, 0.6, 0.8],
1 -> RGBColor[0.4, 0.8, 1]
}],
boxes
}, ImageSize -> 800]


• Cool! But this image has a flaw: parts of the blue region appears to belong to the elevated pink region: Specifically, immediately below the cat's face, a bit to the left and right (especially to the left). Maybe this is caused by the presence of a few black and white squares surrounded by blue faces that are aligned -45 deg instead of the expected +45 deg in the blue layer. Oct 21, 2023 at 12:32
• @AndreasRejbrand Also note that in the example, the vertical lines in the overlay switch color precisely on borders between blue and pink, where in this result it happens exactly halfway across the lines in areas that are more or less directly underneath a border. (@azerbajdzan's solution does this correctly, except on the horizontal lines instead.) Oct 21, 2023 at 20:34

I'll post the code tomorrow, it's a bit of a mess at the moment.

Here is the code with abusing of GriGraph for a little piece of art.

n = 11;
r = {{-(1/2), 0}, {1/2, 0}, {1/2, 1/2}, {-(1/2), 1/2}};
{c1, c2} = {RGBColor[0.4, 0.8, 1], RGBColor[1, 0.6, 0.8]};
vs[fi_, r_] :=
Graphics[{Black, Polygon[RotationMatrix[fi] . # & /@ (-r)], White,
Polygon[RotationMatrix[fi] . # & /@ r]}];

g = GridGraph[{2 n + 1, 2 n + 1}, EdgeStyle -> Black,
VertexShape -> {Alternatives @@ Range[1, (2 n + 1)^2, 2] ->
vs[-π/4, r],
Alternatives @@ Range[2, (2 n + 1)^2, 2] -> vs[3 π/4, r]},
VertexSize -> 0.4, Background -> c1, ImageSize -> 720];
AnnotationValue[g,
EdgeStyle] = {Alternatives @@ Select[EdgeList[g], OddQ[#[[1]]] &] ->
White};

h = GridGraph[{2 n + 1, 2 n + 1}, EdgeStyle -> Black,
VertexShape -> {Alternatives @@ Range[1, (2 n + 1)^2, 2] ->
vs[π/4, r],
Alternatives @@ Range[2, (2 n + 1)^2, 2] -> vs[-3 π/4, r]},
VertexSize -> 0.4, Background -> c2, ImageSize -> 720];
AnnotationValue[h,
VertexCoordinates] = {2 n +
2 - #[[1]], #[[2]]} & /@ (AnnotationValue[{h, #},
VertexCoordinates] & /@ Range[(2 n + 1)^2]);
AnnotationValue[h,
EdgeStyle] = {Alternatives @@ Select[EdgeList[g], OddQ[#[[1]]] &] ->
White};

im = ColorNegate@
Graphics[{Disk[], White, Disk[{-0.32, 0.54}, 1/5],
Disk[{0.32, 0.54}, 1/5],
Disk[{0, -0.15}, 3/5, {π, 2 π}]}, PlotRange -> 1.25,
ImageSize -> 720];

ImageCompose[Image@g, SetAlphaChannel[Image@h, im]]


Just an alternative relying on image operations and using some emojis as input for testing purpose:

emoji = "🐬"(*"🐎"*)(*"🐖"*)(*"🐘"*);
imgSize = {800, 800};
colors = <|"back" -> RGBColor[0.4, 0.8, 1], "front" -> RGBColor[1, 0.6, 0.8]|>;
image = Image[ Rasterize@Magnify[emoji, 40] // Binarize // RemoveBackground //
ColorReplace[#, Black -> colors["front"]] &];
Inset[Graphics[image // ColorReplace[#, colors["front"] -> Black] &,
ImageSize -> imgSize], Center]}}, ImageSize -> imgSize], ImageResolution -> 500];

transform[image_, direction_ : "<" | ">", background_ : colors["back"], steps_ : 20] :=
Module[{size = 7},
colLineColor[x_, y_] := If[EvenQ[x + y], Black, White];
rowLineColor[x_, y_] :=
If[If[direction == "<", EvenQ, OddQ][x + y], Black, White];
theta = If[direction == "<", 45 °, 135 °];
Image[Graphics[{
{Inset[Graphics[image, ImageSize -> imgSize], Center]}
, Table[{
colLineColor[x, y]
, Line[{{x + 1,  y}, {x + 1 , Min[y + size, steps size]}}]
, rowLineColor[x, y]
, Line[{{x, y + 1}, {Min[x + size, steps size] , y + 1}}]
, Rotate[#[x, y], If[EvenQ[x + y], theta, theta + 180 °]] }
, {x, 0, steps size, size}, {y, 0, steps size, size}] &[
{x, y} |-> {White, Rectangle[{x, y}, {x + 1, y + 2}]
, Black, Rectangle[{x + 1, y}, {x + 2, y + 2}]}]}
, Background -> background, ImageSize -> imgSize], ImageResolution -> 500]]


(* Putting them together *)