Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 如何将颜色波长转换为RGB或HSL?_Fortran - Fatal编程技术网

Fortran 如何将颜色波长转换为RGB或HSL?

Fortran 如何将颜色波长转换为RGB或HSL?,fortran,Fortran,我正在做一个项目,其中一部分需要从颜色波长转换为RGB/HSL/HSV(任何一种),所以我找到了这个页面:我有点理解它,但我需要它作为Javascript函数 我试着在色调值和波长之间做一个简单的比例,但感觉不对。我发现的代码是用Fortran编写的: Dan Bruton的可见波长RGB值(astro@tamu.edu) 此程序可在以下网址找到: 最后更新日期为1996年2月20日。 该程序将创建频谱的ppm(便携式pixmap)图像。 光谱是使用可见光的近似RGB值生成的 波长在380纳米到

我正在做一个项目,其中一部分需要从颜色波长转换为RGB/HSL/HSV(任何一种),所以我找到了这个页面:我有点理解它,但我需要它作为Javascript函数

我试着在色调值和波长之间做一个简单的比例,但感觉不对。我发现的代码是用Fortran编写的:

Dan Bruton的可见波长RGB值(astro@tamu.edu) 此程序可在以下网址找到: 最后更新日期为1996年2月20日。 该程序将创建频谱的ppm(便携式pixmap)图像。 光谱是使用可见光的近似RGB值生成的 波长在380纳米到780纳米之间。 NetPBM的ppmtogif可用于转换ppm图像 到gif。红色、绿色和蓝色值(RGB)为 假设随波长线性变化(对于GAMMA=1)。
NetPBM软件:

图像信息-宽度、高度、深度、伽马

   M=400
   N=50
   MAX=255
   GAMMA=.80
将输出写入PPM文件

       OPEN(UNIT=20,FILE='temp.ppm',STATUS='UNKNOWN')
       FORMAT(A10)
       WRITE(20,1) 'P3        ' 
       WRITE(20,1) '# temp.ppm'
       WRITE(20,*) M,N 
       WRITE(20,*) MAX 
       DO J=1,N
        DO I=1,M

   WAVELENGTH = WL

            WL = 380. + REAL(I * 400. / M)

            IF ((WL.GE.380.).AND.(WL.LE.440.)) THEN 
              R = -1.*(WL-440.)/(440.-380.)
              G = 0.
              B = 1.
            ENDIF
            IF ((WL.GE.440.).AND.(WL.LE.490.)) THEN
              R = 0.
              G = (WL-440.)/(490.-440.)
              B = 1.
            ENDIF
            IF ((WL.GE.490.).AND.(WL.LE.510.)) THEN 
              R = 0.
              G = 1.
              B = -1.*(WL-510.)/(510.-490.)
            ENDIF
            IF ((WL.GE.510.).AND.(WL.LE.580.)) THEN 
              R = (WL-510.)/(580.-510.)
              G = 1.
              B = 0.
            ENDIF
            IF ((WL.GE.580.).AND.(WL.LE.645.)) THEN
              R = 1.
              G = -1.*(WL-645.)/(645.-580.)
              B = 0.
            ENDIF
            IF ((WL.GE.645.).AND.(WL.LE.780.)) THEN
              R = 1.
              G = 0.
              B = 0.
            ENDIF
       DO J=1,N
        DO I=1,M
           WL = 380. + REAL(I * 400. / M)        
           IR=INT(MAX*CV(I,J,1))
           IG=INT(MAX*CV(I,J,2))
           IB=INT(MAX*CV(I,J,3))

ITYPE=1 - PLAIN SPECTUM
ITYPE=2 - MARK SPECTRUM AT 100 nm INTEVALS
ITYPE=3 - HYDROGEN BALMER EMISSION SPECTRA
ITYPE=4 - HYDROGEN BALMER ABSORPTION SPECTRA

         ITYPE=4
         IF (ITYPE.EQ.2) THEN
            DO K=400,700,100
              IF ((ABS(INT(WL)-K).LT.1).AND.(J.LE.20)) THEN
               IR=MAX
               IG=MAX
               IB=MAX
              ENDIF
            ENDDO
         ELSEIF (ITYPE.EQ.3) THEN
            IF ((ABS(WL-656.).GT.1.).and.(ABS(WL-486.).GT.1.).and.
     *          (ABS(WL-433.).GT.1.).and.(ABS(WL-410.).GT.1.)
     *           .AND.(ABS(WL-396.).GT.1.)) THEN
              IR = 0
              IG = 0
              IB = 0
            ENDIF
         ELSEIF (ITYPE.EQ.4) THEN
            IF ((ABS(WL-656.).LT.1.1).or.(ABS(WL-486.).LT.1.1).or.
     *          (ABS(WL-433.).LT.1.1).or.(ABS(WL-410.).LT.1.1)
     *           .or.(ABS(WL-396.).LT.1.1)) THEN
              IR = 0
              IG = 0
              IB = 0
            ENDIF
         ENDIF

         WRITE(20,*) IR, IG, IB
        ENDDO
       ENDDO
       STOP
       END 
