マンセル色立体 ワイヤーフレーム版(Munsell Color Solid)
マンセル・カラー・システムをPV3Dのワイヤーフレームで簡易的に再現してみました。
色相(h)は回転軸を中心とした360度で、回転軸に遠い方が彩度(s)が高くなり、座標が上に行くほど明度(v)が高くなります。
昨夜ボーッとしながら作ったので間違いがあったため、彩度と明度の表示を入れ替える修正をしました。(2010.09.16)
/**
* Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9rZ9
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.objects.special.ParticleField;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.view.Viewport3D;
import frocessing.color.ColorHSV;
[SWF(width="465", height="465", backgroundColor="0", frameRate="30")]
public class Main extends Sprite {
private const W:int = 465
private const H:int = 465
private var _scene:Scene3D;
private var _camera:Camera3D;
private var _viewport:Viewport3D;
private var _render:BasicRenderEngine;
private var _rootNode:DisplayObject3D;
private var _cube:Cube
public function Main():void {
graphics.beginFill(0)
graphics.drawRect(0, 0, W, H)
graphics.endFill()
//
init3D();
}
private function init3D():void {
_scene = new Scene3D();
_viewport = new Viewport3D(0, 0, true, false);
_rootNode = new DisplayObject3D();
_camera = new Camera3D();
_camera.y = 5
_camera.z = -_camera.focus * _camera.zoom/2;
_render = new BasicRenderEngine();
//
addChild(_viewport);
_scene.addChild(_rootNode);
setObj()
//
_render.renderScene(_scene, _camera, _viewport);
addEventListener(Event.ENTER_FRAME, update);
}
private function setObj():void{
var n:int = 0
var i:int = 0
while(n < 20){
var h:Number = (360 / 20) * n
i = 0
while(i < 20){
var s:Number = Math.random() * 1
var v:Number = i * .05;
if(i%2 != 0) v += .05;
var rgb:int = ColorUtil.hsvToRgb(h, s, v)
var matList:MaterialsList = new MaterialsList({
front: new WireframeMaterial(rgb, 1),
back: new WireframeMaterial(rgb, 1, 1),
right: new WireframeMaterial(rgb, 1, 1),
left: new WireframeMaterial(rgb, 1, 1),
top: new WireframeMaterial(rgb, 1, 1),
bottom: new WireframeMaterial(rgb, 1, 1)
});
//
var cube:Cube = new Cube(matList, 8, 8, 8, 1, 1, 1, 0, 0)
cube.y = v * 160 - 80;
cube.x = Math.cos( h * i * Math.PI / 180 ) * s * 80;
cube.z = Math.sin( h * i * Math.PI / 180 ) * s * 80;
_rootNode.addChild(cube)
//
i++
}
n++
}
}
private function update(e:Event):void{
_render.renderScene(_scene, _camera, _viewport);
_rootNode.rotationY += 0.2;
}
}
}
// ColorUtil
class ColorUtil {
// HSV > RGB
public static function hsvToRgb(h:Number, s:Number, v:Number):Number {
var cv:Number = Math.round(v * 255);
var r:Number = cv;
var g:Number = cv;
var b:Number = cv;
if (s > 0) {
var i:Number = Math.floor(h / 60);
var f:Number = h / 60 - i;
var m:Number = Math.round(v * (1 - s) * 255);
var n:Number = Math.round(v * (1 - s * f) * 255);
var k:Number = Math.round(v * (1 - s * (1 - f)) * 255);
switch (i) {
case 0 :
g = k;
b = m;
break;
case 1 :
r = n;
b = m;
break;
case 2 :
r = m;
b = k;
break;
case 3 :
r = m;
g = n;
break;
case 4 :
r = k;
g = m;
break;
case 5 :
g = m;
b = n;
break;
}
}
return r << 16 | g << 8 | b;
}
// RGB > HSV
public static function colorToHsv(color:Number):Object {
var r:Number = color >> 16;
var g:Number = (color >> 8) & 0xFF;
var b:Number = color & 0xFF;
var max:Number = Math.max(r,Math.max(g,b));
var min:Number = Math.min(r,Math.min(g,b));
var range:Number = max - min;
var h:Number = 0;
var s:Number = 0;
var v:Number = max / 255;
if (v > 0) {
s = range / max;
if (s > 0) {
var cr:Number = (max - r) / range;
var cg:Number = (max - g) / range;
var cb:Number = (max - b) / range;
if (r == max) {
h = cb - cg;
} else if (g == max) {
h = 2 + cr - cb;
} else {
h = 4 + cg - cr;
}
h *= 60;
if (h<0) {
h+=360;
}
}
}
return {h:Math.round(h * 100) * 0.01, s:Math.round(s * 100), v:Math.round(v * 100)};
}
}