RGB values of visible spectrum

后端 未结 11 1606
难免孤独
难免孤独 2020-11-22 10:37

I need an algorithm or function to map each wavelength of visible range of spectrum to its equivalent RGB values. Is there any structural relation between the RGB System an

11条回答
  •  粉色の甜心
    2020-11-22 11:04

    A runnable example based on a popular answer:

    function spectrogram() {
      var svgns = 'http://www.w3.org/2000/svg';
      var svg = document.createElementNS(svgns, 'svg');
      var defs = document.createElementNS(svgns, 'defs');
      var gradient = document.createElementNS(svgns, 'linearGradient');
      var rect = document.createElementNS(svgns, 'rect');
    
      var stops = spectral_gradient( 400, 700, 3 );
    
      for( var i = 0, length = stops.length; i < length; i++ ) {
        var stop = document.createElementNS(svgns, 'stop');
        stop.setAttribute('offset', stops[i].offset);
        stop.setAttribute('stop-color', stops[i].color);
        gradient.appendChild(stop);
      }
    
      // Apply the  to 
      gradient.id = 'Gradient';
      gradient.setAttribute('x1', '0');
      gradient.setAttribute('x2', '1');
      gradient.setAttribute('y1', '0');
      gradient.setAttribute('y2', '0');
      defs.appendChild(gradient);
    
      // Setup the  element.
      rect.setAttribute('fill', 'url(#Gradient)');
      rect.setAttribute('width', '100%');
      rect.setAttribute('height', '100%');
    
      // Assign an id, classname, width and height
      svg.setAttribute('width', '100%');
      svg.setAttribute('height', '100%')
      svg.setAttribute('version', '1.1');
      svg.setAttribute('xmlns', svgns);
    
      // Add the  and  elements to 
      svg.appendChild(defs);
      svg.appendChild(rect);
    
      // Add the  element to 
      document.body.appendChild(svg);
    }
    
    function spectral_gradient( wl1, wl2, steps ) {
      var stops = [];
      var delta = Math.abs( wl2 - wl1 );
    
      for( var wl = wl1; wl <= wl2; wl += steps ) {
        var offset = Math.round( (1 - Math.abs( wl2 - wl ) / delta) * 100 );
        stops.push({
          "color": wavelength2hex( wl ),
          "offset": offset + "%"
        });
      }
    
      return stops;
    }
    
    function wavelength2hex( l ) {
      var wl = wavelength2rgb( l );
      var rgb = {
        "r": Math.round( wl.r * 255 ),
        "g": Math.round( wl.g * 255 ),
        "b": Math.round( wl.b * 255 )
      };
    
      return rgb2hex( rgb.r, rgb.g, rgb.b );
    }
    
    function wavelength2rgb( l ) {
      var t;
      var r = 0.0;
      var g = 0.0;
      var b = 0.0;
    
      if ((l >= 400.0) && (l < 410.0)) {
        t = (l - 400.0) / (410.0 - 400.0);
        r = +(0.33 * t) - (0.20 * t * t);
      } else if ((l >= 410.0) && (l < 475.0)) {
        t = (l - 410.0) / (475.0 - 410.0);
        r = 0.14 - (0.13 * t * t);
      } else if ((l >= 545.0) && (l < 595.0)) {
        t = (l - 545.0) / (595.0 - 545.0);
        r = +(1.98 * t) - (t * t);
      } else if ((l >= 595.0) && (l < 650.0)) {
        t = (l - 595.0) / (650.0 - 595.0);
        r = 0.98 + (0.06 * t) - (0.40 * t * t);
      } else if ((l >= 650.0) && (l < 700.0)) {
        t = (l - 650.0) / (700.0 - 650.0);
        r = 0.65 - (0.84 * t) + (0.20 * t * t);
      }
    
      if ((l >= 415.0) && (l < 475.0)) {
        t = (l - 415.0) / (475.0 - 415.0);
        g = +(0.80 * t * t);
      } else if ((l >= 475.0) && (l < 590.0)) {
        t = (l - 475.0) / (590.0 - 475.0);
        g = 0.8 + (0.76 * t) - (0.80 * t * t);
      } else if ((l >= 585.0) && (l < 639.0)) {
        t = (l - 585.0) / (639.0 - 585.0);
        g = 0.84 - (0.84 * t);
      }
    
      if ((l >= 400.0) && (l < 475.0)) {
        t = (l - 400.0) / (475.0 - 400.0);
        b = +(2.20 * t) - (1.50 * t * t);
      } else if ((l >= 475.0) && (l < 560.0)) {
        t = (l - 475.0) / (560.0 - 475.0);
        b = 0.7 - (t) + (0.30 * t * t);
      }
    
      return {"r": r, "g": g, "b": b};
    }
    
    function rgb2hex( r, g, b ) {
      return "#" + hex( r ) + hex( g ) + hex( b );
    }
    
    function hex( v ) {
      return v.toString( 16 ).padStart( 2, "0" );
    }
    
    
    
      
      
    
    
    
    

提交回复
热议问题