让强度SSS在视觉极限附近下降

 IF (WL.GT.700.) THEN
    SSS=.3+.7* (780.-WL)/(780.-700.)
 ELSE IF (WL.LT.420.) THEN
    SSS=.3+.7*(WL-380.)/(420.-380.)
 ELSE
    SSS=1.
 ENDIF
GAMMA调整并将图像写入阵列

 CV(I,J,1)=(SSS*R)**GAMMA
 CV(I,J,2)=(SSS*G)**GAMMA
 CV(I,J,3)=(SSS*B)**GAMMA
ENDDO
ENDDO
将图像写入PPM文件

       OPEN(UNIT=20,FILE='temp.ppm',STATUS='UNKNOWN')
       FORMAT(A10)
       WRITE(20,1) 'P3        ' 
       WRITE(20,1) '# temp.ppm'
       WRITE(20,*) M,N 
       WRITE(20,*) MAX 
       DO J=1,N
        DO I=1,M

   WAVELENGTH = WL

            WL = 380. + REAL(I * 400. / M)

            IF ((WL.GE.380.).AND.(WL.LE.440.)) THEN 
              R = -1.*(WL-440.)/(440.-380.)
              G = 0.
              B = 1.
            ENDIF
            IF ((WL.GE.440.).AND.(WL.LE.490.)) THEN
              R = 0.
              G = (WL-440.)/(490.-440.)
              B = 1.
            ENDIF
            IF ((WL.GE.490.).AND.(WL.LE.510.)) THEN 
              R = 0.
              G = 1.
              B = -1.*(WL-510.)/(510.-490.)
            ENDIF
            IF ((WL.GE.510.).AND.(WL.LE.580.)) THEN 
              R = (WL-510.)/(580.-510.)
              G = 1.
              B = 0.
            ENDIF
            IF ((WL.GE.580.).AND.(WL.LE.645.)) THEN
              R = 1.
              G = -1.*(WL-645.)/(645.-580.)
              B = 0.
            ENDIF
            IF ((WL.GE.645.).AND.(WL.LE.780.)) THEN
              R = 1.
              G = 0.
              B = 0.
            ENDIF
       DO J=1,N
        DO I=1,M
           WL = 380. + REAL(I * 400. / M)        
           IR=INT(MAX*CV(I,J,1))
           IG=INT(MAX*CV(I,J,2))
           IB=INT(MAX*CV(I,J,3))

ITYPE=1 - PLAIN SPECTUM
ITYPE=2 - MARK SPECTRUM AT 100 nm INTEVALS
ITYPE=3 - HYDROGEN BALMER EMISSION SPECTRA
ITYPE=4 - HYDROGEN BALMER ABSORPTION SPECTRA

         ITYPE=4
         IF (ITYPE.EQ.2) THEN
            DO K=400,700,100
              IF ((ABS(INT(WL)-K).LT.1).AND.(J.LE.20)) THEN
               IR=MAX
               IG=MAX
               IB=MAX
              ENDIF
            ENDDO
         ELSEIF (ITYPE.EQ.3) THEN
            IF ((ABS(WL-656.).GT.1.).and.(ABS(WL-486.).GT.1.).and.
     *          (ABS(WL-433.).GT.1.).and.(ABS(WL-410.).GT.1.)
     *           .AND.(ABS(WL-396.).GT.1.)) THEN
              IR = 0
              IG = 0
              IB = 0
            ENDIF
         ELSEIF (ITYPE.EQ.4) THEN
            IF ((ABS(WL-656.).LT.1.1).or.(ABS(WL-486.).LT.1.1).or.
     *          (ABS(WL-433.).LT.1.1).or.(ABS(WL-410.).LT.1.1)
     *           .or.(ABS(WL-396.).LT.1.1)) THEN
              IR = 0
              IG = 0
              IB = 0
            ENDIF
         ENDIF

         WRITE(20,*) IR, IG, IB
        ENDDO
       ENDDO
       STOP
       END 

