If the condition were merely that the path cannot go downhill, to find the shortest path you could unroll the cone to a circular wedge with radius $60$ and vertex angle $\frac23\pi.$ The shortest path would run along a straight segment from one end of the radius-$60$ arc to a tangent point on a concentric arc of radius $50$ and then follow the radius-$50$ arc to the other end. If $L$ is the length of this path, then
$$L=\sqrt{60^2-50^2} + 50\left(\frac23\pi - \arccos\frac56\right).$$
Here's a rough sketch of the unrolled cone and the key features of the shortest never-downhill path:
Angle $\angle AOB = \frac23\pi,$ angle $\angle AOT = \arccos\frac56,$
the line $AT$ is tangent to the arc $BT$ at $T,$
and the path consists of the segment $AT$ and the arc $BT.$
Intuitively, since we can never get closer than distance $50$ from $O$
(since otherwise we'd have to go downhill to get to $B$),
the path is constrained to the region between the two arcs.
If we imagine running a string from $A$ to $B$
and then pull the string as tight as possible,
all while staying within that region,
the string will follow the path shown.
Any other path that goes around the cone from $A$ to $B$ will either go downhill at some point or will be longer than $L.$
But you can construct a path that is uphill everywhere and whose length is as close to $L$ as you want simply by replacing the arc of radius $50$ by a suitable spiral.
For example, construct a spiral path from $B$ to a point $C$ on $OA$ such that $OC = 50.000001,$ then construct a line through $A$ tangent to that spiral at a point $T'$; the path is the segment $AT'$ plus the part of the spiral from $T'$ to $B,$ all of it strictly uphill. To make an even shorter path, set $OC = 50.000000001$ instead of $50.000001.$
The only limit on how short you can make this path is that if you
reduce $OC$ to $50$ exactly, then you have a path of exactly length $L,$
but then the path is not strictly uphill the whole way.
Hence the number you are seeking, the length of the shortest uphill path around the cone from $A$ to $B,$ is the smallest number greater than $L.$
Based on the image
you have a left-handed coordinate system, where $x$ increases right, and $y$ down. Given axis-aligned bounding boxes' upper left corner coordinates, width, and height, you wish to find the axis-aligned bounding boxes after rotation by some angle around their center.
It looks like positive angles indicate counterclockwise rotation. In a left-handed coordinate system, this means rotation by $\varphi$ around point $(x_0 , y_0)$ is
$$\begin{cases}
x^\prime = x_0 + (x - x_0) \cos(\varphi) - (y - y_0) \sin(\varphi) \\
y^\prime = y_0 + (x - x_0) \sin(\varphi) + (y - y_0) \cos(\varphi) \end{cases}$$
where $(x, y)$ are the coordinates before the rotation, and $(x^\prime , y^\prime)$ after the rotation.
Let's say $( x_{min} , y_{min} )$ are the upper left coordinates, $w$ is the width, and $h$ is the height of the axis-aligned bounding box. Then,
$x_{min}$ is the left edge of the axis-aligned bounding box,
$y_{min}$ is the top edge of the axis-aligned bounding box,
$x_{max} = x_{min} + w$ is the right edge of the axis-aligned bounding box, and
$y_{max} = y_{min} + h$ is the bottom edge of the axis-aligned bounding box.
The four corners of the axis-aligned bounding box are therefore $( x_{min} , y_{min} )$, $( x_{max} , y_{min} )$, $( x_{min} , y_{max} )$, and $( x_{max} , y_{max} )$. When it is clear that we are talking about axis-aligned bounding boxes, this is often written in simplified form as $( x_{min} , y_{min} ) - ( x_{max} , y_{max} )$; i.e. as the diagonal line segment (in increasing coordinates).
If the center of rotation is at the center of the axis-aligned bounding box, then
$$\begin{cases}
x_0 = x_{min} + \frac{w}{2} = \frac{x_{min} + x_{max}}{2} \\
y_0 = y_{min} + \frac{h}{2} = \frac{y_{min} + y_{max}}{2} \end{cases}$$
Let's say we have an axis-aligned bounding box, and we know $x_{min}$, $y_{min}$, and have calculated $x_{max}$, $y_{max}$, $x_0$, and $y_0$, and that we want to rotate this by $\varphi$ (positive if clockwise, negative if counterclockwise, in this left-handed coordinate system).
There are two ways of calculating the axis-aligned bounding box after the rotation. First way is to calculate the four corner point coordinates:
$$\begin{aligned}
x_1 &= x_0 + (x_{min} - x_0) \cos \varphi - (y_{min} - y_0) \sin\varphi \\
y_1 &= y_0 + (x_{min} - x_0) \sin \varphi + (y_{min} - y_0) \cos\varphi \\
x_2 &= x_0 + (x_{max} - x_0) \cos \varphi - (y_{min} - y_0) \sin\varphi \\
y_2 &= y_0 + (x_{max} - x_0) \sin \varphi + (y_{min} - y_0) \cos\varphi \\
x_3 &= x_0 + (x_{min} - x_0) \cos \varphi - (y_{max} - y_0) \sin\varphi \\
y_3 &= y_0 + (x_{min} - x_0) \sin \varphi + (y_{max} - y_0) \cos\varphi \\
x_4 &= x_0 + (x_{max} - x_0) \cos \varphi - (y_{max} - y_0) \sin\varphi \\
y_4 &= y_0 + (x_{max} - x_0) \sin \varphi + (y_{max} - y_0) \cos\varphi
\end{aligned}$$
so that after the rotation, we pick the smallest and largest coordinates:
$$\begin{aligned}
x_{min} &= \min( x_1 , x_2 , x_3 , x_4 ) \\
y_{min} &= \min( y_1 , y_2 , y_3 , y_4 ) \\
x_{max} &= \max( x_1 , x_2 , x_3 , x_4 ) \\
y_{max} &= \max( y_1 , y_2 , y_3 , y_4 ) \\
w &= x_{max} - x_{min} \\
h &= y_{max} - y_{min} \end{aligned}$$
The other way is to note that since the original shape is a rectangle, and we rotate around its center, two of the corners are just mirrored around the center; and we can simply find the largest coordinates in magnitude with respect to the rotation center:
$$\begin{aligned}
x_{\Delta} &= \left \lvert \frac{w}{2} \cos \varphi \right \rvert + \left\lvert \frac{h}{2} \sin \varphi \right \rvert \\
y_{\Delta} &= \left \lvert \frac{w}{2} \sin \varphi \right \rvert + \left\lvert \frac{h}{2} \cos \varphi \right \rvert \\
\end{aligned}$$
where $\lvert \; \rvert$ refer to taking the absolute value. Then, you can update the axis-aligned bounding box properties using
$$\begin{aligned}
x_{max} &= x_0 + x_{\Delta} = x_{min} + \frac{w}{2} + x_\Delta \\
y_{max} &= y_0 + y_{\Delta} = y_{min} + \frac{h}{2} + y_\Delta \\
x_{min} &= x_0 - x_{\Delta} = x_{min} + \frac{w}{2} - x_\Delta \\
y_{min} &= y_0 - y_{\Delta} = y_{min} + \frac{h}{2} - y_\Delta \\
w &= 2 x_\Delta \\
h &= 2 y_\Delta
\end{aligned}$$
where the operations need to be done in the order shown (but you can omit $x_{max}$ and $y_{max}$, so that all right sides use the values prior to rotation (except for $x_\Delta$ and $y_\Delta$, of course).
In pseudocode, the rotation operation can be written as
Function rotate_aabb(xmin, ymin, width, height, angle):
Let c = cos(angle)
Let s = sin(angle)
Let halfw = 0.5*width
Let halfh = 0.5*height
Let xdelta = abs(c*halfw) + abs(s*halfh)
Let ydelta = abs(s*halfw) + abs(c*halfh)
Let xmin = xmin + halfw - xdelta
Let ymin = ymin + halfw - ydelta
Let width = 2*xdelta
Let height = 2*ydelta
Return (xmin, ymin, width, height)
End Function
which can be implemented using one sin
, one cos
, six multiplications, eight additions or subtractions, and four absolute values.
When rotating e.g. around the upper left corner, we have fewer symmetries:
Function rotate_aabb(xmin, ymin, width, height, angle):
Let c = cos(angle)
Let s = sin(angle)
Let x1 = c*width
Let y1 = s*width
Let x2 = -s*height
Let y2 = c*height
Let x3 = x1 + x2
Let y3 = y1 + y2
Let txmin = min(0, x1, x2, x3)
Let txmax = max(0, x1, x2, x3)
Let tymin = min(0, y1, y2, y3)
Let tymax = max(0, y1, y2, y3)
Let width = txmax - txmin
Let height = tymax - tymin
Let xmin = xmin + txmin
Let ymin = ymin + tymin
Return (xmin, ymin, width, height)
End Function
and we need one sin
and one cos
, four multiplications, six additions or subtractions, and twice an operation to find the maximum and minimum among four values, one of which is zero.
In C (C99 or later), you can implement min(0, x1, x2, x3)
as fmin(fmin(0.0, x1), fmin(x2, x3))
and max(0, y1, y2, y3)
as fmax(fmax(0.0, y1), fmax(y2, y3))
, although
txmin = 0.0;
if (txmin > x1) txmin = x1;
if (txmin > x2) txmin = x2;
if (txmin > x3) txmin = x3;
tymax = 0.0;
if (tymax < y1) tymax = y1;
if (tymax < y2) tymax = y2;
if (tymax < y3) tymax = y3;
and similarly for txmax
and tymin
, should generate optimal code on architectures with hardware min/max instructions, if optimizations are enabled. For example, on x86-64 with GCC 5.4.0 with -O2
, the above generates a sequence of minsd
and maxsd
instructions (and no jumps, so no slowdown due to conditional expressions at all).
The notable downside of calculating the rotated bounding box based on the previous bounding box, is that unless the rotation is a multiple of 90°, the bounding box will become larger after every rotation.
Best Answer
This parameterization should work: $$ \DeclareMathOperator{\sign}{sign} x=a\,\sign(\cos t)\,|\cos t|^{r/a}, \quad y=b\,\sign(\sin t)\,|\sin t|^{r/b}, $$ where $\sign(\cdot)$ is the sign function.