Skip to content

Commit 3846af8

Browse files
committed
add control points to approximate circle
1 parent f061384 commit 3846af8

File tree

2 files changed

+59
-23
lines changed

2 files changed

+59
-23
lines changed

blob.svg

Lines changed: 9 additions & 10 deletions
Loading

svg.ts

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,74 @@
1+
const rand = (a, b) => Math.min(a, b) + (Math.abs(a - b) * Math.random());
2+
13
const size = 600;
24
const count = 8;
35
const color = "grey";
46

5-
const angle = 2 * Math.PI / count;
6-
const distance = size / 3;
7+
const angle = 2 * Math.PI/count;
8+
const distance = size/3;
9+
const ctrlDistance = distance * 4/3 * Math.tan(angle/4);
710

811
const points: {x: number, y: number}[] = [];
9-
for (let i = 0; i < count; i += 1) {
12+
for (let i = 0; i < count; i++) {
1013
points.push({
11-
x: Math.sin(i * angle) * distance,
12-
y: Math.cos(i * angle) * distance,
14+
x: Math.sin(i*angle) * distance,
15+
y: Math.cos(i*angle) * distance,
1316
});
1417
}
1518

16-
const paths = points.map<string>((point, i) => {
19+
const controls: {x1: number, y1: number, x2: number, y2: number}[] = [];
20+
for (let i = 0; i < count; i++) {
21+
const j = (i+count-1)%count;
22+
controls.push({
23+
x1: points[i].x - Math.cos(i*angle) * ctrlDistance,
24+
y1: points[i].y + Math.sin(i*angle) * ctrlDistance,
25+
x2: points[j].x + Math.cos(j*angle) * ctrlDistance,
26+
y2: points[j].y - Math.sin(j*angle) * ctrlDistance,
27+
});
28+
}
29+
30+
const paths: string[] = [];
31+
for (let i = 0; i <= count; i++) {
32+
const point = points[i%count];
33+
const control = controls[i%count];
34+
35+
// Start at the first point's coordinates.
1736
if (i === 0) {
18-
return `M${point.x},${point.y}`;
37+
paths.push(`M${point.x},${point.y}`);
38+
continue;
1939
}
20-
return `L${point.x},${point.y}`;
21-
});
40+
41+
//
42+
paths.push(`C${control.x2},${control.y2},${control.x1},${control.y1},${point.x},${point.y}`);
43+
44+
}
45+
// Close the path.
2246
paths.push("Z");
2347

2448
console.log(`
2549
<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
26-
<g transform="translate(${size / 2}, ${size / 2})">
50+
<g transform="
51+
translate(${size / 2}, ${size / 2})
52+
rotate(${rand(0, 360 / count)})
53+
">
54+
${points.map(({x, y}, i) => {
55+
return `<line x1="${x}" y1="${y}" x2="${controls[i].x1}" y2="${controls[i].y1}" stroke-width="1" stroke="green" />`;
56+
}).join("")}
57+
${points.map(({x, y}) => {
58+
return `<circle cx="${x}" cy="${y}" r="4" fill="red" />`;
59+
}).join("")}
60+
${controls.map(({x1: x, y1: y}, i) => {
61+
return `<circle cx="${x}" cy="${y}" r="2" fill="${i === 0 ? "black" : "blue"}" />`;
62+
}).join("")}
63+
${controls.map(({x2: x, y2: y}, i) => {
64+
return `<circle cx="${x}" cy="${y}" r="2" fill="${i === 0 ? "black" : "blue"}" />`;
65+
}).join("")}
2766
<path
2867
stroke="none"
2968
stroke-width="0"
3069
fill="${color}"
31-
d="${paths.join("\n")}"
70+
d="${paths.join("")}"
3271
/>
3372
</g>
3473
</svg>
3574
`);
36-
37-
// const r = (a, b) => Math.min(a, b) + (Math.abs(a - b) * Math.random());

0 commit comments

Comments
 (0)