Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Exit

0

/t5/illustrator-discussions/help-with-design-please-fractals/td-p/14071968
Sep 08, 2023
Sep 08, 2023

Copy link to clipboard

Copied

Hi Everyone,

I have attached two files. Is there a way to recreate these patterns in illustrator?

I tried poking around to find some answers, but I wonder if I'm having trouble finding the right direction because I don't know what to call it.

Any help with this would be greatly appreciated.

Thank you so much

Matt

TOPICS

Draw and design
,
How-to
,
Scripting

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

Guide
,
Sep 10, 2023
Sep 10, 2023

Here's a script that draws a Sierpinski triangle that fits the open document. The number of recursions can be changed by changing the number of "levels" in line 2, although it is advised not to go too much above 10, otherwise Illustrator may become unresponsive. Adapted from: https://www.youtube.com/watch?v=e3Ll0_oxChU

```
function main() {
var level = 5;
var doc = app.activeDocument;
function drawTriangle(p1, p2, p3) {
var path1 = doc.pathItems.add();
path1.setEnti
```

...
16
Replies
16

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14072008#M379845
Sep 08, 2023
Sep 08, 2023

Copy link to clipboard

Copied

they are called Fractals

the first is called Apollonian Gasket

https://www.wikihow.com/Create-an-Apollonian-Gasket

the second is called Sierpinski Triangle

https://www.youtube.com/watch?v=j6WYSdHuWgY

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14072767#M379870
Sep 09, 2023
Sep 09, 2023

Copy link to clipboard

Copied

Carlos, thank you for the informative links.

Math is not my thing!!!

What I do know is that a hexagon divided into 6 equal segments= 6 equilateral triangles.

So to recreate this Sierpinski triangle, I created a seamless hexagon pattern.

Next Live Paint. I random recolor as I work.

Expand Live Paint. Pathfinder>Unite each unique color.

Recolor as you like.

Here is what it looks like with simple black and white.

K

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14072837#M379872
Sep 09, 2023
Sep 09, 2023

Copy link to clipboard

Copied

Community guidelines

Matt Sk
AUTHOR

Explorer
,

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14073345#M379903
Sep 09, 2023
Sep 09, 2023

Copy link to clipboard

Copied

Thank you so much for the clarity around WHAT they are. That is so helpful.

Creating the Sierpinski Triangle was pretty easy once the math was understood.

*The Apollonian Gasket is proving to be a little more challenging with exact placement to reproduce the same results. *

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14073442#M379908
Sep 09, 2023
Sep 09, 2023

Copy link to clipboard

Copied

usually these images are generated programmatically to place items precisely

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14074517#M379941
Sep 10, 2023
Sep 10, 2023

Copy link to clipboard

Copied

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14074705#M379949
Sep 10, 2023
Sep 10, 2023

Copy link to clipboard

Copied

Here's a script that draws a Sierpinski triangle that fits the open document. The number of recursions can be changed by changing the number of "levels" in line 2, although it is advised not to go too much above 10, otherwise Illustrator may become unresponsive. Adapted from: https://www.youtube.com/watch?v=e3Ll0_oxChU

```
function main() {
var level = 5;
var doc = app.activeDocument;
function drawTriangle(p1, p2, p3) {
var path1 = doc.pathItems.add();
path1.setEntirePath([p1, p2, p3, p1]);
path1.closed = true;
}
function getMidpoint(p1, p2) {
return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];
}
var Triangle = function(p1, p2, p3) {
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
this.draw = function() {
drawTriangle(this.p1, this.p2, this.p3);
}
}
function drawSierpinskiTriangle(tri, depth) {
if (depth == level) return;
var m1 = getMidpoint(tri.p1, tri.p2);
var m2 = getMidpoint(tri.p2, tri.p3);
var m3 = getMidpoint(tri.p3, tri.p1);
var t0 = new Triangle(m1, m2, m3);
t0.draw();
var t1 = new Triangle(tri.p1, m1, m3);
var t2 = new Triangle(tri.p2, m1, m2);
var t3 = new Triangle(tri.p3, m2, m3);
drawSierpinskiTriangle(t1, depth + 1);
drawSierpinskiTriangle(t2, depth + 1);
drawSierpinskiTriangle(t3, depth + 1);
}
var size = doc.width < doc.height ? doc.width : doc.height;
var t = new Triangle(
[size / 2, 0],
[0, -size],
[size, -size]
);
t.draw();
drawSierpinskiTriangle(t, 0);
}
main();
```

