*This is largely adapted from Danielle Navarro’s “Art from Code”
lessons, that go into a lot more detail: https://art-from-code.netlify.app/*

Setup a grid of points, or any set of x and y coordinates

Generate gradient noise for every point on the grid. It represents the vectors that point along the highest gradients in a noise field.

*The gradient noise isn’t actually needed in the final plot but it
helps in illustrating what is happening.*

```
smol_slope <- gradient_noise(
generator = gen_simplex,
seed = 1,
frequency = .1,
x = smol_grid$x,
y = smol_grid$y
)
```

Generate curl noise vectors for every point on the grid, these are perpendicular to the gradient noise vectors and follow the lines of zero gradient in the field.

```
smol_curl <- curl_noise(
generator = gen_simplex,
seed = 1,
frequency = .1,
x = smol_grid$x,
y = smol_grid$y
)
```

Combine grid, and noise vectors into a single data frame

```
smol_field <- smol_grid %>%
mutate(
z = gen_simplex(x, y, seed = 1, frequency = .1),
slope_x = smol_slope$x,
slope_y = smol_slope$y,
curl_x = smol_curl$x,
curl_y = smol_curl$y,
)
```

Plot it with a color map for the “terrain” (the noise field) and arrows for the gradient and curl vectors.

```
ggplot(smol_field) +
geom_contour_filled( aes(x, y, z = z), show.legend = FALSE, bins = 20) +
geom_segment(
mapping = aes(
x = x,
y = y,
xend = x + slope_x * 2,
yend = y + slope_y * 2
),
colour = "white",
arrow = arrow(length = unit(0.1, "cm"))
) +
geom_segment(
mapping = aes(
x = x,
y = y,
xend = x + curl_x * 2,
yend = y + curl_y * 2
),
colour = "black",
arrow = arrow(length = unit(0.1, "cm"))
) +
theme_minimal() +
coord_equal()
```