Spectre
http://k-hiura.cocolog-nifty.com/blog/2009/06/post-9c5b.html
Up : My method using 6th order polynomial whose coefficients are derived from rgbTable quoted from above URL
Down : The original method
I think this method is not suitable for exact spectre calculation, but sufficient for faked graphics.
/**
* Copyright phi16 ( http://wonderfl.net/user/phi16 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7eU6
*/
package {
import flash.display.Sprite;
public class Spectre extends Sprite {
public var spr:Sprite=new Sprite();
public function Spectre() {
spr.graphics.beginFill(0);
spr.graphics.drawRect(0,0,465,465);
spr.graphics.endFill();
for(var i:int=0;i<465;i++){
var wl:Number=interpolate(i/465.0,380,780);
spr.graphics.lineStyle(1.0,spectreRGB(wl));
spr.graphics.moveTo(i,150);
spr.graphics.lineTo(i,465/2.0);
spr.graphics.lineStyle(1.0,wlen2rgb(wl));
spr.graphics.moveTo(i,465/2.0);
spr.graphics.lineTo(i,465-150);
}
this.addChild(spr);
}
}
}
function interpolate(x:Number,a:Number,b:Number):Number{
return a+x*(b-a);
}
function spectreRGB(x:Number):int{
if(x<380)return 0;
else if(x>780)return 0;
var data:Array=[ //6桁だとものすごいバグる
[4.010353218,-80.63249483,631.7030634,-2340.443417,3649.476495,0,-4177.888781],
[0.277385381,-11.15063994,185.6265588,-1637.093036,8062.307429,-21008.39274,22614.05094],
[-0.105722006,2.746241678,-27.82592878,133.2858701,-268.2029047,0,505.990267],
[-8.591709666,229.2801983,-2539.539977,14942.14013,-49253.65203,86238.82071,-62662.66903],
[-2.50432e-05,0.000231452,0,0,0,0,-1.042682898],
[0,0,0,0,0,0,0]];
var ri:int=x<470?0:x<550?5:1;
var gi:int=x<460?5:x<610?2:5;
var bi:int=x<520?3:x<760?5:4;
x/=100;
var r:Number=0,g:Number=0,b:Number=0;
for(var i:int=0;i<7;i++){
r=r*x+data[ri][i];
g=g*x+data[gi][i];
b=b*x+data[bi][i];
}
var rs:int=Math.max(0,Math.min(1,r))*255;
var gs:int=Math.max(0,Math.min(1,g))*255;
var bs:int=Math.max(0,Math.min(1,b))*255;
return (rs<<16)+(gs<<8)+bs;
}
var rgbTable:Array = [
{ L:380 ,R:0.06076 ,G:0.00000 ,B:0.11058 }
,{ L:390 ,R:0.08700 ,G:0.00000 ,B:0.16790 }
,{ L:400 ,R:0.13772 ,G:0.00000 ,B:0.26354 }
,{ L:410 ,R:0.20707 ,G:0.00000 ,B:0.39852 }
,{ L:420 ,R:0.31129 ,G:0.00000 ,B:0.60684 }
,{ L:430 ,R:0.39930 ,G:0.00000 ,B:0.80505 }
,{ L:440 ,R:0.40542 ,G:0.00000 ,B:0.87684 }
,{ L:450 ,R:0.34444 ,G:0.00000 ,B:0.88080 }
,{ L:460 ,R:0.11139 ,G:0.00000 ,B:0.86037 }
,{ L:470 ,R:0.00000 ,G:0.15233 ,B:0.77928 }
,{ L:480 ,R:0.00000 ,G:0.38550 ,B:0.65217 }
,{ L:490 ,R:0.00000 ,G:0.49412 ,B:0.51919 }
,{ L:500 ,R:0.00000 ,G:0.59271 ,B:0.40008 }
,{ L:510 ,R:0.00000 ,G:0.69549 ,B:0.25749 }
,{ L:520 ,R:0.00000 ,G:0.77773 ,B:0.00000 }
,{ L:530 ,R:0.00000 ,G:0.81692 ,B:0.00000 }
,{ L:540 ,R:0.00000 ,G:0.82625 ,B:0.00000 }
,{ L:550 ,R:0.00000 ,G:0.81204 ,B:0.00000 }
,{ L:560 ,R:0.47369 ,G:0.77626 ,B:0.00000 }
,{ L:570 ,R:0.70174 ,G:0.71523 ,B:0.00000 }
,{ L:580 ,R:0.84922 ,G:0.62468 ,B:0.00000 }
,{ L:590 ,R:0.94726 ,G:0.49713 ,B:0.00000 }
,{ L:600 ,R:0.99803 ,G:0.31072 ,B:0.00000 }
,{ L:610 ,R:1.00000 ,G:0.00000 ,B:0.00000 }
,{ L:620 ,R:0.95520 ,G:0.00000 ,B:0.00000 }
,{ L:630 ,R:0.86620 ,G:0.00000 ,B:0.00000 }
,{ L:640 ,R:0.76170 ,G:0.00000 ,B:0.00000 }
,{ L:650 ,R:0.64495 ,G:0.00000 ,B:0.00000 }
,{ L:660 ,R:0.52857 ,G:0.00000 ,B:0.00000 }
,{ L:670 ,R:0.41817 ,G:0.00000 ,B:0.00000 }
,{ L:680 ,R:0.33202 ,G:0.00000 ,B:0.00000 }
,{ L:690 ,R:0.25409 ,G:0.00000 ,B:0.00000 }
,{ L:700 ,R:0.19695 ,G:0.00000 ,B:0.00000 }
,{ L:710 ,R:0.15326 ,G:0.00000 ,B:0.00000 }
,{ L:720 ,R:0.11902 ,G:0.00000 ,B:0.00000 }
,{ L:730 ,R:0.09063 ,G:0.00000 ,B:0.00000 }
,{ L:740 ,R:0.06898 ,G:0.00000 ,B:0.00000 }
,{ L:750 ,R:0.05150 ,G:0.00000 ,B:0.00000 }
,{ L:760 ,R:0.04264 ,G:0.00000 ,B:0.00000 }
,{ L:770 ,R:0.03666 ,G:0.00000 ,B:0.00794 }
,{ L:780 ,R:0.00000 ,G:0.00000 ,B:0.00000 }
];
var wlenStep:Number = 10;
var wlenMin:Number = 380;
var wlenMax:Number = 780;
function wlen2rgb(wlen:Number):int{
wlen = Math.max(wlenMin,wlen);
wlen = Math.min(wlenMax,wlen);
var widx:int = (wlen-wlenMin)/wlenStep;
var wlenSub:Number = (wlen-wlenMin)-(widx*wlenStep);
var ret:Object = new Object();
ret.R = rgbTable[widx].R;
ret.G = rgbTable[widx].G;
ret.B = rgbTable[widx].B;
//if( wlenSub==0 ) return 0;
var rate:Number = wlenSub/wlenStep;
ret.R += (rgbTable[widx+1].R-rgbTable[widx].R)*rate;
ret.G += (rgbTable[widx+1].G-rgbTable[widx].G)*rate;
ret.B += (rgbTable[widx+1].B-rgbTable[widx].B)*rate;
var r:int=ret.R*255;
var g:int=ret.G*255;
var b:int=ret.B*255;
return (r<<16)+(g<<8)+b;
}