Interpolation for degree angles
Usage
approx_degrees(
h1,
h2,
h = NULL,
preset = "custom",
direction = 1,
digits = 10,
verbose = FALSE,
...
)
Arguments
- h1
numeric
vector of degree angles, which should represent the "degree angles from".- h2
numeric
vector of degree angles, which should represent the "degree angles to".- h
numeric
orNULL
, where anumeric
vector is a vector of degree angles "from" that should be converted to the corresponding interpolated angle "to", Whenh is NULL
then the object returned is afunction
to be called to convert a numeric vector "from" to degree angles "to".- digits
integer
value indicating the number of digits of precision to use for the inputh1
andh2
degree angles, used when confining to 360 degrees withh1 %% 360
, and this step sometimes produces slight variations for equivalent values. For example((12.2 %% 360) == (372.2 %% 360))
is notTRUE
without rounding to13
or fewer digits.- ...
additional arguments are ignored.
Details
This function is analogous to stats::approx()
except for
the special case of degree angles. In this case, degrees
are confined to the range [0, 360]
, and angle are smoothly
interpolated around the degrees of a circle.
This function should work properly even when the degree angles
in h2
are reversed, or offset. The only implicit requirement
is that angles in "from" should be mapped to one and only one
angle in "to".
See also
Other colorjam hue warp:
add_colorjam_preset()
,
add_colorjam_step()
,
adjust_hue_warp()
,
colorjam_presets()
,
colorjam_steps()
,
display_degrees()
,
h2hw()
,
h2hwOptions()
,
hcl_to_hsl_hue()
,
hsl_to_hcl_hue()
,
hw2h()
,
mean_angle()
,
plot_colorjam_preset()
,
remap_colorjam_preset()
,
validate_colorjam_preset()
Examples
h_colors <- jamba::getColorRamp(c("white", "firebrick"), n=35, trimRamp=c(1, 0));
h1 <- c(12.2, 27.3, 47.0, 66.5, 85.9, 106.3, 131.7,
223.1, 263.2, 277.2, 307.7, 345.3, 372.2)
h2 <- seq(from=0, to=360, length.out=13)
h_from <- seq(from=0, to=360, length.out=36)[-36]
h_to <- approx_degrees(h1, h2, h_from)
par("mfrow"=c(2, 2))
display_degrees(h_from, col=h_colors)
display_degrees(h_to, col=h_colors)
plot(h_from, h_to, pch=20, col=h_colors)
par("mfrow"=c(1, 1))
h2 <- c(12.2, 27.3, 47.0, 66.5, 85.9, 106.3, 131.7,
223.1, 263.2, 277.2, 307.7, 345.3, 372.2)
h1 <- seq(from=0, to=360, length.out=13)
h_from <- seq(from=0, to=360, length.out=36)[-36]
h_to2 <- approx_degrees(h2, h1, h_from)
par("mfrow"=c(2, 2))
display_degrees(h_from, col=h_colors)
display_degrees(h_to2, col=h_colors)
plot(h_from, h_to2, pch=20, col=h_colors)
par("mfrow"=c(1, 1))
h1 <- c(12.2, 27.3, 47.0, 66.5, 85.9, 106.3, 131.7,
223.1, 263.2, 277.2, 307.7, 345.3, 372.2)
h2 <- rev((seq(from=0, to=360, length.out=13))[c(9:12,1:9)])
h_from <- seq(from=0, to=360, length.out=36)[-36]
h_to <- approx_degrees(h1, h2, h_from)
par("mfrow"=c(2, 2))
display_degrees(h_from, col=h_colors)
display_degrees(h_to, col=h_colors)
plot(h_from, h_to, pch=20, col=h_colors)
par("mfrow"=c(1, 1))
# apply no transform
approx_degrees(h1=0, h2=0, h=c(0, 90, 180, 270))
#> [1] 0 90 180 270
# apply 180 degree transform
approx_degrees(h1=0, h2=180, h=c(0, 90, 180, 270))
#> [1] 180 270 0 90
approx_degrees(h1=180, h2=0, h=c(0, 90, 180, 270))
#> [1] 180 270 0 90
# flip the direction
approx_degrees(h1=c(1, 360), h2=c(359, 0), h=c(0, 90, 180, 270))
#> [1] 0.0000 359.2479 359.4986 359.7493
approx_degrees(h1=c(1, 360), h2=c(359, 0)+90, h=c(0, 90, 180, 270))
#> [1] 90.00000 89.24791 89.49861 89.74930
approx_degrees(h1=c(1, 360)+90, h2=c(359, 0), h=c(0, 90, 180, 270))
#> [1] 359.7493 0.0000 359.2479 359.4986
# verify reverse h2 with break across 0-360
seq1 <- seq(from=0, to=330, by=30)
seq2 <- (rev(seq1) + 120) %% 360
seq_out <- seq(from=0, to=350, by=10);
approx_out <- approx_degrees(h1=seq1, h2=seq2, h=seq_out, verbose=TRUE)
#> ## (13:12:50) 11Dec2024: approx_degrees(): h1h2_df, input:
#> h1 h2 direction h1_diff h2_diff
#> 4 0 90 1 -330 -30
#> 3 30 60 1 30 -30
#> 2 60 30 1 30 -30
#> 1 90 0 1 30 -30
#> 12 120 330 1 30 330
#> 11 150 300 1 30 -30
#> 10 180 270 1 30 -30
#> 9 210 240 1 30 -30
#> 8 240 210 1 30 -30
#> 7 270 180 1 30 -30
#> 6 300 150 1 30 -30
#> 5 330 120 1 30 -30
#> ## (13:12:50) 11Dec2024: approx_degrees(): direction:1
#> ## (13:12:50) 11Dec2024: approx_degrees(): which_flips:2,3,4,6,7,8,9,10,11,12
#> ## (13:12:50) 11Dec2024: approx_degrees(): correcting discontinuity in h2 angles crossing above 360
#> ## (13:12:50) 11Dec2024: approx_degrees(): h1h2_df, expanded:
#> h1 h2 direction h1_diff h2_diff
#> 4 0 90 1 -330 -30
#> 3 30 420 1 30 -30
#> 2 60 750 1 30 -30
#> 1 90 1080 1 30 -30
#> 12 120 1410 1 30 330
#> 11 150 1740 1 30 -30
#> 10 180 2070 1 30 -30
#> 9 210 2400 1 30 -30
#> 8 240 2730 1 30 -30
#> 7 270 3060 1 30 -30
#> 6 300 3390 1 30 -30
#> 5 330 3720 1 30 -30
#> ## (13:12:50) 11Dec2024: h1_min_span:0
#> ## (13:12:50) 11Dec2024: h1_max_span:360
#> ## (13:12:50) 11Dec2024: h1_range_span:360
#> ## (13:12:50) 11Dec2024: h2_min_span:0
#> ## (13:12:50) 11Dec2024: h2_max_span:3,960
#> ## (13:12:50) 11Dec2024: h2_range_span:3,960
#> ## (13:12:50) 11Dec2024: approx_degrees(): h1h2_df (expanded):
#> h1 h2 direction h1_diff h2_diff
#> 4 0 90 1 NA NA
#> 3 30 420 1 30 330
#> 2 60 750 1 30 330
#> 1 90 1080 1 30 330
#> 12 120 1410 1 30 330
#> 11 150 1740 1 30 330
#> 10 180 2070 1 30 330
#> 9 210 2400 1 30 330
#> 8 240 2730 1 30 330
#> 7 270 3060 1 30 330
#> 6 300 3390 1 30 330
#> 5 330 3720 1 30 330
#> 41 360 450 1 30 -3270
#> 31 390 780 1 30 330
#> 21 420 1110 1 30 330
#> 13 450 1440 1 30 330
#> 121 480 1770 1 30 330
#> 111 510 2100 1 30 330
#> 101 540 2430 1 30 330
#> 91 570 2760 1 30 330
#> 81 600 3090 1 30 330
#> 71 630 3420 1 30 330
#> 61 660 3750 1 30 330
#> 51 690 4080 1 30 330
plot(seq1, seq2, pch=20, col="blue", asp=1, ylim=c(0, 360))
points(seq_out, approx_out, col="red", add=TRUE, cex=2)
#> Warning: "add" is not a graphical parameter
# verify forward h2 with break across 0-360
seq1 <- seq(from=0, to=330, by=30)
seq2 <- (seq1 + 120) %% 360
seq_out <- seq(from=0, to=350, by=10);
approx_out <- approx_degrees(h1=seq1, h2=seq2, h=seq_out, verbose=TRUE)
#> ## (13:12:50) 11Dec2024: approx_degrees(): h1h2_df, input:
#> h1 h2 direction h1_diff h2_diff
#> 5 0 120 1 -330 30
#> 6 30 150 1 30 30
#> 7 60 180 1 30 30
#> 8 90 210 1 30 30
#> 9 120 240 1 30 30
#> 10 150 270 1 30 30
#> 11 180 300 1 30 30
#> 12 210 330 1 30 30
#> 1 240 0 1 30 -330
#> 2 270 30 1 30 30
#> 3 300 60 1 30 30
#> 4 330 90 1 30 30
#> ## (13:12:50) 11Dec2024: approx_degrees(): direction:1
#> ## (13:12:50) 11Dec2024: approx_degrees(): which_flips:9
#> ## (13:12:50) 11Dec2024: approx_degrees(): correcting discontinuity in h2 angles crossing above 360
#> ## (13:12:50) 11Dec2024: approx_degrees(): h1h2_df, expanded:
#> h1 h2 direction h1_diff h2_diff
#> 5 0 120 1 -330 30
#> 6 30 150 1 30 30
#> 7 60 180 1 30 30
#> 8 90 210 1 30 30
#> 9 120 240 1 30 30
#> 10 150 270 1 30 30
#> 11 180 300 1 30 30
#> 12 210 330 1 30 30
#> 1 240 360 1 30 -330
#> 2 270 390 1 30 30
#> 3 300 420 1 30 30
#> 4 330 450 1 30 30
#> ## (13:12:50) 11Dec2024: h1_min_span:0
#> ## (13:12:50) 11Dec2024: h1_max_span:360
#> ## (13:12:50) 11Dec2024: h1_range_span:360
#> ## (13:12:50) 11Dec2024: h2_min_span:0
#> ## (13:12:50) 11Dec2024: h2_max_span:720
#> ## (13:12:51) 11Dec2024: h2_range_span:720
#> ## (13:12:51) 11Dec2024: approx_degrees(): h1h2_df (expanded):
#> h1 h2 direction h1_diff h2_diff
#> 5 0 120 1 NA NA
#> 6 30 150 1 30 30
#> 7 60 180 1 30 30
#> 8 90 210 1 30 30
#> 9 120 240 1 30 30
#> 10 150 270 1 30 30
#> 11 180 300 1 30 30
#> 12 210 330 1 30 30
#> 1 240 360 1 30 30
#> 2 270 390 1 30 30
#> 3 300 420 1 30 30
#> 4 330 450 1 30 30
#> 51 360 480 1 30 30
#> 61 390 510 1 30 30
#> 71 420 540 1 30 30
#> 81 450 570 1 30 30
#> 91 480 600 1 30 30
#> 101 510 630 1 30 30
#> 111 540 660 1 30 30
#> 121 570 690 1 30 30
#> 13 600 720 1 30 30
#> 21 630 750 1 30 30
#> 31 660 780 1 30 30
#> 41 690 810 1 30 30
plot(seq1, seq2, pch=20, col="blue", asp=1, ylim=c(0, 360))
points(seq_out, approx_out, col="red", add=TRUE, cex=2)
#> Warning: "add" is not a graphical parameter
new_h1h2 <- adjust_hue_warp(preset="dichromat", h2_shift=15, reverse_h2=TRUE)
hseq <- seq(from=0, to=350, by=15);
approx_degrees(h2=new_h1h2$h1, h1=new_h1h2$h2, h=hseq, verbose=FALSE)
#> [1] 26.60759 81.16162 198.58586 293.17607 336.14153 19.10699 62.07245
#> [8] 105.03791 148.00337 190.96883 233.93429 274.48661 311.31696 348.14732
#> [15] 24.97768 61.80804 291.89394 348.71212 47.51960 111.61568 175.71176
#> [22] 239.80784 303.90392 8.00000