Community guidelines

Matt Sk
AUTHOR

Explorer
,

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14074805#M379953
Sep 10, 2023
Sep 10, 2023

Copy link to clipboard

Copied

How cool is that. Being able to write code to achieve the look!

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14077371#M380067
Sep 11, 2023
Sep 11, 2023

Copy link to clipboard

Copied

That's a very good approach, Femke.

I once created an action and a graphic style to create the triangle construction. Of course, it was insanely complicated.

Your script is way better and pretty fast.

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14077411#M380073
Sep 11, 2023
Sep 11, 2023

Copy link to clipboard

Copied

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14079555#M380180
Sep 12, 2023
Sep 12, 2023

Copy link to clipboard

Copied

@Ton Frederiks I've added a line that makes the paths closed.

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14080119#M380221
Sep 12, 2023
Sep 12, 2023

Copy link to clipboard

Copied

Thanks @femkeblanco I found that the new code indeed closed the paths, but created triangles with 4 points.

I am not a scripter but tried to change

`path1.setEntirePath([p1, p2, p3, p1]);`

into

`path1.setEntirePath([p1, p2, p3]);`

and to my surprise that worked.

Thanks again!

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14117099#M382090
Sep 27, 2023
Sep 27, 2023

Copy link to clipboard

Copied

And here's a script that draws three types of Apollonian gaskets. This is adapted from a browser script that is dependent on the size of the canvas. I've kept it at the same size (400 pt) so as to show the same results; they can be manually scaled.