嗯,我甚至从未听说过Fortran代码,所以我不知道它是如何工作的。有人能帮我吗?

如果您知道这一点,代码很容易阅读

.GT. = greater than
.GE. = greater than or equal to
.LT. = less than
.LE. = less than or equal to
1. = 1.000
1.1 = 1.1000
.1 = 0.1000
1.1.GT.1
1.1>1
相同。进一步

!this is a comment
IMPLICIT REAL*8 (a-h,o-z) !variables starting with a,b,...h and o,..,z are double scalars
REAL*8 CV(500,500,3) ! this is an array of doubles

现在编写JavaScript

为了避免将来的麻烦,下面是转换为javascript的fortran代码:

const wl2rgb_pregamma = wl => {
  if (wl >= 380 && wl < 440) {
    const s = wl < 420 ? 0.3 + (0.7 * (wl - 380.0)) / (420.0 - 380.0) : 1.0;
    return [(s * -1 * (wl - 440)) / (440 - 380), 0, s];
  }
  if (wl >= 440 && wl < 490) {
    return [0, (wl - 440) / (490 - 440), 1];
  }
  if (wl >= 490 && wl < 510) {
    return [0, 1, (-1 * (wl - 510)) / (510 - 490)];
  }
  if (wl >= 510 && wl < 580) {
    return [(wl - 510) / (580 - 510), 1.0, 0.0];
  }
  if (wl >= 580 && wl < 645) {
    return [1, (-1 * (wl - 645)) / (645 - 580), 0];
  }
  if (wl > 700) {
    return [0.3 + (0.7 * (780 - wl)) / (780 - 700), 0, 0];
  }
  return [1, 0, 0];
};
const wl2rgb = wl => {
  const gamma = 0.8;
  const [r, g, b] = wl2rgb_pregamma(wl);
  return [Math.pow(r, gamma), Math.pow(g, gamma), Math.pow(b, gamma)];
};
const wl2rgb\u pregamma=wl=>{
如果(wl>=380&&wl<440){
常数s=wl<420?0.3+(0.7*(wl-380.0))/(420.0-380.0):1.0;
返回[(s*-1*(wl-440))/(440-380),0,s];
}
如果(wl>=440&&wl<490){
返回[0,(wl-440)/(490-440),1];
}
如果(wl>=490&&wl<510){
返回[0,1,(-1*(wl-510))/(510-490)];
}
如果(wl>=510&&wl<580){
回报率[(wl-510)/(580-510),1.0,0.0];
}
如果(wl>=580&&wl<645){
返回[1,(-1*(wl-645))/(645-580),0];
}
如果(wl>700){
返回[0.3+(0.7*(780-wl))/(780-700),0,0];
}
返回[1,0,0];
};
常量wl2rgb=wl=>{
常数伽马=0.8;
常数[r,g,b]=wl2rgb_pregamma(wl);
return[Math.pow(r,gamma),Math.pow(g,gamma),Math.pow(b,gamma)];
};
要在画布上试用:

var ctx = canvas.getContext("2d");
for (var i = 380; i < 780; i++) {
  const [r,g,b] = wl2rgb(i);
  ctx.fillStyle = `rgb(${r*255}, ${g*255}, ${b*255})`;
  ctx.fillRect(i - 380, 0, 1, 50);
}
var ctx=canvas.getContext(“2d”);
对于(变量i=380;i<780;i++){
常数[r,g,b]=wl2rgb(i);
ctx.fillStyle=`rgb(${r*255},${g*255},${b*255})`;
ctx.fillRect(i-380,0,1,50);
}

波长只能转换为色调。

公式与图形 公式是(如果w=波长,h=色调):h=(40/27)ww=(27h)/40
该图位于(色调为x,波长(nm)为y)。
请注意,如果波长小于400或大于650,则可能需要向色调添加360,直到波长大于400或小于650

代码 色调与波长
h=输入('Hue:');
def hw():
w=27*int(h);
w/=40;
当w>650或w<400时:
hw()
印刷品(w);
##色相波长##
w=输入('波长单位为nm:')
h=40/27
h*=w

也许本文档将帮助您实现它。这与javascript有什么关系?@Justinas哦,我忘了提到我需要在javascript上使用它……无论如何,谢谢。。。