Interpolation for degree angles
approx_degrees(
h1,
h2,
h = NULL,
preset = "custom",
direction = 1,
digits = 10,
verbose = FALSE,
...
)
numeric
vector of degree angles, which should
represent the "degree angles from".
numeric
vector of degree angles, which should
represent the "degree angles to".
numeric
or NULL
, where a numeric
vector is a
vector of degree angles "from" that should be converted to
the corresponding interpolated angle "to", When h is NULL
then the object returned is a function
to be called
to convert a numeric vector "from" to degree angles "to".
integer
value indicating the number of digits
of precision to use for the input h1
and h2
degree angles,
used when confining to 360 degrees with h1 %% 360
, and
this step sometimes produces slight variations for equivalent
values. For example ((12.2 %% 360) == (372.2 %% 360))
is not
TRUE
without rounding to 13
or fewer digits.
additional arguments are ignored.
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".
Other colorjam hue warp:
add_colorjam_preset()
,
add_colorjam_step()
,
adjust_hue_warp()
,
colorjam_presets()
,
colorjam_steps()
,
display_degrees()
,
h2hwOptions()
,
h2hw()
,
hcl_to_hsl_hue()
,
hsl_to_hcl_hue()
,
hw2h()
,
mean_angle()
,
plot_colorjam_preset()
,
remap_colorjam_preset()
,
validate_colorjam_preset()
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)
#> ## (11:02:41) 20Sep2023: 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
#> ## (11:02:41) 20Sep2023: approx_degrees(): direction:1
#> ## (11:02:41) 20Sep2023: approx_degrees(): which_flips:2,3,4,6,7,8,9,10,11,12
#> ## (11:02:41) 20Sep2023: approx_degrees(): correcting discontinuity in h2 angles crossing above 360
#> ## (11:02:41) 20Sep2023: 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
#> ## (11:02:41) 20Sep2023: h1_min_span:0
#> ## (11:02:41) 20Sep2023: h1_max_span:360
#> ## (11:02:41) 20Sep2023: h1_range_span:360
#> ## (11:02:41) 20Sep2023: h2_min_span:0
#> ## (11:02:41) 20Sep2023: h2_max_span:3960
#> ## (11:02:41) 20Sep2023: h2_range_span:3960
#> ## (11:02:41) 20Sep2023: 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)
#> ## (11:02:41) 20Sep2023: 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
#> ## (11:02:41) 20Sep2023: approx_degrees(): direction:1
#> ## (11:02:41) 20Sep2023: approx_degrees(): which_flips:9
#> ## (11:02:41) 20Sep2023: approx_degrees(): correcting discontinuity in h2 angles crossing above 360
#> ## (11:02:41) 20Sep2023: 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
#> ## (11:02:41) 20Sep2023: h1_min_span:0
#> ## (11:02:41) 20Sep2023: h1_max_span:360
#> ## (11:02:41) 20Sep2023: h1_range_span:360
#> ## (11:02:41) 20Sep2023: h2_min_span:0
#> ## (11:02:41) 20Sep2023: h2_max_span:720
#> ## (11:02:41) 20Sep2023: h2_range_span:720
#> ## (11:02:41) 20Sep2023: 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