R/gradient.R

Defines functions gradient_noise

Documented in gradient_noise

#' Calculate the gradient of a scalar field
#'
#' The gradient of a scalar field such as those generated by the different noise
#' algorithms in ambient is a vector field encoding the direction to move to get
#' the strongest increase in value. The vectors generated have the properties of
#' being perpendicular on the contour line drawn through that point. Take note
#' that the returned vector field flows upwards, i.e. points toward the steepest
#' ascend, rather than what is normally expected in a gravitational governed
#' world.
#'
#' @inheritParams curl_noise
#' @param x,y,z,t The coordinates to generate the gradient for as unquoted expressions
#' @param seed A seed for the generator.
#'
#' @export
#'
#' @family derived values
#'
#' @examples
#' grid <- long_grid(seq(0, 1, l = 100), seq(0, 1, l = 100))
#'
#' # Use one of the generators
#' grid$gradient <- gradient_noise(gen_simplex, x = grid$x, y = grid$y)
#' plot(grid$x, grid$y, type = 'n')
#' segments(grid$x, grid$y, grid$x + grid$gradient$x / 100, grid$y + grid$gradient$y / 100)
#'
gradient_noise <- function(generator, x, y, z = NULL, t = NULL, ..., seed = NULL, delta = NULL) {
  if (is.null(seed)) seed <- random_seed()
  if (is.null(delta)) {
    delta <- max(diff(range(x)), diff(range(y %||% 0)), diff(range(z %||% 0)), diff(range(t %||% 0))) * 1e-4
  }
  gradient <- list(
    x = (generator(x + delta, y, z, t, seed = seed, ...) - generator(x - delta, y, z, t, seed = seed, ...)) / (2 * delta)
  )
  if (!is.null(y)) {
    gradient$y <- (generator(x, y + delta, z, t, seed = seed, ...) - generator(x, y - delta, z, t, seed = seed, ...)) / (2 * delta)
  }
  if (!is.null(z)) {
    gradient$z <- (generator(x, y, z + delta, t, seed = seed, ...) - generator(x, y, z - delta, t, seed = seed, ...)) / (2 * delta)
  }
  if (!is.null(t)) {
    gradient$t <- (generator(x, y, z, t + delta, seed = seed, ...) - generator(x, y, z, t - delta, seed = seed, ...)) / (2 * delta)
  }
  as.data.frame(gradient)
}

Try the ambient package in your browser

Any scripts or data that you put into this service are public.

ambient documentation built on Sept. 8, 2022, 5:07 p.m.