You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
3.8 KiB
140 lines
3.8 KiB
4 years ago
|
// Cubehelix color scheme for Max/MSP/Jitter
|
||
4 years ago
|
// By Théophile Clet
|
||
|
// https://tflcl.xyz
|
||
|
//
|
||
|
// Based on Dave Green's work:
|
||
|
// http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/cubetry.html
|
||
|
//
|
||
|
// Original publication: Green, D. A., 2011, `A colour scheme for the display of astronomical intensity images', Bulletin of the Astronomical Society of India, 39, 289. (2011BASI...39..289G at ADS.)
|
||
|
// http://astron-soc.in/bulletin/11June/289392011.pdf )
|
||
|
//
|
||
|
// Original js code taken straight from the online example implementation:
|
||
|
// http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/cubetry.html
|
||
|
|
||
|
|
||
4 years ago
|
autowatch = 0;
|
||
4 years ago
|
inlets = 1;
|
||
4 years ago
|
outlets = 4;
|
||
|
|
||
|
var RGBOUTLET = 0;
|
||
|
var HSLOUTLET = 1;
|
||
|
var LISTOUTLET = 2
|
||
|
var DUMPOUTLET = 3;
|
||
4 years ago
|
|
||
|
setinletassist(0, "List as input: {makeCubehelixRGB, start[float], rots[float], sign[-1,1], hue[float], gamma[float], levels(int), flip([0,1]}")
|
||
4 years ago
|
setoutletassist(0, "To jit.matrix: always outputs the color palette as a ARGB 4-plane matrix");
|
||
|
setoutletassist(1, "To jit.matrix: if 'hslenable 1' outputs the color palette as a AHSL 4-plane matrix");
|
||
|
setoutletassist(2, "If 'listmode 1' outputs all colors in list format as RGB or HSL.");
|
||
|
setoutletassist(3, "Bangs when generation is done.");
|
||
4 years ago
|
|
||
4 years ago
|
var hslmode = false;
|
||
|
var listmode = false;
|
||
|
|
||
|
function hslenable(s){
|
||
|
hslmode = s;
|
||
|
}
|
||
|
function listenable(s){
|
||
|
listmode = s;
|
||
|
}
|
||
|
|
||
|
function makeCubehelix(start, rots, hue, gamma, levels, flip){
|
||
4 years ago
|
|
||
|
//dumpOut(start, rots, hue, gamma, levels, flip);
|
||
4 years ago
|
outlet(RGBOUTLET, "dim", levels, 1);
|
||
|
if (hslmode) {
|
||
|
outlet(HSLOUTLET, "dim", levels, 1);
|
||
|
}
|
||
|
|
||
4 years ago
|
|
||
|
for (var i = 0; i < levels; i++) {
|
||
|
|
||
4 years ago
|
|
||
4 years ago
|
var fract = CubeHelixFract(i,levels,flip);
|
||
4 years ago
|
var color = CubeHelixRGB(fract,start,rots,hue,gamma);
|
||
|
|
||
4 years ago
|
|
||
|
if(flip == 1){fract = 1.0-fract;}
|
||
|
|
||
4 years ago
|
outlet(RGBOUTLET, "setcell", i, 0, "val", 1., color);
|
||
|
|
||
|
if (hslmode) {
|
||
|
color = rgb2hsl(color[0], color[1], color[2]);
|
||
|
outlet(HSLOUTLET, "setcell", i, 0, "val", 1., color);
|
||
|
}
|
||
|
|
||
|
if (listmode) { outlet(LISTOUTLET, i, color); }
|
||
|
|
||
4 years ago
|
}
|
||
4 years ago
|
|
||
|
outlet(RGBOUTLET, "bang");
|
||
|
if (hslmode) { outlet(HSLOUTLET, "bang"); }
|
||
|
if (listmode) { outlet(LISTOUTLET, "bang"); }
|
||
|
|
||
|
outlet(DUMPOUTLET, "bang");
|
||
4 years ago
|
}
|
||
|
|
||
|
function dumpOut(start, rots, hue, gamma, levels, flip){
|
||
4 years ago
|
outlet(DUMPOUTLET, "start", start);
|
||
|
outlet(DUMPOUTLET, "rots", rots);
|
||
|
outlet(DUMPOUTLET, "hue", hue);
|
||
|
outlet(DUMPOUTLET, "gamma", gamma);
|
||
|
outlet(DUMPOUTLET, "levels", levels);
|
||
|
outlet(DUMPOUTLET, "flip", flip);
|
||
|
}
|
||
|
|
||
|
function rgb2hsl(r,g,b) {
|
||
|
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||
|
var h, s, l = (max + min) / 2;
|
||
|
|
||
|
if (max == min) {
|
||
|
h = s = 0; // achromatic
|
||
|
} else {
|
||
|
var d = max - min;
|
||
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||
|
|
||
|
switch (max) {
|
||
|
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||
|
case g: h = (b - r) / d + 2; break;
|
||
|
case b: h = (r - g) / d + 4; break;
|
||
|
}
|
||
|
|
||
|
h /= 6;
|
||
|
}
|
||
|
|
||
|
return [ h, s, l ];
|
||
4 years ago
|
}
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// 2017 May 30: make consistent with Fortran
|
||
4 years ago
|
// 2021 mai 12: a bit of calculation optimization (I think) - Théophile Clet
|
||
4 years ago
|
// ----------------------------------------------------------------------------
|
||
|
|
||
4 years ago
|
function CubeHelixRGB(fract,start,rots,hue,gamma){
|
||
4 years ago
|
|
||
|
var angle = 2*Math.PI*(start/3.0+1+rots*fract);
|
||
|
var fract = Math.pow(fract, gamma);
|
||
|
var amp=hue*fract*(1-fract)/2.0;
|
||
4 years ago
|
var acos = Math.cos(angle);
|
||
|
var asin = Math.sin(angle);
|
||
4 years ago
|
|
||
4 years ago
|
var r=fract+amp*(-0.14861*acos+1.78277*asin);
|
||
4 years ago
|
r=Math.max(Math.min(r,1.0),0.0);
|
||
4 years ago
|
|
||
4 years ago
|
var g=fract+amp*(-0.29227*acos-0.90649*asin);
|
||
4 years ago
|
g=Math.max(Math.min(g,1.0),0.0);
|
||
4 years ago
|
|
||
4 years ago
|
var b=fract+amp*(+1.97294*acos);
|
||
4 years ago
|
b=Math.max(Math.min(b,1.0),0.0);
|
||
|
|
||
4 years ago
|
return [r, g, b];
|
||
4 years ago
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
function CubeHelixFract(i,n,flip){
|
||
|
var fraction = i/(n-1);
|
||
|
if (flip == 1) {
|
||
|
fraction = 1 - fraction;
|
||
|
}
|
||
|
return fraction;
|
||
|
}
|