Skip to content

Instantly share code, notes, and snippets.

@moritzmhmk
Created January 22, 2025 21:37
Show Gist options
  • Save moritzmhmk/90feb6e79850fee3bd4beeb2796d2169 to your computer and use it in GitHub Desktop.
Save moritzmhmk/90feb6e79850fee3bd4beeb2796d2169 to your computer and use it in GitHub Desktop.
Python script to generate a "squircle" in svg format.
# Loosely based on the constants found by Liam Rosenfeld
# https://liamrosenfeld.com/posts/apple_icon_quest/
# Node coordinates
n1 = 0.63149379
n2 = 0.07491139
# Handle coordinates
h1 = 0.86840694
h2 = 0.37282383
h3 = 0.16905956
def squircle(size: float, r: float):
w = size
h = size
def top_left(x: float, y: float) -> str:
return f"{x*r:.2f},{y*r:.2f}"
def top_right(x: float, y: float) -> str:
return f"{w-x*r:.2f},{y*r:.2f}"
def btm_right(x: float, y: float) -> str:
return f"{w-x*r:.2f},{h-y*r:.2f}"
def btm_left(x: float, y: float) -> str:
return f"{x*r:.2f},{h-y*r:.2f}"
return f"\
M{w/2},{0} \
\
C{top_right(h1, 0)}\
{top_right(h1, 0)}\
{top_right(n1, n2)} \
C{top_right(h2, h3)}\
{top_right(h3, h2)}\
{top_right(n2, n1)} \
C{top_right(0, h1)}\
{top_right(0, h1)}\
{w},{h/2} \
\
C{btm_right(0, h1)}\
{btm_right(0, h1)}\
{btm_right(n2, n1)} \
C{btm_right(h3, h2)}\
{btm_right(h2, h3)}\
{btm_right(n1, n2)} \
C{btm_right(h1, 0)}\
{btm_right(h1, 0)}\
{w/2},{h} \
\
C{btm_left(h1, 0)}\
{btm_left(h1, 0)}\
{btm_left(n1, n2)} \
C{btm_left(h2, h3)}\
{btm_left(h3, h2)}\
{btm_left(n2, n1)} \
C{btm_left(0, h1)}\
{btm_left(0, h1)}\
{0},{h/2} \
\
C{top_left(0, h1)}\
{top_left(0, h1)}\
{top_left(n2, n1)} \
C{top_left(h3, h2)}\
{top_left(h2, h3)}\
{top_left(n1, n2)} \
C{top_left(h1, 0)}\
{top_left(h1, 0)}\
{w/2},{0}"
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Create a squircle with given size and radius."
)
parser.add_argument(
"size", type=int, help="The size (required).")
parser.add_argument("--radius", type=int,
help="The radius (defaults to 0.45 * size/2).")
# Parse the arguments
args = parser.parse_args()
size = args.size
r = 0.45*args.size/2 if args.radius is None else args.radius
print(f'\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {size} {size}">\n\
<path d="{squircle(size, r)}" />\n\
</svg>')
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path d="M16.0,0 C25.75,0.00 25.75,0.00 27.45,0.54 C29.32,1.22 30.78,2.68 31.46,4.55 C32.00,6.25 32.00,6.25 32,16.0 C32.00,25.75 32.00,25.75 31.46,27.45 C30.78,29.32 29.32,30.78 27.45,31.46 C25.75,32.00 25.75,32.00 16.0,32 C6.25,32.00 6.25,32.00 4.55,31.46 C2.68,30.78 1.22,29.32 0.54,27.45 C0.00,25.75 0.00,25.75 0,16.0 C0.00,6.25 0.00,6.25 0.54,4.55 C1.22,2.68 2.68,1.22 4.55,0.54 C6.25,0.00 6.25,0.00 16.0,0" />
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment