vignettes/arcwedges.qmd
Arcs and Wedges
Setup
Packages
Base Plot
To avoid repetitive code, we make a base plot:
my_font <- "Roboto Condensed"
my_font_size <- 20
my_point_size <- 2
my_arrowhead <- arrowheadr::arrow_head_deltoid(2.3, n = 101)
# my_colors <- viridis::viridis(2, begin = .25, end = .5)
my_colors <- c("#3B528B", "#21908C")
bp <- ggdiagram(
font_family = my_font,
font_size = my_font_size,
point_size = my_point_size,
linewidth = .5,
theme_function = theme_minimal,
axis.title.x = element_text(face = "italic"),
axis.title.y = element_text(
face = "italic",
angle = 0,
hjust = .5,
vjust = .5)) +
scale_x_continuous(labels = signs_centered,
limits = c(-4, 4)) +
scale_y_continuous(labels = signs::signs,
limits = c(-4, 4))
Arcs
Just as a segment is part of a line between two points on the line, an arc is part of a circle between two points (on the circle). Thus, an arc has all the properties a circle, with the addition of starting and ending points. For the sake of simplicity, these starting points are specified as angles.
Arc starting and ending points can be specified with any angle unit. If a number is used, it will be interpreted as a degree unit.
ob_arc(center = ob_point(1,2),
start = 25,
end = 75,
radius = 3)
#> <ggdiagram::ob_arc>
#> @ center: <ggdiagram::ob_point>
#> @ x: num 1
#> @ y: num 2
#> @ radius: num 3
#> @ start : <ggdiagram::degree>
#> @ degree: num 25
#> @ end : <ggdiagram::degree>
#> @ degree: num 75
#> @ theta : <ggdiagram::degree>
#> @ degree: num 50
#> Other props: label, type, alpha, arrow_head, arrow_fins,
#> arrowhead_length, length_head, length_fins, color,
#> fill, lineend, linejoin, linewidth, linewidth_fins,
#> linewidth_head, linetype, n, resect, resect_fins,
#> resect_head, stroke_color, stroke_width, apothem,
#> arc_length, sagitta, bounding_box, circle, chord,
#> length, end_point, polygon, start_point, style,
#> tibble, geom, angle_at, autolabel, hatch, midpoint,
#> normal_at, place, point_at, tangent_at, aesthetics
Code
ggtext::GeomRichText$default_aes
#> Aesthetic mapping:
#> * `colour` -> "black"
#> * `fill` -> "white"
#> * `size` -> 7.029196
#> * `angle` -> 0
#> * `hjust` -> 0.5
#> * `vjust` -> 0.5
#> * `alpha` -> NA
#> * `family` -> "Roboto Condensed"
#> * `fontface` -> 1
#> * `lineheight` -> 1.2
#> * `text.colour` -> NULL
#> * `label.colour` -> NULL
#> * `label.size` -> 0.25
bp +
{p1 <- ob_point(0, 0)} +
{a1 <- ob_arc(
center = p1,
radius = {r <- 4},
start = {ang_start <- degree(25)},
end = {ang_end <- degree(75)}
)} +
ob_label(
label = paste0("Center ", p1@auto_label),
center = p1,
vjust = 1.1) +
connect(
p1,
a1@midpoint(),
label = paste0("Radius = ", r)) +
ob_label(
label = ang_start,
center = a1@midpoint(0),
polar_just = ob_polar(ang_start + degree(-90), 1.3),
plot_point = TRUE) +
ob_label(
label = ang_end,
center = a1@midpoint(1),
polar_just = ob_polar(ang_end + degree(90), 1),
plot_point = TRUE)
Starting or ending points of arcs
Sometimes you do not know where the center of an arc should be. Instead, you want the arc to start or end at a specific point. For example, you might want to specify the start point or the end point.
p1 <- ob_point(0, 0)
bp +
ob_arc(start = -45,
end = 45,
radius = 2,
color = "orchid4",
start_point = p1) +
ob_arc(start = -45,
end = 45,
radius = 2,
color = "forestgreen",
end_point = p1) +
p1
As a example, I used the start_point
argument to recreate a fun meme about a “square” object with 4 equal sides that meet at right angles:
little_r <- 1 / (2 * pi - 1)
ggdiagram(font_family = my_font,
font_size = my_font_size) +
{p1 <- ob_point(0,0)} +
{p2 <- ob_point(1,0)} +
ob_segment(p1, p2) +
{a1 <- ob_arc(start = 0, end = radian(1), radius = 1 + little_r, start_point = p2)} +
{p3 <- a1@midpoint(1)} +
{p4 <- a1@normal_at(radian(1), distance = -1)} +
ob_segment(p3, p4) +
ob_arc(start_point = p4,
radius = little_r,
start = radian(1),
end = turn(1))
Midpoints
The midpoint function can find one or more midpoints at different positions. The default position is .5.
bp +
a1 +
a1@midpoint()
The starting and ending points are at position 0 and 1, respectively.
bp +
a1 +
a1@midpoint(position = c(0,1))
Labelling arcs
By default, the arc label will appear outside the midpoint of the arc
If a label is needed elsewhere, it can be set with the label
function’s position
property.
bp +
ob_arc(
radius = 3,
start = 20,
end = 120,
label = ob_label(
c("Start", "Middle", "End"),
position = c(0, .5, 1),
plot_point = TRUE
)
)
If the orientation of the label needs to be changed, it can be set with vjust
, hjust
, or polar_just
.
There are cases where the arc is already created and a label is needed. Although the label
can be added after the arc has been created, the position would have to be set manually (otherwise the position will be at 0,0 by default). In such cases, the auto_label
function can help place the label correctly. By default, the auto_label
will show the the theta
property (i.e., end
− start
).
bp +
{a1 <- ob_arc(radius = 3,
start = 20,
end = 120)} +
a1@autolabel()
However, any label can be inserted at any position.
bp +
a1 +
a1@autolabel(label = "Start",
position = 0)
Arcs with arrows
The arc object is plotted using ggarrow::arrow
. This means that arrows can be placed on either end of an arc.
my_arrow_head <- arrowheadr::arrow_head_deltoid(d = 2.3, n = 100)
bp +
ob_arc(radius = 3,
start = 0,
end = 180,
arrow_head = my_arrow_head,
arrow_fins = my_arrow_head,
arrowhead_length = 8)
Wedges
The ob_arc
function has a @type
property that can be set to "arc"
, "wedge"
, or "segment"
. When set to arc
, the arc is drawn with geom::arrow
so that the arc endpoints can be arrows. Otherwise, when @type
is wedge
or segment
, ob_arc
drawn with ggplot2::geom_polygon
.
The ob_wedge
function is a convenient wrapper function for ob_arc
that sets the @type
property to wedge
.
Circular Segments
A circular segment is an arc made into a polygon.
The ob_circular_segment
function is a convenient wrapper function for ob_arc
that sets the @type
property to segment
.
ggdiagram() +
ob_circular_segment(
start = c(30, 150, 270),
end = c(150, 270, 390),
fill = c("dodgerblue4", "orchid4", "darkgreen")
)
Objects made with ob_arc
, ob_wedge
, or ob_circular_segment
can return important features of arcs, including the chord
, sagitta
, and arc_length
. In Figure 13, the chord
is the ob_segment
that connects the endpoints of the arc. The sagitta
is ob_segment
from the arc’s midpoint to the chord’s midpoint. Not shown in Figure 13, the apothem
is the ob_segment
from the arc’s center point to the midpoint of the chord. The radius is the sum of the distances spanned by the apothem and the sagitta.
bp +
{cs <- ob_circular_segment(
radius = 3,
start = radian(-acos(1 / 3)),
end = radian(acos(1 / 3)),
fill = "dodgerblue3"
)} +
ob_arc(
radius = 3,
start = cs@end,
end = cs@start + degree(360),
linetype = "dashed"
) +
cs@chord@midpoint()@label(
paste0("Chord Length = ", round(cs@chord@distance, 2)),
angle = cs@chord@line@angle,
vjust = -.1,
color = "black",
size = 18
) +
cs@sagitta %>% set_props(color = "white") +
cs@sagitta@midpoint()@label(
paste0("Sagitta = ", round(cs@sagitta@distance, 2)),
vjust = 0,
size = 18,
fill = NA,
color = "white"
) +
ob_path(
ob_point(
cs@polygon %>%
mutate(id = dplyr::row_number()) %>%
arrange(-id) %>%
select(x, y)
),
label = ob_label(
paste0("Arc Length = ", round(cs@arc_length, 2)),
vjust = -0.1,
size = 18,
color = "black"
),
color = "dodgerblue3"
)
Fun fact: Our geometric concepts arc, chord, and sagitta are all archery terms, deriving from the Latin words arcus (bow), chorda (string), and sagitta (arrow).