Tower of Pisa function
The equation of a circle at offset $(x_0,y_0)$ and radius $r$ is $(x-x_0)^2+(y-y_0)^2=r^2$. Therefore we can make the tower if we make $x_0$, $y_0$, and $r$ a function of height, moving $(x_0,y_0)$ along a line and shrinking $r$ as we go:
With[{a = 0.6, b = 0.3},
Show[
ContourPlot3D[(x - a*t)^2 + (y - b*t)^2 ==
0.04/t^2 (1 - t) + t (1 - t), {x, -2, 2}, {y, -2, 2}, {t, 0, 1},
ContourStyle -> Opacity[0.8],
MeshFunctions -> {Function[{x, y, t}, t]}, Axes -> None]
, Graphics3D[{Thick, InfiniteLine[{{0, 0, 0}, {a, b, 1}}]}]
]
]
The {a = 0.6, b = 0.3}
controls the direction of the tower, while the expression 0.04/t^2 (1 - t) + t (1 - t)
controls the radius.
Here's why I chose this specific expression for the radius: When t
is near zero the radius behaves as 0.04/t^2
so you get infinitely large circles creating an infinitely large base shrinking to form a nice smooth join with the tower. As t
approaches 1, the radius is more like (1 - t)
and shrinks to zero near the top creating the tower cap.
Let $r : [0,1] \longrightarrow [0,\infty[$ be decreasing with $r(0)=\infty$ and $r(1)=0$.
For $c\in [0,1[$ set $s:= c r$ then $$r'(t') < -|s'(t)|$$ and $$(x-c r(f(x,y)))^2 + y^2= r^2(f(x,y))$$ such that $$f(x,y)= r^{-1}\left(\frac{1}{c^2-1}\left(c x \pm \sqrt{x^2-(c^2-1)y^2}\right)\right).$$ $r^{-1}$ just has to be chosen such that $f$ is differentiable, e.g., $r^{-1}(t)=\exp(-t^2)$. Here, $c$ allows to adjust the tilt ($c=0$ no tilt, $c\rightarrow 1$ maximal).
You can also use other functions like $r^{-1}(t)=1-t^2$ to create other towers such as the Burj al Arab.
(Extended comment, not an answer.)
Imported the STL file from here: https://www.thingiverse.com/thing:2733780/files .
One approach would be to use intersections of this STL-file mesh object with planes orthogonal to the X-axis and derive (pairs of) functions over a certain set of X values.
rgSTLPisa =
Quiet[Import[
"https://cdn.thingiverse.com/assets/10/ba/d8/e6/06/Leaning_Tower_of_Pisa.stl"]];
Show[rgSTLPisa, Boxed -> True, Axes -> True]
Show[rgSTLPisa, Boxed -> True, Axes -> True, PlotRange -> {{-10, 20}, All, All}]