Something I've wondered about a couple of times is how to "flatten" graphics in Mathematica. I don't know if this is really the right terminology, but the idea is that I have a bunch of semi-transparent objects inside a Graphics
object. They are visually layered from bottom to top based on the order the appear inside Graphics
, but I would like merge them down so that they're all in the same visual layer.
Here's an example:
Here's the code that produces the above image:
Module[{n, m, cols},
n = 9;
m = 20;
cols = Insert[#, First[#], 4] &[
RGBColor /@ {"#E45171", "#F8A79B", "#F8D99B", "#002C6A"}];
Graphics[
Table[{FaceForm[
Directive[Blend[cols[[;; 4]], \[Theta]/(2 \[Pi])], Opacity[.3]]],
EdgeForm[
Directive[Blend[cols[[;; 4]], \[Theta]/(2 \[Pi])],
Thickness[.004]]],
Polygon[Table[{Cos[\[Theta]] + Cos[\[Phi] + \[Theta]],
Sin[\[Theta]] + Sin[\[Phi] + \[Theta]]}, {\[Phi], 0,
2 \[Pi] - 2 \[Pi]/n, 2 \[Pi]/n}]]}, {\[Theta], 0,
2 \[Pi] - 2 \[Pi]/m, 2 \[Pi]/m}], PlotRange -> 3,
Background -> cols[[5]], ImageSize -> 540]]
Now, the problem with the image is that the individual 9-gons are not all visually at the same level. For example, the last entry in the table is the reddish 9-gon just below 3 o'clock in the image which clearly lies above all the other 9-gons. The question is: how do I get the final image to appear flat?
I can more or less achieve this using ImageMultiply
as follows:
imglist = Module[{n, m, cols},
n = 9;
m = 20;
cols =
Insert[#, First[#], 4] &[
RGBColor /@ {"#E45171", "#F8A79B", "#F8D99B", "#002C6A"}];
Table[Graphics[{FaceForm[
Directive[Blend[cols[[;; 4]], \[Theta]/(2 \[Pi])],
Opacity[.3]]],
EdgeForm[
Directive[Blend[cols[[;; 4]], \[Theta]/(2 \[Pi])],
Thickness[.004]]],
Polygon[Table[{Cos[\[Theta]] + Cos[\[Phi] + \[Theta]],
Sin[\[Theta]] + Sin[\[Phi] + \[Theta]]}, {\[Phi], 0,
2 \[Pi] - 2 \[Pi]/n, 2 \[Pi]/n}]]}, PlotRange -> 3,
Background -> White, ImageSize -> 540], {\[Theta], 0,
2 \[Pi] - 2 \[Pi]/m, 2 \[Pi]/m}]];
Fold[ImageMultiply, First[#], #[[2 ;;]]] &[imglist]
(I used essentially the same trick to make Opposites Attract)
A minor problem is that ImageMultiply
darkens all the colors (which could probably be gotten around by careful fiddling), but the big problem is that there's no way to do this trick with a colored or transparent background.
I assume there's some clever way to achieve this, so does anybody have any ideas?