ijlyttle / colorpath

Build Color Paths
https://ijlyttle.github.io/colorpath
Other
0 stars 0 forks source link

API #1

Closed ijlyttle closed 4 years ago

ijlyttle commented 4 years ago

A color-path can be thought-of as a special case of a sequential palette:

All paths in a family will have the same luminance for start and end points. This way, parts of different paths can be joined to create a diverging palette.

ijlyttle commented 4 years ago

Functions to:

ijlyttle commented 4 years ago

The big mistake I made in {paleval} was to use hex-code based colors as the internal representation of a color. A hex-code does not have enough precision to form meaningful derivatives or to show meaningful splines through LUV or HCL space.

I think it would be better to use a colorspace-type color class that uses double precision for each dimension.

ijlyttle commented 4 years ago

cc @haleyjeppson

ijlyttle commented 4 years ago

Given my newly-shaken faith in the "numbers", perhaps we need not rescale the input.

We could ask for points on the spline to be equidistant in LUV space, and rely on that to be "close enough".

In summary:

ijlyttle commented 4 years ago

Thinking in code-sketches now:

I think this can be done entirely using {farver} and {bezier}, which is kind of a shame because the ideas are so strongly inspired by {colorspace}.

To specify using HCL:

# something like
x <- matrix(
  c(h1, c1, l1, h2, c2, l2, ...), 
  nrow = ??, 
  ncol = 3, 
  byrow = TRUE, 
  dimnames = list(NULL, c("h", "c", "l")
)

# it might be easier to convert from a data.frame...

To convert to LUV

farver::convert_colour(x, from = "hcl", to = "luv")

I'll need to check to see if {farver} cares about matrix-column names. At this point, we would have a matrix on which we could make a Bézier spline, using {bezier}.

library("bezier")

## EVENLY_SPACED METHOD ##
## BEZIER CURVE CONTROL POINTS
p <- matrix(c(3,2, 3,0, 5,5), nrow=3, ncol=2, byrow=TRUE)
pob <- pointsOnBezier(p=p, n=10, method="evenly_spaced") # takes a few seconds

str(pob)
List of 3
 $ points: num [1:10, 1:2] 3 3.07 3.46 3.73 3.97 ...
 $ error : num [1:10] 0.00 8.37e-10 8.47e-09 2.89e-08 4.13e-08 ...
 $ t     : num [1:10] 0 0.193 0.48 0.605 0.696 ...

Our splined points would be in a matrix using LUV, so it remains to convert them back to hex:

farver::encode_colour(x, from = "luv")
ijlyttle commented 4 years ago

I claim that a function with S3 class cpath_palette:

I claim that a function with S3 class cpath_rescaler:

With this we can consider set of functions:

# given a data frame of `h`, `c`, `l` values
luv <- function(df_hcl) # returns matrix of luv values

# given matrix of luv values
palette_bezier <- function(luv) # returns cpath_palette
rescaler_bezier <- function(luv) # returns cpath_rescaler

# linear input-rescaler, maps c(0, 1) to `range`
rescaler_linear_input <- function(range) # returns cpath_rescaler

# linear luminance-rescaler, maps c(0, 1) to luminance `range` for `palette`
rescaler_linear_luminance <- function(range, palette) # returns cpath_rescaler

# rescale the input to a palette
rescale_palette <- function(palette, rescaler) # returns cpath_palette

# join two palettes
join_palettes <- function(palette_low, palette_high) # returns cpath_palette

We might also want a a function that takes a cpath_palette and returns a function that returns hexcodes:

palette_hex <- function(palette) # returns palette-function that returns hex-codes

This will get us off the ground, but we might also consider things like derivatives.

We might consider a helper for diverging palettes, as this is a combination of rescaling two palettes, then joining them.

ijlyttle commented 4 years ago

Maybe also a plot() method for cpath_palette, which could build on the colorspace plot.

ijlyttle commented 4 years ago

Want to "simplify" things:

ijlyttle commented 4 years ago

this is largely implemented.