В связи с наступающей пасхой возникла у меня идея — а не сделать ли мне яйцо с помощью Geometry Nodes?
Скачать готовые файлы:
https://lavorocertosino.gumroad.com/l/dkcxai
https://buymeacoffee.com/studiareweb/e/528358
Здесь я приведу список ресурсов, которые помогли мне найти подходящее решение (и подсказали задачи на будущее).
Как вообще можно математически описать форму яйца?
Из википедии:
Ово́ид (лат. ovum — яйцо + греч. έιδος — подобный) — замкнутая гладкая выпуклая кривая, имеющая только одну ось симметрии.
«Овоидной» также называют форму пространственного тела, полученного вращением плоского овоида вокруг оси симметрии (синоним «яйцевидная»).
В Интернете можно найти много примеров построения овоидов. Для Geometry Nodes в блендер я выбрала, на мой взгляд, самый простой вариант.
https://bsidneysmith.com/writings/jotsndoodles/the-egg-equations

Но, конечно, это не единственный вариант решения задачи.
На этом ресурсе собрано очень много разных кривых, овоидов и подобных. Методы построения используются тоже разные.
https://www.mathematische-basteleien.de/eggcurves.htm
Мне понравилось уравнение для трехмерной поверхности, и я задумалась о его реализации.

Весьма интересная формула, которую тоже стоит попробовать реализовать в Geometry Nodes, была найдена на одном из форумов.

Там же был указан источник этого уравнения. К сожалению, я не нашла в источнике читабельных формул, хотя и нашла очень интересные результаты.
Уравнение Овоида, которое считается классическим

https://scipython.com/blog/a-universal-formula-for-egg-shape/
В этом же источнике приведен код на языке Python для построения графика по этим зависимостям (код я не проверяла).
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d
def yegg(x, L, B, w, D):
"""
The "universal" formula for an egg, from Narushin et al., "Egg and math:
introducing a universal formula for egg shape", *Ann. N.Y. Acad. Sci.*,
**1505**, 169 (2021).
x should vary between -L/2 and L/2 where L is the length of the egg; B
is the maximum breadth of the egg; w is the distance between two vertical
lines corresponding to the maximum breadth and y-axis (with the origin
taken to be at the centre of the egg); D is the egg diameter at the point
a distance L/4 from the pointed end.
"""
fac1 = np.sqrt(5.5*L**2 + 11*L*w + 4*w**2)
fac2 = np.sqrt(L**2 + 2*w*L + 4*w**2)
fac3 = np.sqrt(3)*B*L
fac4 = L**2 + 8*w*x + 4*w**2
return (B/2) * np.sqrt((L**2 -4*x**2) / fac4) * (
1 - (fac1 * (fac3 - 2*D*fac2) / (fac3 * (fac1 - 2*fac2)))
* (1 - np.sqrt(L*fac4 / (2*(L - 2*w)*x**2
+ (L**2 + 8*L*w - 4*w**2)*x + 2*L*w**2 + L**2*w + L**3))))
def plot_egg_contour(ax, title, x, L, B, w, D):
y = yegg(x, L, B, w, D)
ax.plot(x, y, 'k')
ax.plot(x, -y, 'k')
ax.axis('equal')
ax.axis('off')
ax.set_title(title)
fig, axes = plt.subplots(nrows=2, ncols=2)
L = 1
x = np.linspace(-L/2, L/2, 200)
# Circular egg (e.g. Ural owl).
plot_egg_contour(axes[0][0], 'Ural Owl', x, L, L, 0, L * np.sqrt(3) / 2)
# Hen egg.
plot_egg_contour(axes[1][0], 'Hen', x, L, 0.8, 0.1, 0.6)
# Guillemot egg (pyriform).
plot_egg_contour(axes[0][1], 'Guillemot', x, L, 0.5, 0.1, 0.3)
# Ostrich egg.
plot_egg_contour(axes[1][1], 'Ostrich', x, L, 0.7, 0, 0.6)
plt.show()
# Render a 3D image of a guillemot egg.
B, w, D = 0.5, 0.1, 0.3
phi = np.linspace(0, 2*np.pi, 100)
X, Phi = np.meshgrid(x, phi)
Y = yegg(X, L, B, w, D) * np.cos(Phi)
Z = yegg(X, L, B, w, D) * np.sin(Phi)
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X, Y, Z, alpha=0.3, color='r', rstride=10, cstride=10)
ax.plot_wireframe(X, Y, Z, color='k', rstride=10, cstride=10, lw=1)
ax.set_xlim(-L/2, L/2)
ax.set_ylim(-L/2, L/2)
ax.set_zlim(-L/2, L/2)
ax.axis('off')
plt.show()