Answer
i think that it can be done with mathematica; by just finding the "right" function.
Yes, and you have found the right function. (RandomMandala
from the Wolfram Function Repository.)
In short, any doodles you want to use have to be expressed in terms of graphics primitives and be put within a seed generation function. (With a signature that fits the RandomMandala
framework.)
For example, using doodles produced with the code:
(BezierCurve@RandomPoint[Disk[{0, 0}, #1, {0, #2}], 9] &) // Graphics[{Thick, #[1, \[Pi]/4]}] &
we can make make mandalas seeded by them through the option "SeedFunction":
SeedRandom[12];
Table[ResourceFunction["RandomMandala"][
"RotationalSymmetryOrder" -> RandomChoice[{3, 6, 12}],
"SeedFunction" -> (BezierCurve@RandomPoint[Disk[{0, 0}, #1, {0, #2}], 9] &)],
5]
Below I show how to use fragments of images in the mandala making process.
Procedure outline
Here is an outline of the procedure we follow below:
Transform one of the given images and extract its components
Convert the components into point coordinates and rescale them to be within $[0,1]$
Make mandala seed function with arguments radius
and angle
:*
Selects points to be within the unit disc sector that corresponds $[0, angle]$
Scales the selected points with radius
Makes Graphics
points
Plot mandalas of with the defined mandala seed function
Code and walk-through
First let us transform one of the given images and extract its components:
img1d = Dilation[EdgeDetect[img1], 0.6];
mcs1 = MorphologicalComponents[Thinning[img1d], 0.01];
Colorize@mcs1
Here is an association for each component with its corresponding points:
aCompCoords = Association[# -> Position[mcs1, #] & /@ Rest[Union[Flatten[mcs1]]]];
Length[aCompCoords]
Length /@ aCompCoords
(*30*)
(*<|1 -> 24462, 2 -> 168, 3 -> 158, 4 -> 161, 5 -> 73, 6 -> 73, 7 -> 156, 8 -> 69, 9 -> 66, 10 -> 163, 11 -> 68, 12 -> 102, 13 -> 63,14 -> 63, 15 -> 149, 16 -> 157, 17 -> 160, 18 -> 159, 19 -> 72, 20 -> 63, 21 -> 74, 22 -> 156, 23 -> 159, 24 -> 69, 25 -> 65, 26 -> 158, 27 -> 73, 28 -> 72, 29 -> 163, 30 -> 164|>*)
Rescale the obtained point coordinates:
aCompCoords2 = AssociationThread[Keys[aCompCoords], Values[aCompCoords] /. {x_?NumberQ :> Rescale[x, {ImageDimensions[img1][[1]]/2, ImageDimensions[img1][[1]]}, {0, 1}]}];
Remark: I prefer to use direct rescaling instead of using GeometricTransformation
and ScalingTransform
because computations are faster and the data is "readily" interpretable.
Here we define the mandala seed generating function that uses extracted graphical elements of the given mandala image:
Clear[MandalaImageSegment]
Options[MandalaImageSegment] = {"ComponentCoordinates" -> aCompCoords2, "MaxComponentSize" -> 30000, "ShowLargeComponents" -> False};
MandalaImageSegment[radius_, angle_, args___, opts : OptionsPattern[]] :=
Block[{reg, regf, aCompCoords, aCompCoordsIn, maxSize, showLargeOnes},
showLargeOnes = TrueQ[OptionValue[MandalaImageSegment, "ShowLargeComponents"]];
maxSize = OptionValue[MandalaImageSegment, "MaxComponentSize"];
aCompCoords = OptionValue[MandalaImageSegment, "ComponentCoordinates"];
reg = Disk[{0, 0}, 1, {0, angle}];
regf = RegionMember[reg];
aCompCoordsIn = Map[Pick[#, regf[#]] & /@ # &, aCompCoords];
aCompCoordsIn = radius*aCompCoordsIn;
If[showLargeOnes,
{Map[Point, Values[Select[aCompCoordsIn, Length[#] <= maxSize &]]], {PointSize[0.005], Opacity[0.2], Map[Point, Values[Select[aCompCoordsIn, Length[#] > maxSize &]]]}},
(*ELSE*)
{PointSize[0.005], Opacity[0.8], Map[Point, Values[Select[aCompCoordsIn, Length[#] <= maxSize &]]]}
]
];
Here is how the seed segment looks like for the angle $\pi /6$:
Graphics[MandalaImageSegment[1, \[Pi]/6, "ComponentCoordinates" -> N[aCompCoords2], "MaxComponentSize" -> 500, "ShowLargeComponents" -> True], Frame -> True]
Finally, here are mandalas with the defined mandala seed function:
Grid@Table[
ResourceFunction["RandomMandala"]["Radius" -> 10, "RotationalSymmetryOrder" -> rs, "SeedFunction" -> (MandalaImageSegment[##, "MaxComponentSize" -> 500, "ShowLargeComponents" -> show] &), PlotLabel -> rs], {show, {False, True}}, {rs, {5, 6, 4}}]
Here is a multi-mandala mode example:
SeedRandom[33];
ResourceFunction["RandomMandala"]["Radius" -> {10, 10}, "RotationalSymmetryOrder" -> {12, 6}, ColorFunction -> "Rainbow", "SeedFunction" -> (MandalaImageSegment[##, "MaxComponentSize" -> 2000, "ShowLargeComponents" -> False] &)]