```
// part 1: Complex class (manipulates complex numbers)
// abridged from Complex.js by Robert Eisele
// https://rawgit.com/infusion/Complex.js/master/complex.js
var parse = function (a, b) {
var z = {
're': 0,
'im': 0
};
if (a == undefined || a == null) {
z['re'] = z['im'] = 0;
} else if (b != undefined) {
z['re'] = a;
z['im'] = b;
} else
if (typeof a == 'object') {
z['re'] = a['re'];
z['im'] = a['im'];
} else if (typeof a == 'number') {
z['im'] = 0;
z['re'] = a;
}
return z;
};
var Complex = function (a, b) {
if (!(this instanceof Complex)) {
return new Complex(a, b);
}
var z = parse(a, b);
this['re'] = z['re'];
this['im'] = z['im'];
};
Complex.prototype = {
're': 0,
'im': 0,
'add': function(a, b) {
var z = new Complex(a, b);
return new Complex(
this['re'] + z['re'],
this['im'] + z['im']);
},
'sub': function(a, b) {
var z = new Complex(a, b);
return new Complex(
this['re'] - z['re'],
this['im'] - z['im']);
},
'mul': function(a, b) {
var z = new Complex(a, b);
if (z['im'] == 0 && this['im'] == 0) {
return new Complex(this['re'] * z['re'], 0);
}
return new Complex(
this['re'] * z['re'] - this['im'] * z['im'],
this['re'] * z['im'] + this['im'] * z['re']);
},
'div': function(a, b) {
var z = new Complex(a, b);
a = this['re'];
b = this['im'];
var c = z['re'];
var d = z['im'];
var t, x;
if (0 == d) {
return new Complex(a / c, b / c);
}
if (Math.abs(c) < Math.abs(d)) {
x = c / d;
t = c * x + d;
return new Complex(
(a * x + b) / t,
(b * x - a) / t);
} else {
x = d / c;
t = d * x + c;
return new Complex(
(a + b * x) / t,
(b - a * x) / t);
}
},
'sqrt': function() {
var a = this['re'];
var b = this['im'];
var r = this['abs']();
var re, im;
if (a >= 0) {
if (b == 0) {
return new Complex(Math.sqrt(a), 0);
}
re = 0.5 * Math.sqrt(2.0 * (r + a));
} else {
re = Math.abs(b) / Math.sqrt(2 * (r - a));
}
if (a <= 0) {
im = 0.5 * Math.sqrt(2.0 * (r - a));
} else {
im = Math.abs(b) / Math.sqrt(2 * (r + a));
}
return new Complex(re, b < 0 ? -im : im);
},
'abs': function() {
return Math.sqrt(this['re'] * this['re'] + this['im'] * this['im']);
}
};
// part 2: main
// adapted from Apollonian gasket by pimskie
// https://codepen.io/pimskie
var doc = app.activeDocument;
var DIM = 400;
var MID = DIM * 0.5;
var MIN_R = 2;
var Circle = function(r, center) {
this.r = r;
this.b = 1 / this.r;
this.center = center;
this.bc = this.center.mul(this.b);
};
var solveEquation = function(k1, k2, k3) {
var s = k1.add(k2).add(k3);
var k12 = k1.mul(k2);
var k13 = k1.mul(k3);
var k23 = k2.mul(k3);
var ksum = k12.add(k13).add(k23);
return ksum.sqrt().mul(2).add(s);
};
var getAdjacent = function(c1, c2, c3) {
var b1 = new Complex(c1.b);
var b2 = new Complex(c2.b);
var b3 = new Complex(c3.b);
var b4 = solveEquation(b1, b2, b3);
var r4 = Math.abs(1 / b4.re);
var pos4 = solveEquation(c1.bc, c2.bc, c3.bc).div(b4);
return new Circle(r4, pos4);
};
var flip = function(c4, c1, c2, c3) {
var bend = 2 * (c1.b + c2.b + c3.b) - c4.b;
var center = c1.bc.add(c2.bc).add(c3.bc).mul(2).sub(c4.bc).div(bend);
return new Circle(1 / bend, center);
};
var addCircle = function (circle) {
circles.push(circle);
};
var recurse = function(c1, c2, c3, c4, depth) {
depth = depth || 0;
var cn2 = flip(c2, c1, c3, c4);
var cn3 = flip(c3, c1, c2, c4);
var cn4 = flip(c4, c1, c2, c3);
if (cn2.r > MIN_R) {
addCircle(cn2);
recurse(cn2, c1, c3, c4, depth + 1);
}
if (cn3.r > MIN_R) {
addCircle(cn3);
recurse(cn3, c1, c2, c4, depth + 1);
}
if (cn4.r > MIN_R) {
addCircle(cn4);
recurse(cn4, c1, c2, c3, depth + 1);
}
};
var drawGasket = function(c1, c2, c3) {
var c4 = getAdjacent(c1, c2, c3);
var c5 = flip(c1, c2, c3, c4)
addCircle(c1);
addCircle(c2);
addCircle(c3);
addCircle(c4);
addCircle(c5);
recurse(c1, c2, c3, c4);
recurse(c5, c2, c3, c4);
};
var symmetricSet = function() {
var c1r = -MID;
var c1center = new Complex(MID, MID);
var c1 = new Circle(c1r, c1center);
var c2r = 100;
var c2center = new Complex(c2r, MID);
var c2 = new Circle(c2r, c2center);
var c3r = Math.abs(c1.r) - c2.r;
var c3x = c2.center.re + c2.r + c3r;
var c3y = c2.center.im;
var c3center = new Complex(c3x, c3y);
var c3 = new Circle(c3r, c3center);
return [
[c1, c2, c3]
];
};
var aSymmetricSet = function() {
var c1r = -MID;
var c1center = new Complex(MID, MID);
var c1 = new Circle(c1r, c1center);
var c2r = 160;
var c2center = new Complex(c2r, MID);
var c2 = new Circle(c2r, c2center);
var c3r = Math.abs(c1.r) - c2.r;
var c3x = c2.center.re + c2.r + c3r;
var c3y = c2.center.im;
var c3center = new Complex(c3x, c3y);
var c3 = new Circle(c3r, c3center);
return [
[c1, c2, c3]
];
};
var nestedSet = function() {
var c1r = -MID;
var c1center = new Complex(MID, MID);
var c1 = new Circle(c1r, c1center);
var c2r = 160;
var c2center = new Complex(MID, c2r);
var c2 = new Circle(c2r, c2center);
var c3r = MID - 160;
var c3center = new Complex(MID, DIM - c3r);
var c3 = new Circle(c3r, c3center);
var ci1r = -c2r;
var ci1center = new Complex(MID, Math.abs(ci1r));
var ci1 = new Circle(ci1r, ci1center);
var ci2r = Math.abs(ci1r) / 2;
var ci2center = new Complex(MID, ci2r);
var ci2 = new Circle(ci2r, ci2center);
var ci3r = Math.abs(ci1r) - ci2.r;
var ci3x = ci2.center.re;
var ci3y = ci2r + ci2r + ci3r;
var ci3center = new Complex(ci3x, ci3y);
var ci3 = new Circle(ci3r, ci3center);
return [
[c1, c2, c3],
[ci1, ci2, ci3]
];
};
var sets = {
'Symmetric': symmetricSet(),
'Asymmetric': aSymmetricSet(),
'Nested': nestedSet()
};
var drawCircle = function (c) {
var absR = Math.abs(c.r);
var d = absR * 2;
var dx = (doc.width - DIM) / 2 - d / 2;
var dy = (doc.height - DIM) / 2 - d / 2;
return doc.pathItems.ellipse(
-c.center.im - dy, c.center.re + dx,
d, d);
};
var circles;
var group;
var draw = function(selectedSet) {
circles = [];
group = doc.groupItems.add();
group.name = selectedSet;
var set = sets[selectedSet];
for (var i = 0; i < set.length; i++) {
var gasket = set[i];
drawGasket(gasket[0], gasket[1], gasket[2]);
}
for (var i = 0; i < circles.length; i++) {
drawCircle(circles[i]).moveToBeginning(group);
}
};
draw('Symmetric');
app.redraw();
// part 3: ScriptUI
var w = new Window("dialog");
var g = w.add("group");
var b1 = g.add("button", undefined, "Symmetric");
b1.preferredSize.width = 100;
var b2 = g.add("button", undefined, "Asymmetric");
b2.preferredSize.width = 100;
var b3 = g.add("button", undefined, "Nested");
b3.preferredSize.width = 100;
var b4 = w.add("button", undefined, "OK");
b4.preferredSize.width = 100;
var f1 = function (p1) {
doc.groupItems.removeAll();
draw(p1);
app.redraw();
};
b1.onClick = function () {
f1(b1.text);
};
b2.onClick = function () {
f1(b2.text);
};
b3.onClick = function () {
f1(b3.text);
};
w.show();
```

Community guidelines

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14117222#M382100
Sep 27, 2023
Sep 27, 2023

Copy link to clipboard

Copied

Perfectly wonderful, Femke.

Thanks for sharing.

Community guidelines

Matt Sk
AUTHOR

Explorer
,

/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14117346#M382105
Sep 27, 2023
Sep 27, 2023

Copy link to clipboard

Copied

@femkeblanco holy cow! That is impressive! Still always amazed at the genius of others.

Thank you so much for passing that along!

Community guidelines

Community Expert
,

LATEST
/t5/illustrator-discussions/help-with-design-please-fractals/m-p/14117433#M382107
Sep 27, 2023
Sep 27, 2023

Copy link to clipboard

Copied

Thanks Femke, I am impressed again.

Community guidelines

Resources

Learning Resources for Illustrator

Crash on launch and known issues

Fonts and Typography in Illustrator

Copyright © 2023 Adobe. All rights reserved.