Skip to content

Instantly share code, notes, and snippets.

@zyocum
Last active July 1, 2021 16:06
Show Gist options
  • Save zyocum/cb13369a9ea26dcab4b277d9fb1791d0 to your computer and use it in GitHub Desktop.
Save zyocum/cb13369a9ea26dcab4b277d9fb1791d0 to your computer and use it in GitHub Desktop.
surface_area_of_cup
<meta charset="utf-8" emacsmode="-*- markdown -*">
**Surface Area of a Cup with a Straight Outer Edge**
Let's say our cup is defined by the following parameters:
\begin{align*}
r=\,&\text{radius of the top of the cup}\\
b=\,&\text{height of the cup}\\
B=\,&\text{angle of the sloped side of the cup}\\
\end{align*}
*********************
* B_____C_____*
* ┌ \ | /*
* │ c\ |b / *
* h│ \__|__/ *
* │ ┌ \ | *
* │ y│ d\| *
* └ └ | *
* └─┘A *
* x *
* └─────┘ *
* r *
* *
*********************
\begin{align*}
A=\,&\text{the angle at the tip of the cone that subsumes our cup}\\
C=\,&\text{the remaining 90 degree angle of our triangle ABC}\\
b=\,&\text{the height of the cup}\\
c=\,&\text{the length of the sloped outer edge of the cup}\\
h=\,&\text{the height of the extended cone}\\
x=\,&\text{the radius of the bottom of the cup}\\
y=\,&h - b\\
\end{align*}
From the cross section of half the cup above, there is another triangle we can derive that shares the angle $B$, and has base $r-x$:
***********
* *
* B'_____C*
* ┌|\ |*
*b│|c\ |*
* └|__\__|*
* *
* └───┴─┘*
* r-x x *
* └─────┘*
* r *
***********
Let's call the outside angle $B'$ the angle that sums to $90\degrees$ with $B$:
\begin{align*}
B' = A = \,& 90\degrees - B\\
-> \tan{\left(B'\right)} =\,& {{\left(r - x\right)}\over{}b}\\
-> x =\,& -1 \cdot \left(b \cdot \tan{\left( 90\degrees - B \right)} - r\right)\\
-> x =\,& - \left(b \cdot \tan{\left( 90\degrees - B \right)}\right) + r
\end{align*}
So, we've defined $x$ in terms of $b$, $B$, and $r$ which are the parameters we used to define our cup originally.
*************
* *
* B'_____C *
* ┌|\ |┐ *
*b│|c\ |│ *
* ├|__\__|│ *
* │ \ |│h*
*y│ d\|│ *
* └ |┘ *
* └───┴─┘A *
* r-x x *
* └─────┘ *
* r *
*************
Next we want to derive $h$ which, along with $r$, defines the cone that subsumes the cup.
We know $c$ now due to Pythagoras' Theorem:
\begin{align*}
c^{2} =\,& \left(r-x\right)^{2} + b^{2}\\
c =\,& \sqrt{\left(r-x\right)^{2} + b^{2}}\\
\end{align*}
Note that in case $x \leq 0$, then you don't really have a cup, you just have a cone.
************
* *
* B_____C *
* \ |┐ *
* \ |│ *
* c\ |│ *
* \ |│h*
* \|│ *
* |┘ *
* └─────┘A *
* r *
************
In that case, $h$ can be computed in terms of $r$ and $B$ alone:
\begin{align*}
\tan\left(B\right) =\,& {{h}\over{r}}\\
h =\,& \tan\left(B\right) \cdot r
\end{align*}
Otherwise, when $x > 0$, we can derive $d$:
\begin{align*}
\csc\left(A\right) =\,& {{d}\over{x}}\\
-> {{1}\over{\cos\left(A\right)}}=\,& {{d}\over{x}}\\
-> d =\,& {{x}\over{\cos\left(A\right)}}\\
\end{align*}
We know $A$ from above, so:
\begin{align*}
-> d =\,& {{x}\over{\cos\left(90\degrees - B\right)}}\\
-> d =\,& {{-\left(b \cdot \tan{\left( 90\degrees - B \right)}\right) + r}\over{\cos\left(90\degrees - B\right)}}\\
\end{align*}
And from Pythagoras' Theorem, again, we can derive $h$:
\begin{align*}
h^{2} =\,& \left({c+d}\right)^{2}+x^{2}\\
-> h =\,& \sqrt{\left({c+d}\right)^{2}+x^{2}}\\
-> h =\,& \sqrt{\left({{\sqrt{\left(r-\left({-\left(b \cdot \tan{\left( 90\degrees - B \right)}\right) + r}\right)\right)^{2} + b^{2}}}+{{{-\left(b \cdot \tan{\left( 90\degrees - B \right)}\right) + r}\over{\cos\left(90\degrees - B\right)}}}}\right)^{2}+\left({-\left(b \cdot \tan{\left( 90\degrees - B \right)}\right) + r}\right)^{2}}\\
\end{align*}
Now that we have $h$, we can compute the cup's surface area by subtracting the surface area of the cone defining the tip that extends beyond the base (whose triangle cross section has hypotenuse $d$) from the subsuming cone (whose triangle cross section has hypotenuse $d+c$):
\begin{align*}
\text{subsuming cone surface area}=\,& \pi r \sqrt{r^{2} + h^{2}}\\
\text{tip cone surface area}=\,& \pi x \sqrt{x^{2} + y^{2}}\\
\text{cup surface area}=\,& \left(\pi r \sqrt{r^{2} + h^{2}}\right) - \left(\pi x \sqrt{x^{2} + y^{2}}\right)
\end{align*}
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script type="text/javascript" nonce="73ff92345fb24880b2768041be8" src="//local.adguard.org?ts=1625089155390&amp;type=content-script&amp;dmn=casual-effects.com&amp;app=com.apple.SafariTechnologyPreview&amp;css=1&amp;js=1&amp;gcss=1&amp;rel=1&amp;rji=1&amp;sbe=0&amp;stealth=1&amp;uag=&amp;trref=aHR0cHM6Ly9jYXN1YWwtZWZmZWN0cy5jb20v"></script>
<script type="text/javascript" nonce="73ff92345fb24880b2768041be8" src="//local.adguard.org?ts=1625089155390&amp;name=Web%20of%20Trust&amp;name=AdGuard%20Popup%20Blocker&amp;name=AdGuard%20Extra&amp;type=user-script"></script><script src="markdeep.min.js" charset="utf-8"></script><script src="https://morgan3d.github.io/markdeep/latest/markdeep.min.js?" charset="utf-8"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>
#!/usr/bin/env python3
import math
import sys
def cone_surface_area(radius, height):
"""Compute the surface area of a cone defined by two parameters:
radius: the radius of the base of the cone
height: the height of the cone
"""
return math.pi * radius * math.sqrt((radius ** 2) + (height ** 2))
def cylinder_surface_area(radius, height):
"""Compute the surface area of a cylinder defined by two parameters:
radius: the radius of the base of the cylinder
height: the height of the cylinder
"""
return 2 * math.pi * radius * height
def cup_surface_area(radius, height, angle, verbose=False):
"""Compute the surface area of a cup defined by three parameters:
radius: the radius of the top of the cup
height: the height of the cup
angle: the angle between the top of the cup and the sloped edge (in radians)
"""
A = (math.pi / 2) - angle
x = -(height * math.tan(A)) + radius
b = (radius - x) / math.tan(A)
c = math.sqrt(((radius - x) ** 2) + (b ** 2))
d = x / math.cos(A)
y = math.sqrt((d ** 2) + (x ** 2))
subsuming_cone_height = math.sqrt(((c + d) ** 2) + (x ** 2))
subsuming_cone_surface_area = cone_surface_area(radius, subsuming_cone_height)
tip_cone_surface_area = cone_surface_area(x, y)
if verbose:
print(
f'A={A}',
f'x={x}',
f'b={b}',
f'c={c}',
f'd={d}',
f'y={y}',
f'subsuming_cone_height={subsuming_cone_height}',
f'subsuming_cone_surface_area={subsuming_cone_surface_area}',
f'tip_cone_surface_area={tip_cone_surface_area}',
sep='\n'
)
if x <= 0: # in case x is not positive, you have a cone, not a cup
print(
'FYI: based on the radius, angle, and height, this cup is actually a cone',
file=sys.stderr
)
return cone_surface_area(radius, math.tan(angle) * radius)
return subsuming_cone_surface_area - tip_cone_surface_area
if __name__ == '__main__':
import argparse
def angle(value):
value = float(value)
if (value < 0) or (value >= 90):
raise argparse.ArgumentError(f'angle must be between 0 and 90 degrees')
return math.radians(value)
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description=__doc__
)
parser.add_argument(
'--radius',
type=float,
required=True,
help='cup radius',
)
parser.add_argument(
'--height',
type=float,
help='cup height'
)
parser.add_argument(
'--angle',
type=angle,
required=True,
help='cup angle (in degrees)'
)
parser.add_argument(
'-v', '--verbose',
action='store_true',
help='print verbose output',
)
args = parser.parse_args()
cup = args.radius, args.height, args.angle
print(
f'''A cup with ...''',
f'radius={args.radius}',
f'height={args.height}',
f'angle={math.degrees(args.angle):0.3f} degrees ({args.angle:0.3f} radians)',
f'... has surface area of: {cup_surface_area(*cup, verbose=args.verbose)}',
sep='\n'
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment