# materialSpectra: compute standard material spectra In colorSpec: Color Calculations with Emphasis on Spectral Data

## Description

Compute neutral gray material constant reflectance/transmittance, and rectangular spectra. Also compute absorbance of the human lens, as a function of age.

## Usage

 1 2 3 4 neutralMaterial( gray=1, wavelength=380:780 ) rectangularMaterial( lambda, alpha=1, wavelength=380:780 ) lensAbsorbance( age=32, wavelength=400:700 ) 

## Arguments

 gray a numeric N-vector of gray levels, in the interval [0,1]. gray=1 represents the Perfect Reflecting Diffuser. lambda a numeric Nx2 matrix with wavelength pairs in the rows, or a vector that can be converted to such a matrix, by row. The two wavelengths are the two transition wavelengths of the returned spectrum, see Details. alpha a numeric N-vector of chromatic amplitudes in the interval [-1,1]. N must be equal to nrow(lambda). alpha can also be a single number, which is then replicated to length nrow(lambda). The chromatic amplitude is defined by Logvinenko and controls the size of both transitions, see Details. age a numeric N-vector of ages in years; all ages must be ≥ 20. wavelength a vector of wavelengths for the returned object

## Details

A rectangular spectrum, or rectangular metamer, is easiest to define when α=1 and λ_1 < λ_2. In this case it is a band-pass filter with transmittance=1 for λ \in [λ_1 , λ_2] and transmittance=0 otherwise. To create a long-pass filter, just set λ_2 to Inf, or any large wavelength outside the spectrum range; and similarly for a short-pass filter.
When 0<α<1 the spectrum is a weighted mixture of this band-pass filter with a perfect neutral gray filter with transmittance=0.5 at all λ, using α and 1-α as the two weights. The minimum transmittance is (1-α)/2 and the maximum is (1+α)/2, and their difference, the chromatic amplitude, is α. It is still a band-pass filter.
If α=0 the spectrum is a perfect neutral with transmittance=0.5.
To "flip" the spectrum to its complement (change band-pass to band-stop, etc.), change α to a negative number, or swap λ_1 and λ_2. If λ_1==λ_2 then the spectrum is undefined and a warning is issued (unless α=0).

## Value

neutralMaterial() returns a colorSpec object with quantity equal to 'reflectance'. The reflectance of each spectrum is constant and taken from gray. There are N spectra in the object - one for each gray level.

rectangularMaterial() returns a colorSpec object with quantity equal to 'transmitance'. The transmitance of each spectrum is a step function with 0, 1 or 2 transitions (jumps) defined by the corresponding row in lambda. If rownames(lambda) is not NULL, they are copied to specnames of the output. Otherwise the specnames are computed from the shape of the spectrum using these acronyms: LP (long-pass), SP (short-pass), BP (band-pass), BS (band-stop), and N (neutral, in case alpha==0).

lensAbsorbance() returns a colorSpec object with quantity equal to 'absorbance'. The absorbance model for the human lens is taken from Pokorny. There are N spectra in the object - one for each age (N=length(age)).

## Logvinenko

It is clear that there are 3 degrees-of-freedom in the spectra returned by rectangularMaterial(). Logvinenko shows that these spectra in fact form a 3D ball, which he calls the rectangle color atlas. He also shows that if a material responder satisfies the 2-transition condition, then these spectra uniquely generate all colors in the corresponding object color solid. For more on this, see the inversion vignette.

## Ostwald

Every spectrum returned by rectangularMaterial() is an Ostwald ideal spectrum. In Ostwald's terminology, the color content = chromatic amplitude = α. And the black content = white content = (1-α)/2. Note that the sum of these 3 contents is 1. However, Ostwald allows black content and white content to be unequal, as long as the sum of the 3 contents is 1, and all are non-negative. Thus there is one extra degree-of-freedom for Ostwald's ideal spectra, for a total of 4 degrees-of-freedom. If an additional argument (or arguments) were added to rectangularMaterial(), then it could return all Ostwald ideal spectra.

## References

Foss, Carl E. and Dorothy Nickerson and Walter C. Granville. Analysis of the Ostwald Color System. J. Opt. Soc. Am.. vol. 34. no. 7. pp. 361-381. July, 1944.

Logvinenko, A. D. An object-color space. Journal of Vision. 9(11):5, 1-23, (2009). https://jov.arvojournals.org/article.aspx?articleid=2203976. doi:10.1167/9.11.5.

Pokorny, Joel, Vivianne C. Smith, and Margaret Lutze. Aging of the Human Lens. Applied Optics. Vol. 26, No. 8. 15 April 1987. Table I. Page 1439.

lightSpectra, quantity(), specnames(), computeADL(), vignette inversion
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 # make a perfect reflecting diffuser (PRD) prd = neutralMaterial( 1 ) # make a perfect transmitting filter (PTF) ptf = prd quantity(ptf) = 'transmittance' # make a band-stop filter (for interval [500,550]) # with 1% transmittance in the band, and 99% outside the band bs = rectangularMaterial( c(500,550), -0.98, 400:700 ) bs = rectangularMaterial( c(550,500), 0.98, 400:700 ) # equivalent to previous line # compare transmittance at 3 ages: 20, 32, and 80 years plot( linearize(lensAbsorbance( c(20,32,80) )), col='black', lty=1:3 )