# Vera Molnár's interruptions - erasing graphic elements

Vera Molnár

Vera Molnár (1924 - 2023) was a Hungarian artist who, like Victor Vasarely, lived and worked in France. She was one of the pioneers of computer graphics. Trained as a traditional artist, she produced combinatorial images from as early as 1959, "imagining I had a computer", a method she referred to as "machine imaginaire".

Vera Molnár in 1961

In 1968, Molnár created her first computer graphics, and in 1976 she developed "Molnart", a graphics software written in Fortran. Her work has been widely collected by major museums, including MoMA, Tate and Centre Pompidou. Vera Molnár died on 7 December 2023, at age 99.

"I have no regrets. My life is squares, triangles, lines", she once remarked.

Quatre éléments

One of Vera Molnár's first digital works, created in 1968, was "Quatre éléments distribués au hasard" ("Four randomly distributed elements").

Vera Molnár, Quatre éléments distribués au hasard, 1968

My replication attempt with Mathematica was surprisingly simple.

a = Line[{{i, j}, {i + 1, j + 1}}];
b = Line[{{i, j + 1}, {i + 1, j}}];
c = Line[{{i + 0.5, j}, {i + 0.5, j + 1}}];
d = Line[{{i, j + 0.5}, {i + 1, j + 0.5}}];

SeedRandom[0];

Framed[
Graphics[{
Thickness[0.0075],
Table[RandomChoice[{a, b, c, d}], {i, 25}, {j, 25}]},
Background -> GrayLevel[0.95]],
Background -> GrayLevel[0.95]]


Interruptions (1968-1969)

In this series, Molnár starts with a grid covered with straight lines of the same length, and applies a random rotation to each, generating a densely complex pattern. To this, she adds "interruptions", random sections in which certain lines are erased. "Interruptions", was produced with a mainframe computer using her own program, which she entered into punch cards and printed on a plotter.

Vera Molnár, Interruptions, 1968

To reproduce the lines wasn't too difficult, but I have no idea how to produce the random erasure patterns.

SeedRandom[0];

Framed[
Graphics[{
GrayLevel[0.0],
Thickness[0.002],
Table[
Rotate[
Line[{{i, j}, {i + 1.3, j + 1.3}}],
RandomInteger[{0, 180}] Degree],
{i, 40}, {j, 40}]}],
FrameStyle -> GrayLevel[0.8]]


My question

How can I "inject" the erased patterns? Please also have a look at the other works of the series interruptions to see what I would like to reproduce: One or two large erasures or several smaller ones. The problem is complicated by the fact, that erased areas might still contain small "islands" of lines.

• Thank you for making my morning browse that much more interesting 🙂 Feb 26 at 18:53
• You are most welcome, thanks for the upvote :)
– eldo
Feb 26 at 18:58

• We define the rotated lines by RotationTransform in order to keep the lines be the Region.

• We use RegionDisjoin to erase the lines.

