想象一下,你想列印出情節,然后用剪刀剪下來。您如何確保繪制的圖具有正確的尺寸?
一個例子:
您想繪制當平面以角度 θ 切割半徑為 r(以毫米為單位)的圓柱時形成的橢圓。
您希望將繪圖列印在紙上,這樣如果您將其切出,您可以將其包裹在半徑為 r 的物理圓柱體上,并將其用作斜接圖案:如果您沿著圖案的邊緣切割圓柱體,您會在以下位置獲得完美的直線切割角θ。
為了確保你做對了,你在兩個不同的紙板圓筒上練習:一個是一卷衛生紙,半徑等于 22 毫米;另一個,來自一卷紙巾,半徑等于 19 毫米。這是代碼:
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?
uj5u.com熱心網友回復:
我的評論似乎沒有通過,所以我將提出部分答案,即如何建立 1 的縱橫比,這將有望使 x 軸和 y 軸尺寸處于相同的比例:
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")) coord_fixed(1)
}
cylinders <- c(toilet_paper_roll = 22,
paper_towel_roll = 19) %>%
map(plot_unfurled_ellipse)
png()
print(cylinders)
#$toilet_paper_roll
#
#$paper_towel_roll
dev.off()
#RStudioGD
# 2

第二個情節:

剩下的任務是建立一種機制,將繪圖單位的任意比例轉換為物理 inces。這(我認為)可以通過呼叫設定網格單元來完成
units( ..., "in")
這個答案可能會有所幫助:R convert grid units of layout object to native
uj5u.com熱心網友回復:
OK完成。正如我懷疑的那樣,如果您獲得正確的繪圖大小,則設定縱橫比是多余的。如果兩個軸上的單位均以實際毫米為單位,則網格圖案將為方形,縱橫比將等于 1,而無需 coord_fixed()明確設定。此外,我在get_unfurled_ellipse(). 我修好了它。突破是我正在使用該egg包以毫米為單位明確設定繪圖尺寸,并在此處圖 3 正上方顯示數學。新版本的代碼是這樣的:
library(tidyverse)
library(egg)
# 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.
# 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) {
# imagine that the ellipse that cuts this cylinder
# is itself cut through the middle by a circle that
# is parallel to the bottom of the cylinder. Now
# you have two wedges: one above the circle, one
# below it. The goal is to express any point on
# the elliptical (long) arc in the wedge as a function
# of the point on the circular (short) arc that falls
# directly below it. That is the vertical projection of
# the ellipse's major radius inside that wedge.
top_half <- tibble(x = seq(0, pi*r, length.out = steps)) %>%
mutate(h = r * tan(theta * pi / 180) * sin(x / r))
bottom_half <- top_half %>%
mutate(x = x pi*r,
h = -h)
top_half %>%
bind_rows(bottom_half) %>%
rename(y = h)
}
plot_unfurled_ellipse <- function(r = 1,
theta = 30,
steps = 1000,
dot_size = .5) {
df <- get_unfurled_ellipse(r, theta, steps)
xlims <- c(0, max(df$x))
ylims <- c(min(df$y), max(df$y))
df %>%
ggplot(aes(x, y))
geom_point(size = dot_size)
theme(axis.ticks.length=unit(r/steps, "mm"))
scale_x_continuous(limits = xlims, expand = c(0, 0))
scale_y_continuous(limits = ylims, expand = c(0, 0))
}
cylinders <- c(toilet_paper_roll = 22,
paper_towel_roll = 19) %>%
map(plot_unfurled_ellipse)
cylinder_grobs <- tibble(plot = cylinders) %>%
mutate(title = names(plot)) %>%
pmap(.f = function(plot, title) {
x <- plot
ggtitle(title)
x %>%
egg::set_panel_size(width = unit(max(.$data$x), "mm"),
height = unit(2 * max(.$data$y), "mm")) %>%
arrangeGrob()
})
當這些 grobs 以橫向模式在 US Letter 上匯出為 pdf 并以?? 100% 的比例列印時,紙張上的尺寸與預期的尺寸完全匹配:實際毫米。現在我有一個斜接圖案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/376447.html
