1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

入出力がふわっとした状態で HSV を RGB にする試み

Last updated at Posted at 2023-01-26

HSV を RGB に変換するのってどうやるんだっけというのを確認しながらコードに落とし込んだ。
しかも詳細を把握してない状態で入出力についてふわっとした状態で書いた。
なので全然間違ってるかもしれん。

何がふわっとしているのかというと
hue が 0 から 359 なのか 0.0 から 0.999 なのかどうかとか、
RGB の要素だって 0 から 255 までとも限らず、
出力されるのも要素の配列なのか、HTML での色指定の文字列なのかどうか辺り。

ちょっと何言ってるかわからねーと思うし、まだちゃんとしてないが一応それっぽいやつの片鱗を味あわせるぜ。

hsvToRgb.js
const hsvToRgb = function(hue, saturation, value, prophet) {
	if (prophet == null) {
		prophet = {
			saturationIsZero: function(saturation) {
				return !(saturation > 0) && !(saturation < 0);
			},
			saturationRate: function(saturation) {
				return saturation / this.maxSaturation;
			},
			maxSaturation: 255,
			valueRate: function(value) {
				return value / this.maxValue;
			},
			maxValue: 255,
			hueStageAndRate: function(hue) {
				const hueNormalized = hue % 360;
				const hueStage = parseInt(hueNormalized / 60, 10);
				const hueTmp = (parseInt(hue % 60, 10) / 60);
				const hueRate = (hueStage % 2 == 0) ? hueTmp : 1 - hueTmp;
				return [hueStage, hueRate];
			},
			newResult: function(r, g, b) {
				return [r * 255, g * 255, b * 255];
			}
		};
	}

	const valueRate = prophet.valueRate(value);
	if (prophet.saturationIsZero(saturation)) {
		return prophet.newResult(valueRate, valueRate, valueRate);
	}

	const saturationRate = prophet.saturationRate(saturation);
	const min = valueRate - (saturationRate * valueRate);
	const [hueStage, hueRate] = prophet.hueStageAndRate(hue);
	switch (hueStage) {
		case 0: {
			const r = valueRate;
			const g = hueRate * (valueRate - min) + min;
			const b = min;
			return prophet.newResult(r, g, b);
		} break;
		case 1: {
			const r = hueRate * (valueRate - min) + min;
			const g = valueRate;
			const b = min;
			return prophet.newResult(r, g, b);		
		} break;
		case 2: {
			const r = min;
			const g = valueRate;
			const b = hueRate * (valueRate - min) + min;
			return prophet.newResult(r, g, b);		
		} break;
		case 3: {
			const r = min;
			const g = hueRate * (valueRate - min) + min;
			const b = valueRate;
			return prophet.newResult(r, g, b);
		} break;
		case 4: {
			const r = hueRate * (valueRate - min) + min;
			const g = min;
			const b = valueRate;
			return prophet.newResult(r, g, b);
		} break;
		case 5: {
			const r = valueRate;
			const g = min;
			const b = hueRate * (valueRate - min) + min;
			return prophet.newResult(r, g, b);
		} break;
	}

	// unexpected
	return null;
};

const myProphet = {
	saturationIsZero: function(saturation) {
		return !(saturation > 0) && !(saturation < 0);
	},
	saturationRate: function(saturation) {
		return saturation / this.maxSaturation;
	},
	maxSaturation: 1,
	valueRate: function(value) {
		return value / this.maxValue;
	},
	maxValue: 1,
	hueStageAndRate: function(hue) {
		const hueNormalized = hue % 360;
		const hueStage = parseInt(hueNormalized / 60, 10);
		const hueTmp = (parseInt(hue % 60, 10) / 60);
		const hueRate = (hueStage % 2 == 0) ? hueTmp : 1 - hueTmp;
		return [hueStage, hueRate];
	},
	newResult: function(r, g, b) {
		// return [r * 255, g * 255, b * 255];
		const toHex = function(val) {
			const num = parseInt(val, 10);
			const hex = num.toString(16);
			const padded = hex.padStart(2, '0');
			return padded;
		};
		return `#${toHex(r * 255)}${toHex(g * 255)}${toHex(b * 255)}`;
	}			
};
console.log(`red? ${hsvToRgb(0, 0.5, 1, myProphet)}`);
console.log(`yellow? ${hsvToRgb(60, 0.5, 1, myProphet)}`);
console.log(`green? ${hsvToRgb(120, 0.5, 1, myProphet)}`);
console.log(`cyan? ${hsvToRgb(180, 0.5, 1, myProphet)}`);
console.log(`blue? ${hsvToRgb(240, 0.5, 1, myProphet)}`);
console.log(`magenta? ${hsvToRgb(300, 0.5, 1, myProphet)}`);
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?