Imagine that you want to print out the plot and then cut it out with scissors. How do you make sure that the plot you draw has the correct dimensions?
An example:
You want to plot the ellipse formed when a plane cuts a cylinder of radius r, in millimeters, at an angle θ.
You want the plot printed on paper such that if you cut it out, you can wrap it around a physical cylinder of radius r and use it as a mitering pattern: if you cut the cylinder along the pattern's edges you get a perfectly straight cut at the angle θ.
To make sure that you got this right, you practice on two different cardboard cylinders: one from a roll of toilet paper, with radius equal to 22mm; the other, from a roll of paper towels, with radius equal to 19 mm. Here's the code:
library(tidyverse)
# Draw the ellipse you get when you intersect
# a cylinder of radius r by a plane at an
# angle theta (in degrees). Unfurl it for
# printing on a piece of paper that can then
# be cut and wrapped around a cylinder of
# radius r, so you can use it as a pattern
# for cutting the cylinder at angle theta.
# `steps` will set the resolution: the higher
# the number, the more precise the curve.
get_unfurled_ellipse <- function(r = 1,
theta = 30,
steps = 1000) {
# based on the equation of an ellipse in standard form shown here:
# https://saylordotorg.github.io/text_intermediate-algebra/s11-03-ellipses.html
# with the parameterization that a = r and b = r / cos(theta * pi / 180)
# where a is the minor radius and b is the major radius. The formula
# above for b follows directly from looking at the vertical section of the
# cylinder along its axis of symmetry in the plane that is perpendicular
# to the intersecting plane: it's a trapezoid with the non-perpendicular
# side equal to 2*b and the length of b can be derived as a / cos(theta * pi / 180)
# This is easier drawn than explained. See also here:
# https://mathworld.wolfram.com/CylindricalSegment.html
top_half <- tibble(x = seq(-r, r, length.out = steps)) %>%
mutate(y = sqrt((r^2 - x^2) * r / cos(theta * pi / 180)))
bottom_half <- tibble(x = top_half$x + 2*r) %>%
mutate(y = - sqrt((r^2 - (x-2*r)^2) * r / cos(theta * pi / 180)))
top_half %>%
bind_rows(bottom_half)
}
plot_unfurled_ellipse <- function(r = 1, theta = 30, steps = 1000) {
get_unfurled_ellipse(r, theta, steps) %>%
ggplot(aes(x, y)) +
geom_point() +
theme(axis.ticks.length=unit(r/steps, "mm"))
}
cylinders <- c(toilet_paper_roll = 22,
paper_towel_roll = 19) %>%
map(plot_unfurled_ellipse)
Shown above is the picture corresponding to the toilet paper cylinder. You print it out and start cutting at 0, follow the curve up, then down, return to the x axis, cut all the way through and you keep the bottom part. You should be able to roll it around the cardboard cylinder precisely, with the horizontal sections of the cut serving as flaps that you can tape on top of each other and they should overlap perfectly, because the curves start and end at the same point.
How do you make sure that the printed picture will be of the correct size for this, without any distortions along either axis?