Skip to content

Commit

Permalink
running tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmonteagudo28 committed Dec 6, 2024
1 parent b0cd9d6 commit 0c5dcbf
Show file tree
Hide file tree
Showing 16 changed files with 582 additions and 270 deletions.
342 changes: 171 additions & 171 deletions .Rhistory

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
Package: sequentially
Title: An R package for non-linear sequence generation using easing functions
Title: An R package for non-linear sequence generation using easing functions based on Robert Penner's easing functions
Version: 0.0.0.9000
Authors@R:
person("JP", "Monteagudo",
email = "[email protected]",
role = c("aut", "cre","cph"),
comment = c(ORCID = "0009-0003-6465-6658"))
Description: This package is born out of curiosity rather than necessity. 'sequentially' creates non-linear and linear numeric sequences. By using non-linear interpolation the user can animate their data
in a way that is more visually pleasing than uniform, linear interpolation. The functions in this package could be used in data visualization,
motion animation, frame interpolation, UI/UX design, population dynamics, economics and finance.
Description: This package is born out of curiosity rather than necessity. 'sequentially' creates non-linear and linear numeric sequences.
By using non-linear interpolation the user can animate their data in a way that is more visually pleasing than uniform, linear interpolation. The functions in this package could be used in data visualization, motion animation, frame interpolation, UI/UX design, population dynamics, economics and finance.
License: GPL (>= 3)
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
URL: https://github.com/jpmonteagudo28/sequentially
Issues: https://github.com/jpmonteagudo28/sequentially/issues

BugReports: https://github.com/jpmonteagudo28/sequentially/issues
Suggests:
spelling,
testthat (>= 3.0.0)
Language: en-US
Config/testthat/edition: 3
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Generated by roxygen2: do not edit by hand

export(seq_smooth)
Empty file added R/seq_color.R
Empty file.
243 changes: 154 additions & 89 deletions R/seq_nl.R
Original file line number Diff line number Diff line change
@@ -1,25 +1,93 @@
#' Generate Non-linear Smooth Sequences with Custom Easing
#'
#' The `seq_smooth` function generates a sequence of numbers between a specified range (`from` to `to`) using different smoothing techniques and easing types. It supports various interpolation methods such as linear, quadratic, cubic, and more. Additionally, easing options (`in`, `out`, and `in_out`) allow for customization of how the transition occurs across the range.
#'
#' @param from A numeric value specifying the starting value of the sequence. Default is 1.
#' @param to A numeric value specifying the ending value of the sequence. Default is 1.
#' @param n An integer specifying the number of points in the sequence. Default is 100.
#' @param type A character string indicating the type of smoothing to apply. Available options include `"linear"`, `"quad"`, `"cubic"`, `"quart"`, `"quint"`, `"exp"`, `"circle"`, `"back"`, `"elastic"`, `"sine"`, `"bounce"`, and `"step"`. Default is `"linear"`.
#' @param step_count An integer specifying the number of discrete steps for the `"step"` type. If `NULL`, defaults to 4.The number of steps cannot exceed 'n'.
#' @param ease A character string indicating the easing direction to apply. Available options are `"in"` (smooth transition at the start), `"out"` (smooth transition at the end), and `"in_out"` (smooth transition at both start and end). Required for non-linear types. Default is `NULL`.
#'
#' @details
#' The function calculates a sequence based on the specified `type` and applies the easing (`ease`) to modify how values progress. For `"linear"` types, no easing is applied, and the sequence is uniformly spaced. For other types, the function supports easing that modifies the progression curve.
#'
#' - **Linear**: A straight-line interpolation.
#' - **Quadratic to Quintic**: Higher-degree polynomial interpolations.
#' - **Exponential**: Exponential interpolation.
#' - **Elastic and Bounce**: Nonlinear interpolations with oscillations.
#' - **Step**: A step-wise progression with discrete levels.
#'
#' The `ease` parameter controls how values are distributed along the sequence:
#' - `"in"`: Starts slow and accelerates.
#' - `"out"`: Starts fast and decelerates.
#' - `"in_out"`: Combines both for a smooth start and end.
#'
#' For `"step"` type, `step_count` specifies the number of steps in the sequence.
#'
#' @return A numeric vector of length `n`, representing the non-linear, smoothed sequence.
#'
#' @examples
#' # Linear sequence from 0 to 10
#' t <- seq(0,1,length.out = 100)
#' lin_seq <- seq_smooth(0, 10, n = 100, type = "linear")
#' plot.new()
#' plot.window(range(t),range(lin_seq))
#' points(t,lin_seq,pch = 16, cex = .75,col = "red")
#' axis(1,tcl = 0.75,lwd = 0, family = "serif")
#' axis(2,lwd = 0, family = "serif", las = 1)
#' grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
#' mtext("Linear Sequence",3,cex = 1.3, family = "serif")
#'
#' # Quadratic easing in sequence
#' quad_seq <- seq_smooth(0, 10, n = 100, type = "quad", ease = "in")
#' plot.new()
#' plot.window(range(t),range(quad_seq))
#' points(t,quad_seq,pch = 16, cex = .75,col = "red")
#' axis(1,tcl = 0.75,lwd = 0, family = "serif")
#' axis(2,lwd = 0, family = "serif", las = 1)
#' grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
#' mtext("Ease-in Quadratic Sequence",3,cex = 1.3, family = "serif")
#'
#' # Step sequence with 5 steps
#' step_seq <- seq_smooth(0, 10, n = 100, type = "step", step_count = 5)
#' plot.new()
#' plot.window(range(t),range(step_seq))
#' lines(t,step_seq,pch = 16, cex = .75,col = "red")
#' axis(1,tcl = 0.75,lwd = 0, family = "serif")
#' axis(2,lwd = 0, family = "serif", las = 1)
#' grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
#' mtext("Step Sequence",3,cex = 1.3, family = "serif")
#'
#' # Elastic easing out sequence
#' elastic_seq <- seq_smooth(0, 10, n = 100, type = "elastic", ease = "out")
#' plot.new()
#' plot.window(range(t),range(elastic_seq))
#' points(t,elastic_seq,pch = 16, cex = .75,col = "red")
#' axis(1,tcl = 0.75,lwd = 0, family = "serif")
#' axis(2,lwd = 0, family = "serif", las = 1)
#' grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
#' mtext("Ease-out Elastic Sequence",3,cex = 1.3, family = "serif")
#'
#' @export


