cacatoo
Version:
Building, exploring, and sharing spatially structured models
174 lines (158 loc) • 5.2 kB
JavaScript
/**
* Reverse dictionary
* @param {Object} obj dictionary-style object to reverse in order
*/
export function dict_reverse(obj) {
let new_obj = {}
let rev_obj = Object.keys(obj).reverse();
rev_obj.forEach(function (i) {
new_obj[i] = obj[i];
})
return new_obj;
}
/**
* Randomly shuffle an array with custom RNG
* @param {Array} array array to be shuffled
* @param {MersenneTwister} rng MersenneTwister RNG
*/
export function shuffle(array, rng) {
let i = array.length;
while (i--) {
const ri = Math.floor(rng.random() * (i + 1));
[array[i], array[ri]] = [array[ri], array[i]];
}
return array;
}
/**
* Convert colour string to RGB. Works for colour names ('red','blue' or other colours defined in cacatoo), but also for hexadecimal strings
* @param {String} string string to convert to RGB
*/
export function stringToRGB(string) {
if (string[0] != '#') return nameToRGB(string)
else return hexToRGB(string)
}
/**
* Convert hexadecimal to RGB
* @param {String} hex string to convert to RGB
*/
export function hexToRGB(hex) {
var result
if(hex.length == 7) {
result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]
}
if(hex.length == 9) {
result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16), parseInt(result[4], 16)]
}
}
/**
* Convert colour name to RGB
* @param {String} name string to look up in the set of known colours (see below)
*/
export function nameToRGB(string) {
let colours = {
'black': [0, 0, 0],
'white': [255, 255, 255],
'red': [255, 0, 0],
'blue': [0, 0, 255],
'green': [0, 255, 0],
'darkgrey': [40, 40, 40],
'lightgrey': [180, 180, 180],
'violet': [148, 0, 211],
'turquoise': [64, 224, 208],
'orange': [255, 165, 0],
'gold': [240, 200, 0],
'grey': [125, 125, 125],
'yellow': [255, 255, 0],
'cyan': [0, 255, 255],
'aqua': [0, 255, 255],
'silver': [192, 192, 192],
'nearwhite': [192, 192, 192],
'purple': [128, 0, 128],
'darkgreen': [0, 128, 0],
'olive': [128, 128, 0],
'teal': [0, 128, 128],
'navy': [0, 0, 128]
}
let c = colours[string]
if (c == undefined) throw new Error(`Cacatoo has no colour with name '${string}'`)
return c
}
/**
* Make sure all colours, even when of different types, are stored in the same format (RGB, as cacatoo uses internally)
* @param {Array} cols array of strings, or [R,G,B]-arrays. Only strings are converted, other returned.
*/
export function parseColours(cols) {
let return_cols = []
for (let c of cols) {
if (typeof c === 'string' || c instanceof String) {
return_cols.push(stringToRGB(c))
}
else {
return_cols.push(c)
}
}
return return_cols
}
/**
* Compile a dict of default colours if nothing is given by the user. Reuses colours if more colours are needed.
*/
export function default_colours(num_colours)
{
let colour_dict = [
[0, 0, 0], // black
[255, 255, 255], // white
[255, 0, 0], // red
[0, 0, 255], // blue
[0, 255, 0], //green
[60, 60, 60], //darkgrey
[180, 180, 180], //lightgrey
[148, 0, 211], //violet
[64, 224, 208], //turquoise
[255, 165, 0], //orange
[240, 200, 0], //gold
[125, 125, 125],
[255, 255, 0], // yellow
[0, 255, 255], // cyan
[192, 192, 192], // silver
[0, 128, 0], //darkgreen
[128, 128, 0], // olive
[0, 128, 128], // teal
[0, 0, 128]] // navy
let return_dict = {}
for(let i = 0; i < num_colours; i++)
{
return_dict[i] = colour_dict[i%19]
}
return return_dict
}
/**
* A list of default colours if nothing is given by the user.
*/
export function random_colours(num_colours,rng)
{
let return_dict = {}
return_dict[0] = [0,0,0]
for(let i = 1; i < num_colours; i++)
{
return_dict[i] = [rng.genrand_int(0,255),rng.genrand_int(0,255),rng.genrand_int(0,255)]
}
return return_dict
}
/**
* Deep copy function.
* @param {Object} aObject Object to be deep copied. This function still won't deep copy every possible object, so when enabling deep copying, make sure you put your debug-hat on!
*/
export function copy(aObject) {
if (!aObject) {
return aObject;
}
let v;
let bObject = Array.isArray(aObject) ? [] : {};
for (const k in aObject) {
v = aObject[k];
bObject[k] = (typeof v === "object") ? copy(v) : v;
}
return bObject;
}