(趣味程序)可见光光谱的绘制
2006-12-11 13:23
267 查看
作者:Y___Y
联系:yinwei_88@sina.com
本文根据相关的数据绘制了可见光(波长从380nm到780nm)的光谱,读者可根据该光谱迅速的知道某个波长 所对应的光的颜色,本文用三次样条插值来拟合波长与颜色的变化曲线,从而更加准确的表达波长与颜色的变化规律。数据资料来源:http://www.cgan.net/book/books/print/packcolor/link/5-4-2.html。
主要代码(MFC单文档):
#include "stdio.h"
double wavelen[81],red[81],green[81],blue[81];//存储波长,红绿蓝的离散数据
//读数据文件
int ReadSpectrumFile()
...{
int i=0,temp;
float r,g,b;
FILE *fp;
fp=fopen("spectrum.txt","r");
if(!fp)
return 0;
while(!feof(fp))
...{
fscanf(fp,"%d%f%f%f",&temp,&r,&g,&b);
wavelen[i]=(double)temp;
red[i]=r;
green[i]=g;
blue[i]=b;
fscanf(fp,"%f%f%f",&r,&g,&b);//空的,不对刺激值
if(i>=80)
break;
i++;
}
fclose(fp);
return 1;
}
//三次样条插值函数
double GetValueSpline(int n, double x[], double y[], double t)
...{
int i,j;
double h0,h1,alpha,beta,*s,z,*dy;
dy=new double
;
for(i=0;i<n;i++)dy[i]=0.0;
// 初值
s=new double
;
s[0]=dy[0];
dy[0]=0.0;
h0=x[1]-x[0];
for (j=1;j<=n-2;j++)
...{
h1=x[j+1]-x[j];
alpha=h0/(h0+h1);
beta=(1.0-alpha)*(y[j]-y[j-1])/h0;
beta=3.0*(beta+alpha*(y[j+1]-y[j])/h1);
dy[j]=-alpha/(2.0+(1.0-alpha)*dy[j-1]);
s[j]=(beta-(1.0-alpha)*s[j-1]);
s[j]=s[j]/(2.0+(1.0-alpha)*dy[j-1]);
h0=h1;
}
for (j=n-2;j>=0;j--)dy[j]=dy[j]*dy[j+1]+s[j];
for (j=0;j<=n-2;j++)s[j]=x[j+1]-x[j];
if (t>=x[n-1])i=n-2;
else
...{
i=0;
while (t>x[i+1])
i=i+1;
}
h1=(x[i+1]-t)/s[i];
h0=h1*h1;
z=(3.0*h0-2.0*h0*h1)*y[i];
z=z+s[i]*(h0-h0*h1)*dy[i];
h1=(t-x[i])/s[i];
h0=h1*h1;
z=z+(3.0*h0-2.0*h0*h1)*y[i+1];
z=z-s[i]*(h0-h0*h1)*dy[i+1];
delete[] s;
delete[] dy;
return(z);
}
//绘制光谱
void CSpectrumView::OnDraw(CDC* pDC)
...{
CSpectrumDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
double r,g,b;
CRect rect;
rect.top=10;
rect.bottom=200;
rect.left=10;
for(int i=0;i<=400;i++)
...{
rect.right=rect.left+1;
r=GetValueSpline(81,wavelen,red,380.0+i);
g=GetValueSpline(81,wavelen,green,380.0+i);
b=GetValueSpline(81,wavelen,blue,380.0+i);
pDC->FillSolidRect(&rect,RGB(int(255.0*r),int(255.0*g),int(255.0*b)));
rect.left++;
}
//画标尺
pDC->SetBkMode(TRANSPARENT);
pDC->MoveTo(10,200);
pDC->LineTo(10,225);
pDC->TextOut(10,200,"380纳米");
pDC->MoveTo(210,200);
pDC->LineTo(210,225);
pDC->TextOut(210,200,"580纳米");
pDC->MoveTo(410,200);
pDC->LineTo(410,225);
pDC->TextOut(410,200,"780纳米");
}
数据文件格式
380
0.1741
0.0050
0.8209
0.00145
0.0000
0.0065
385
0.1740
0.0050
0.8210
0.0022
0.0001
0.0105
第一条为波长数据,接下来三行为红绿蓝的分量,最后三个为各色的刺激值(这里没用上)。
效果图
注:实际上,根据量子力学,实际的光谱是不连续的。
文件内容
380
0.1741
0.0050
0.8209
0.00145
0.0000
0.0065
385
0.1740
0.0050
0.8210
0.0022
0.0001
0.0105
390
0.1738
0.0049
0.8213
0.0042
0.0001
0.0201
395
0.1736
0.0049
0.8215
0.0076
0.0002
0.0362
400
0.1733
0.0048
0.8219
0.0143
0.0004
0.0679
405
0.1730
0.0048
0.8222
0.0232
0.0006
0.1102
410
0.1726
0.0048
0.8226
0.0435
0.0012
0.2074
415
0.1721
0.0048
0.8231
0.0776
0.0022
0.3713
420
0.1714
0.0051
0.8235
0.1344
0.0040
0.6456
425
0.1703
0.0058
0.8239
0.2148
0.0073
1.0391
430
0.1689
0.0069
0.8242
0.2839
0.0116
1.3856
435
0.1669
0.0086
0.8245
0.3285
0.0168
1.6230
440
0.1644
0.0109
0.8247
0.3483
0.0230
1.7471
445
0.1611
0.0138
0.8251
0.3481
0.0298
1.7826
450
0.1566
0.0177
0.8257
0.3362
0.0380
1.7721
455
0.1510
0.0227
0.8263
0.3187
0.0480
1.7441
460
0.1440
0.0297
0.8263
0.2908
0.0600
1.6692
465
0.1355
0.0399
0.8246
0.2511
0.0739
1.5281
470
0.1241
0.0578
0.8181
0.1954
0.0910
1.2876
475
0.1096
0.0868
0.8036
0.1421
0.1126
1.0419
480
0.0913
0.1327
0.7760
0.0956
0.1390
0.8130
485
0.0687
0.2007
0.7306
0.0580
0.1693
0.6162
490
0.0454
0.2950
0.6596
0.0320
0.2080
0.4652
495
0.0235
0.4127
0.5638
0.0147
0.2586
0.3533
500
0.0082
0.5384
0.4534
0.0049
0.3230
0.2720
505
0.0039
0.6548
0.3413
0.0024
0.4073
0.2123
510
0.0139
0.7502
0.2359
0.0093
0.5030
0.1582
515
0.0389
0.8120
0.1491
0.0291
0.6082
0.1117
520
0.0743
0.8338
0.0919
0.0633
0.7100
0.0782
525
0.1142
0.8262
0.0596
0.1096
0.7932
0.0573
530
0.1547
0.8059
0.0394
0.1655
0.8620
0.0422
535
0.1929
0.7816
0.0255
0.2257
0.9149
0.0298
540
0.2296
0.7543
0.0161
0.2904
0.9540
0.0203
545
0.2658
0.7243
0.0099
0.3597
0.9803
0.0134
550
0.3016
0.6923
0.0061
0.4334
0.9950
0.0087
555
0.3373
0.6589
0.0038
0.5121
1.0000
0.0057
560
0.3731
0.6245
0.0024
0.5945
0.9950
0.0039
565
0.4087
0.5896
0.0017
0.6784
0.9786
0.0027
570
0.4441
0.5547
0.0012
0.7621
0.9520
0.0021
575
0.4788
0.5202
0.0010
0.8425
0.9154
0.0010
580
0.5125
0.4866
0.0009
0.9163
0.8700
0.0017
585
0.5448
0.4544
0.0008
0.9786
0.8163
0.0014
590
0.5752
0.4242
0.0006
1.0263
0.7570
0.0011
595
0.6029
0.3965
0.0006
1.0567
0.6949
0.0010
600
0.6270
0.3725
0.0005
1.0522
0.6130
0.0008
605
0.6482
0.3514
0.0004
1.0456
0.5668
0.0006
610
0.6658
0.3340
0.0002
1.0026
0.5030
0.0003
615
0.6801
0.3197
0.0002
0.9384
0.4412
0.0002
620
0.6915
0.3083
0.0002
0.8544
0.3810
0.0002
625
0.7006
0.2993
0.0001
0.7514
0.3210
0.0001
630
0.7079
0.2920
0.0001
0.6424
0.2650
0.0000
635
0.7140
0.2859
0.0001
0.5419
0.2170
0.0000
640
0.7219
0.2809
0.0001
0.4479
0.1750
0.0000
645
0.7230
0.2770
0.0000
0.3608
0.1382
0.0000
650
0.7260
0.2740
0.0000
0.2835
0.1070
0.0000
655
0.7283
0.2717
0.0000
0.2187
0.0816
0.0000
660
0.7300
0.2700
0.0000
0.1649
0.0610
0.0000
665
0.7311
0.2689
0.0000
0.1212
0.0446
0.0000
670
0.7320
0.2680
0.0000
0.0874
0.0320
0.0000
675
0.7327
0.2673
0.0000
0.0636
0.0232
0.0000
680
0.7334
0.2666
0.0000
0.0468
0.0170
0.0000
685
0.7340
0.2660
0.0000
0.0329
0.0119
0.0000
690
0.7344
0.2656
0.0000
0.0227
0.0082
0.0000
695
0.7346
0.2654
0.0000
0.0158
0.0057
0.0000
700
0.7347
0.2653
0.0000
0.0114
0.0041
0.0000
705
0.7347
0.2653
0.0000
0.0081
0.0029
0.0000
710
0.7347
0.2653
0.0000
0.0058
0.0021
0.0000
715
0.7347
0.2653
0.0000
0.0041
0.0015
0.0000
720
0.7347
0.2653
0.0000
0.0029
0.0010
0.0000
725
0.7347
0.2653
0.0000
0.0020
0.0007
0.0000
730
0.7347
0.2653
0.0000
0.0014
0.0005
0.0000
735
0.7347
0.2653
0.0000
0.0010
0.0004
0.0000
740
0.7347
0.2653
0.0000
0.0007
0.0002
0.0000
745
0.7347
0.2653
0.0000
0.0005
0.0002
0.0000
750
0.7347
0.2653
0.0000
0.0003
0.0001
0.0000
755
0.7347
0.2653
0.0000
0.0002
0.0001
0.0000
760
0.7347
0.2653
0.0000
0.0002
0.0001
0.0000
765
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
770
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
775
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
780
0.7347
0.2653
0.0000
0.0000
0.0000
0.0000
联系:yinwei_88@sina.com
本文根据相关的数据绘制了可见光(波长从380nm到780nm)的光谱,读者可根据该光谱迅速的知道某个波长 所对应的光的颜色,本文用三次样条插值来拟合波长与颜色的变化曲线,从而更加准确的表达波长与颜色的变化规律。数据资料来源:http://www.cgan.net/book/books/print/packcolor/link/5-4-2.html。
主要代码(MFC单文档):
#include "stdio.h"
double wavelen[81],red[81],green[81],blue[81];//存储波长,红绿蓝的离散数据
//读数据文件
int ReadSpectrumFile()
...{
int i=0,temp;
float r,g,b;
FILE *fp;
fp=fopen("spectrum.txt","r");
if(!fp)
return 0;
while(!feof(fp))
...{
fscanf(fp,"%d%f%f%f",&temp,&r,&g,&b);
wavelen[i]=(double)temp;
red[i]=r;
green[i]=g;
blue[i]=b;
fscanf(fp,"%f%f%f",&r,&g,&b);//空的,不对刺激值
if(i>=80)
break;
i++;
}
fclose(fp);
return 1;
}
//三次样条插值函数
double GetValueSpline(int n, double x[], double y[], double t)
...{
int i,j;
double h0,h1,alpha,beta,*s,z,*dy;
dy=new double
;
for(i=0;i<n;i++)dy[i]=0.0;
// 初值
s=new double
;
s[0]=dy[0];
dy[0]=0.0;
h0=x[1]-x[0];
for (j=1;j<=n-2;j++)
...{
h1=x[j+1]-x[j];
alpha=h0/(h0+h1);
beta=(1.0-alpha)*(y[j]-y[j-1])/h0;
beta=3.0*(beta+alpha*(y[j+1]-y[j])/h1);
dy[j]=-alpha/(2.0+(1.0-alpha)*dy[j-1]);
s[j]=(beta-(1.0-alpha)*s[j-1]);
s[j]=s[j]/(2.0+(1.0-alpha)*dy[j-1]);
h0=h1;
}
for (j=n-2;j>=0;j--)dy[j]=dy[j]*dy[j+1]+s[j];
for (j=0;j<=n-2;j++)s[j]=x[j+1]-x[j];
if (t>=x[n-1])i=n-2;
else
...{
i=0;
while (t>x[i+1])
i=i+1;
}
h1=(x[i+1]-t)/s[i];
h0=h1*h1;
z=(3.0*h0-2.0*h0*h1)*y[i];
z=z+s[i]*(h0-h0*h1)*dy[i];
h1=(t-x[i])/s[i];
h0=h1*h1;
z=z+(3.0*h0-2.0*h0*h1)*y[i+1];
z=z-s[i]*(h0-h0*h1)*dy[i+1];
delete[] s;
delete[] dy;
return(z);
}
//绘制光谱
void CSpectrumView::OnDraw(CDC* pDC)
...{
CSpectrumDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
double r,g,b;
CRect rect;
rect.top=10;
rect.bottom=200;
rect.left=10;
for(int i=0;i<=400;i++)
...{
rect.right=rect.left+1;
r=GetValueSpline(81,wavelen,red,380.0+i);
g=GetValueSpline(81,wavelen,green,380.0+i);
b=GetValueSpline(81,wavelen,blue,380.0+i);
pDC->FillSolidRect(&rect,RGB(int(255.0*r),int(255.0*g),int(255.0*b)));
rect.left++;
}
//画标尺
pDC->SetBkMode(TRANSPARENT);
pDC->MoveTo(10,200);
pDC->LineTo(10,225);
pDC->TextOut(10,200,"380纳米");
pDC->MoveTo(210,200);
pDC->LineTo(210,225);
pDC->TextOut(210,200,"580纳米");
pDC->MoveTo(410,200);
pDC->LineTo(410,225);
pDC->TextOut(410,200,"780纳米");
}
数据文件格式
380
0.1741
0.0050
0.8209
0.00145
0.0000
0.0065
385
0.1740
0.0050
0.8210
0.0022
0.0001
0.0105
第一条为波长数据,接下来三行为红绿蓝的分量,最后三个为各色的刺激值(这里没用上)。
效果图
注:实际上,根据量子力学,实际的光谱是不连续的。
文件内容
380
0.1741
0.0050
0.8209
0.00145
0.0000
0.0065
385
0.1740
0.0050
0.8210
0.0022
0.0001
0.0105
390
0.1738
0.0049
0.8213
0.0042
0.0001
0.0201
395
0.1736
0.0049
0.8215
0.0076
0.0002
0.0362
400
0.1733
0.0048
0.8219
0.0143
0.0004
0.0679
405
0.1730
0.0048
0.8222
0.0232
0.0006
0.1102
410
0.1726
0.0048
0.8226
0.0435
0.0012
0.2074
415
0.1721
0.0048
0.8231
0.0776
0.0022
0.3713
420
0.1714
0.0051
0.8235
0.1344
0.0040
0.6456
425
0.1703
0.0058
0.8239
0.2148
0.0073
1.0391
430
0.1689
0.0069
0.8242
0.2839
0.0116
1.3856
435
0.1669
0.0086
0.8245
0.3285
0.0168
1.6230
440
0.1644
0.0109
0.8247
0.3483
0.0230
1.7471
445
0.1611
0.0138
0.8251
0.3481
0.0298
1.7826
450
0.1566
0.0177
0.8257
0.3362
0.0380
1.7721
455
0.1510
0.0227
0.8263
0.3187
0.0480
1.7441
460
0.1440
0.0297
0.8263
0.2908
0.0600
1.6692
465
0.1355
0.0399
0.8246
0.2511
0.0739
1.5281
470
0.1241
0.0578
0.8181
0.1954
0.0910
1.2876
475
0.1096
0.0868
0.8036
0.1421
0.1126
1.0419
480
0.0913
0.1327
0.7760
0.0956
0.1390
0.8130
485
0.0687
0.2007
0.7306
0.0580
0.1693
0.6162
490
0.0454
0.2950
0.6596
0.0320
0.2080
0.4652
495
0.0235
0.4127
0.5638
0.0147
0.2586
0.3533
500
0.0082
0.5384
0.4534
0.0049
0.3230
0.2720
505
0.0039
0.6548
0.3413
0.0024
0.4073
0.2123
510
0.0139
0.7502
0.2359
0.0093
0.5030
0.1582
515
0.0389
0.8120
0.1491
0.0291
0.6082
0.1117
520
0.0743
0.8338
0.0919
0.0633
0.7100
0.0782
525
0.1142
0.8262
0.0596
0.1096
0.7932
0.0573
530
0.1547
0.8059
0.0394
0.1655
0.8620
0.0422
535
0.1929
0.7816
0.0255
0.2257
0.9149
0.0298
540
0.2296
0.7543
0.0161
0.2904
0.9540
0.0203
545
0.2658
0.7243
0.0099
0.3597
0.9803
0.0134
550
0.3016
0.6923
0.0061
0.4334
0.9950
0.0087
555
0.3373
0.6589
0.0038
0.5121
1.0000
0.0057
560
0.3731
0.6245
0.0024
0.5945
0.9950
0.0039
565
0.4087
0.5896
0.0017
0.6784
0.9786
0.0027
570
0.4441
0.5547
0.0012
0.7621
0.9520
0.0021
575
0.4788
0.5202
0.0010
0.8425
0.9154
0.0010
580
0.5125
0.4866
0.0009
0.9163
0.8700
0.0017
585
0.5448
0.4544
0.0008
0.9786
0.8163
0.0014
590
0.5752
0.4242
0.0006
1.0263
0.7570
0.0011
595
0.6029
0.3965
0.0006
1.0567
0.6949
0.0010
600
0.6270
0.3725
0.0005
1.0522
0.6130
0.0008
605
0.6482
0.3514
0.0004
1.0456
0.5668
0.0006
610
0.6658
0.3340
0.0002
1.0026
0.5030
0.0003
615
0.6801
0.3197
0.0002
0.9384
0.4412
0.0002
620
0.6915
0.3083
0.0002
0.8544
0.3810
0.0002
625
0.7006
0.2993
0.0001
0.7514
0.3210
0.0001
630
0.7079
0.2920
0.0001
0.6424
0.2650
0.0000
635
0.7140
0.2859
0.0001
0.5419
0.2170
0.0000
640
0.7219
0.2809
0.0001
0.4479
0.1750
0.0000
645
0.7230
0.2770
0.0000
0.3608
0.1382
0.0000
650
0.7260
0.2740
0.0000
0.2835
0.1070
0.0000
655
0.7283
0.2717
0.0000
0.2187
0.0816
0.0000
660
0.7300
0.2700
0.0000
0.1649
0.0610
0.0000
665
0.7311
0.2689
0.0000
0.1212
0.0446
0.0000
670
0.7320
0.2680
0.0000
0.0874
0.0320
0.0000
675
0.7327
0.2673
0.0000
0.0636
0.0232
0.0000
680
0.7334
0.2666
0.0000
0.0468
0.0170
0.0000
685
0.7340
0.2660
0.0000
0.0329
0.0119
0.0000
690
0.7344
0.2656
0.0000
0.0227
0.0082
0.0000
695
0.7346
0.2654
0.0000
0.0158
0.0057
0.0000
700
0.7347
0.2653
0.0000
0.0114
0.0041
0.0000
705
0.7347
0.2653
0.0000
0.0081
0.0029
0.0000
710
0.7347
0.2653
0.0000
0.0058
0.0021
0.0000
715
0.7347
0.2653
0.0000
0.0041
0.0015
0.0000
720
0.7347
0.2653
0.0000
0.0029
0.0010
0.0000
725
0.7347
0.2653
0.0000
0.0020
0.0007
0.0000
730
0.7347
0.2653
0.0000
0.0014
0.0005
0.0000
735
0.7347
0.2653
0.0000
0.0010
0.0004
0.0000
740
0.7347
0.2653
0.0000
0.0007
0.0002
0.0000
745
0.7347
0.2653
0.0000
0.0005
0.0002
0.0000
750
0.7347
0.2653
0.0000
0.0003
0.0001
0.0000
755
0.7347
0.2653
0.0000
0.0002
0.0001
0.0000
760
0.7347
0.2653
0.0000
0.0002
0.0001
0.0000
765
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
770
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
775
0.7347
0.2653
0.0000
0.0001
0.0000
0.0000
780
0.7347
0.2653
0.0000
0.0000
0.0000
0.0000
相关文章推荐
- 趣味C程序100.1 .1 绘制余弦曲线
- 趣味C程序100.9 绘制杨辉三角
- 趣味C程序100.1 .2 绘制正弦曲线
- C语言趣味程序(14)
- VS2012下基于Glut OpenGL绘制直线示例程序:
- 中国象棋程序的设计与实现(十二)--棋盘绘制算法(尽管注释非常详细,完全理解仍有难度)
- “趣味照片”小程序,好玩又实用
- 趣味小程序
- 这个绘制圆的程序那里错了!
- Ferguson曲线原理及绘制程序
- 描述特征分类时常用绘制散点图程序
- C语言趣味程序(8)
- 跟着Code走,详解Symbian UI程序框架(3)——窗口管理及绘制过程
- c++ 趣味小程序
- vs2010控制台程序下绘制图形
- c程序基本算法百例之二—绘制余弦曲线和直线
- C#趣味小程序(6)——动态工具栏
- Windows 画图程序绘制像素小女孩头像
- 高速正圆绘制程序
- C#趣味程序---理財高手