seq_smooth <- function(from = 1, to = 1,
n = 100,
type = "linear",
step_count = NULL,
ease = NULL){

stopifnot(
is.character(type),
is.character(ease)
)
stopifnot(is.character(type))

if(!is.null(ease))
if(!is.character(ease))
stop("Ease must be a characer string of length 1")

type <- match.arg(type,c("linear","quad","cubic","quart",
"quint","exp","circle","back",
"elastic","sine","bounce","step"))

# `in` curves it at the start
#`out` will curve the line at the end
#`in_out` will curve the line at both ends
# Keep in mind there are n - 1 critical points
# as polynomials of size n increases.
ease <- match.arg(ease,c("in","out","in_out"))

# Compute normalized time (t) as the y-component
# Time could be any range, but it complicates comparison if
# time range is not bounded. However, you can always
Expand All @@ -32,34 +100,56 @@ stopifnot(
return(seq)
}

# Issue warning if 'eae' not set to NULL when type is linear
if(type == "linear" & !is.null(ease)) {
warning("No easing applied to linear sequence.")
seq <- from + t*(to-from)
return(seq)
# `in` curves it at the start
#`out` will curve the line at the end
#`in_out` will curve the line at both ends
# Keep in mind there are n - 1 critical points
# as polynomials of size n increases.

# Issue warning if 'ease' not set to NULL when type is linear
if (type != "linear" && type != "step") {
ease <- match.arg(ease, c("in", "out", "in_out"))
}

if(type == "step" & is.null(step_count)){
warning("Step count set to 'NULL'. Using default steps = 4")
step_count = 4
smooth_seq <- from + (to - from)*round(step_count*t)
return(smooth_seq)
} else{
smooth_seq <- from + (to - from)*round(step_count*t)
return(smooth_seq)
# Compute normalized time
t <- seq(0, 1, length.out = n)

# Linear sequence
if (type == "linear") {
seq <- from + t * (to - from)
return(seq)
}

if(type == "step" && !is.null(ease)){
warning("Step function is not continuous and cannot be smoothed using an easing function.\nUsing default steps = 4")
if(is.null(step_count)){step_count = 4
smooth_seq <- from + (to - from)*round(step_count*t)
return(smooth_seq)
} else {
smooth_seq <- from + (to - from)*round(step_count*t)
return(smooth_seq)
# Step sequence
if (type == "step") {

# Handle null or invalid step_count
if (is.null(step_count)) {
warning("Step count is 'NULL'. Using default 'step_count' = 4.")
step_count <- 4
}

# Check step_count limits
if (step_count < 1) {
stop("Invalid 'step_count': Minimum number of steps is 1. Provided: ", step_count)
}
if (step_count > n) {
stop("Invalid 'step_count': Number of steps (", step_count,
") cannot exceed the length of the numeric vector (n = ", n, ").")
}

# Warn if 'ease' is provided (not applicable for steps)
if (!is.null(ease) && !is.na(ease)) {
warning("'ease' has no effect on step functions. Step function is not continuous.")
}

# Compute step sequence
smooth_seq <- from + (to - from) * round(step_count * t) / step_count

return(smooth_seq)
}


# What type of sequence and direction to compute
smooth_fashion <- join_char(type,"_",ease)

Expand Down Expand Up @@ -104,7 +194,7 @@ stopifnot(
(2 - 2^(-20*t+10))/2
))),
#---- --- ---- --- ---- --- ---- --- ----- --- ----#
circle_in = 1 - sqrt(1-t)^2,
circle_in = 1 - sqrt(1-t^2),
circle_out = sqrt(1 - (t - 1)^2),
circle_in_out = ifelse(t < 0.5,
(1 - sqrt(1 - (2 * t)^2)) / 2,
Expand Down Expand Up @@ -142,66 +232,41 @@ stopifnot(
sine_out = sin((t*pi)/2),
sine_in_out = -(cos(t*pi)-1)/2,
#---- --- ---- --- ---- --- ---- --- ----- --- ----#
bounce_in = 1 - ifelse(
(1 - t) < 0.3636,
7.5625 * (1 - t)^2,
ifelse(
(1 - t) < 0.7273,
7.5625 * ((1 - t) - 1.5 / 2.75)^2 + 0.75,
ifelse(
(1 - t) < 0.9091,
7.5625 * ((1 - t) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((1 - t) - 2.625 / 2.75)^2 + 0.984375
)
)
bounce_in = 1 - ifelse((1 - t) < 0.3636,
7.5625 * (1 - t)^2,
ifelse((1 - t) < 0.7273,
7.5625 * ((1 - t) - 1.5 / 2.75)^2 + 0.75,
ifelse((1 - t) < 0.9091,
7.5625 * ((1 - t) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((1 - t) - 2.625 / 2.75)^2 + 0.984375))
),
bounce_out = ifelse(
t < 0.3636,
7.5625 * t^2,
ifelse(
t < 0.7273,
7.5625 * (t - 1.5 / 2.75)^2 + 0.75,
ifelse(
t < 0.9091,
7.5625 * (t - 2.25 / 2.75)^2 + 0.9375,
7.5625 * (t - 2.625 / 2.75)^2 + 0.984375
)
)
bounce_out = ifelse(t < 0.3636,
7.5625 * t^2,
ifelse(t < 0.7273,
7.5625 * (t - 1.5 / 2.75)^2 + 0.75,
ifelse(t < 0.9091,
7.5625 * (t - 2.25 / 2.75)^2 + 0.9375,
7.5625 * (t - 2.625 / 2.75)^2 + 0.984375))
)
,
bounce_in_out = ifelse(
t < 0.5,
0.5 * ifelse(
t * 2 < 0.3636,
7.5625 * (2 * t)^2,
ifelse(
t * 2 < 0.7273,
7.5625 * ((2 * t) - 1.5 / 2.75)^2 + 0.75,
ifelse(
t * 2 < 0.9091,
7.5625 * ((2 * t) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((2 * t) - 2.625 / 2.75)^2 + 0.984375
)
)
),
0.5 * ifelse(
(2 * t - 1) < 0.3636,
7.5625 * (2 * t - 1)^2,
ifelse(
(2 * t - 1) < 0.7273,
7.5625 * ((2 * t - 1) - 1.5 / 2.75)^2 + 0.75,
ifelse(
(2 * t - 1) < 0.9091,
7.5625 * ((2 * t - 1) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((2 * t - 1) - 2.625 / 2.75)^2 + 0.984375
)
)
) + 0.5
),

stop("The specified ease type doesn't exist:", type)

bounce_in_out = ifelse(t < 0.5,
0.5 * ifelse(t * 2 < 0.3636,
7.5625 * (2 * t)^2,
ifelse(t * 2 < 0.7273,
7.5625 * ((2 * t) - 1.5 / 2.75)^2 + 0.75,
ifelse(t * 2 < 0.9091,
7.5625 * ((2 * t) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((2 * t) - 2.625 / 2.75)^2 + 0.984375))),
0.5 * ifelse((2 * t - 1) < 0.3636,
7.5625 * (2 * t - 1)^2,
ifelse((2 * t - 1) < 0.7273,
7.5625 * ((2 * t - 1) - 1.5 / 2.75)^2 + 0.75,
ifelse((2 * t - 1) < 0.9091,
7.5625 * ((2 * t - 1) - 2.25 / 2.75)^2 + 0.9375,
7.5625 * ((2 * t - 1) - 2.625 / 2.75)^2 + 0.984375))) + 0.5
)
)

smooth_seq <- from + smooth_fashion * (to-from)

return(smooth_seq)
Expand Down
25 changes: 23 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,29 @@ install.packages("sequentially")
This is a basic example which shows you how to solve a common problem:

```{r example}
# library(sequentially)
## basic example code
library(sequentially)
# Linear sequence from 0 to 10
t <- seq(0,1,length.out = 100)
lin_seq <- seq_smooth(0, 10, n = 100, type = "linear")
plot.new()
plot.window(range(t),range(lin_seq))
points(t,lin_seq,pch = 16, cex = .75,col = "red")
axis(1,tcl = 0.75,lwd = 0, family = "serif")
axis(2,lwd = 0, family = "serif", las = 1)
grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
mtext("Linear Sequence",3,cex = 1.3, family = "serif")
# Elastic easing out sequence
elastic_seq <- seq_smooth(0, 10, n = 100, type = "elastic", ease = "out")
plot.new()
plot.window(range(t),range(elastic_seq))
points(t,elastic_seq,pch = 16, cex = .75,col = "red")
axis(1,tcl = 0.75,lwd = 0, family = "serif")
axis(2,lwd = 0, family = "serif", las = 1)
grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
mtext("Ease-out Elastic Sequence",3,cex = 1.3, family = "serif")
```

What is special about using `README.Rmd` instead of just `README.md`? You can include R chunks like so:
Expand Down
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,38 @@ install.packages("sequentially")
This is a basic example which shows you how to solve a common problem:

``` r
# library(sequentially)
## basic example code
library(sequentially)

# Linear sequence from 0 to 10
t <- seq(0,1,length.out = 100)
lin_seq <- seq_smooth(0, 10, n = 100, type = "linear")
plot.new()
plot.window(range(t),range(lin_seq))
points(t,lin_seq,pch = 16, cex = .75,col = "red")
axis(1,tcl = 0.75,lwd = 0, family = "serif")
axis(2,lwd = 0, family = "serif", las = 1)
grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
mtext("Linear Sequence",3,cex = 1.3, family = "serif")
```

<img src="man/figures/README-example-1.png" width="100%" />

``` r


# Elastic easing out sequence
elastic_seq <- seq_smooth(0, 10, n = 100, type = "elastic", ease = "out")
plot.new()
plot.window(range(t),range(elastic_seq))
points(t,elastic_seq,pch = 16, cex = .75,col = "red")
axis(1,tcl = 0.75,lwd = 0, family = "serif")
axis(2,lwd = 0, family = "serif", las = 1)
grid(2,3,col = "gray80",lty = "dotted", lwd = 0.50)
mtext("Ease-out Elastic Sequence",3,cex = 1.3, family = "serif")
```

<img src="man/figures/README-example-2.png" width="100%" />

What is special about using `README.Rmd` instead of just `README.md`?
You can include R chunks like so:

Expand Down
Loading

0 comments on commit 0c5dcbf

Please sign in to comment.