Clear["Global*"];
SeedRandom[0];
lines = Flatten[
Table[RotationTransform[RandomInteger[{0, 180}]  Degree,
Mean[{{i, j}, {i + 1.3, j + 1.3}}]]@
Line[{{i, j}, {i + 1.3, j + 1.3}}], {i, 40}, {j, 40}], 1];
contour = BezierCurve[{{0, 20}, {10, 30}, {20, 20}, {10, 10}}];
reg = FilledCurve[contour] // BoundaryDiscretizeGraphics;
Graphics[{GrayLevel[0.0],
Thickness[0.002], {EdgeForm[Red], FaceForm[], reg},
Select[lines, RegionDisjoint[reg, #] &]}]


• Use random curve.
Clear["Global*"];
SeedRandom[0];
lines = Flatten[
Table[RotationTransform[RandomInteger[{0, 180}]  Degree,
Mean[{{i, j}, {i + 1.3, j + 1.3}}]]@
Line[{{i, j}, {i + 1.3, j + 1.3}}], {i, 40}, {j, 40}], 1];
contour = BezierCurve[RandomReal[{10, 30}, {100, 2}]];
reg = contour // DiscretizeGraphics;
Graphics[{GrayLevel[0.0], Thickness[0.002], {EdgeForm[], FaceForm[]},
Select[lines, RegionDisjoint[reg, #] &]}]


• Thank you, the second solution gives a Molnár-like result
– eldo
Feb 26 at 10:12

Here is an example using a random walk.

First we create all the lines. Then we delete lines along a random path:

SeedRandom[9];
n = 40;(*original number of lines: n^2*)
nd = 150; (*approx. number of deleted lines*)
dat = Table[
Rotate[Line[{{i, j}, {i + 1.3, j + 1.3}}],
RandomInteger[{0, 180}]  Degree], {i, n}, {j, n}];
pos = Round[Length[dat]/2] {1, 1};
getrand := {t = RandomReal[1, 2];
Which[t[[1]] < 0.4, -1, t[[1]] < 0.8, 1, True, 0],
Which[t[[2]] < 0.4, -1, t[[2]] < 0.8, 1, True, 0]};
Do[dat =
Delete[dat, pos += getrand;
If[pos[[1]] < 1 || pos[[1]] > Length[dat] , pos[[1]] = 1;
Continue[]];
If[pos[[2]] < 1 || pos[[2]] > Length[dat[[pos[[1]]]]],
pos[[2]] = 1; Continue[]]; pos], {i, nd}];

Framed[Graphics[{GrayLevel[0.0], Thickness[0.002], dat}],
FrameStyle -> GrayLevel[0.8]]


Further, you may broaden the random path. And you may play with SeedRandom to get different patterns.

Edit And trying to reproduce some of the interruptions ... :

by using:

interruptions2[rx_ : 1, ry_ : 2, n_ : 20, dx_ : 40, dy_ : 40 ] :=
Module[{e = 1.3, r = 3, f = .9, t = .03, pts, lines, scaled,
exclusions, img},
lines = Flatten[Table[{{i, j}, {i + e, j + e}}, {i, dx}, {j, dy}], 1];
img = Image[
Graphics[
Table[{Thickness[t],
Circle[RandomReal[dx, {2}], {RandomReal[rx],
RandomReal[ry]}]}, {n}]], ImageSize -> {100, 100}];
pts = PixelValuePositions[EdgeDetect[img, 2], 1];
scaled = Partition[Threaded[{r, r}] + f  dx   Rescale[pts], {2}];
exclusions = NearestTo[scaled, DistanceFunction -> ManhattanDistance]@lines;
Rotate[Line@#, RandomInteger[{0, 180}]   Degree] & /@ Select[lines, FreeQ[exclusions, #] &]]

Graphics[{GrayLevel[0.5],
interruptions2[1, 1, 20, 50, 50]
, Translate[interruptions2[.1, 4, 10, 50, 40], .5 + {22, 8} ]
, Translate[interruptions2[2, 1, 1, 50, 8], {62, 3} ]
, Translate[interruptions2[7, .2, 10, 50, 50], .5 + {82, 0} ]
}, ImageSize -> {1200, 800}]


Original: Just an alternative using NearestTo in order to filter out the lines based on the proximity to some exclusion points (edges of an image for example ..).

interruptions[pts_] := Module[{d = 40, r = 5, lines, scaledpts, exclusions},
lines = Flatten[Table[{{i, j}, {i + 1.3, j + 1.3}}, {i, d}, {j, d}] , 1];
scaledpts = Partition[
Threaded[RandomReal[{-r, r}, 2] + {d/4, d/4}] + d/2  Rescale[pts], {2}];
exclusions = NearestTo[scaledpts, DistanceFunction -> ManhattanDistance]@lines;
Graphics[Rotate[#, RandomInteger[{0, 180}]  Degree] & /@
Line /@ Select[lines, FreeQ[exclusions, #] &], ImageSize -> Small]]

Multicolumn[
interruptions@
PixelValuePositions[
EdgeDetect[Image@Rasterize@Magnify[#, 15], 1], 1] & /@
{"🐉", "🐧",  "🦣", "🌴", "🌿", "☘️"}, 3]