2010-03-29 4 views
1

this ActionScript sample은 파형을 사용하여 루프를 통해 한 번에 한 줄씩 색상 스펙트럼을 그리는 방법을 보여줍니다.파형으로 색상 스펙트럼 그리기

그러나 각 RGB 채널의 파형 위치는 색상 (순수 노란색, 시안 색 및 자홍색)이 누락 된 색상 스펙트럼을 생성하므로 스펙트럼이 불완전합니다.

그려진 색상 스펙트럼이 모든 색상을 나타낼 수 있도록이 문제를 어떻게 해결할 수 있습니까? 관심있는 사람들을위한 솔루션


업데이트


// Loop through all of the pixels from '0' to the specified width. 
for(var i:int = 0; i < nWidth; i++) 
    { 
    // Calculate the color percentage based on the current pixel. 
    nColorPercent = i/nWidth; 

    // Calculate the radians of the angle to use for rotating color values. 
    nRadians = (-360 * nColorPercent) * (Math.PI/180); 

    // Calculate the RGB channels based on the angle. 
    nR = Math.cos(nRadians)     * 127 + 128 << 16; 
    nG = Math.cos(nRadians + 2 * Math.PI/3) * 127 + 128 << 8; 
    nB = Math.cos(nRadians + 4 * Math.PI/3) * 127 + 128; 

    // OR the individual color channels together. 
    nColor = nR | nG | nB; 
    } 
는 아래 내가 위의 문제를 해결하기 위해 쓴 솔루션입니다. RGB 파형은 풀 컬러 스펙트럼을 생성하는 데 사용되지 않습니다. 또한 코드는 유연하므로 생성 된 스프라이트에 대해 크기와 색상 변수를 지정할 수 있습니다. 이 예에서 컬러 변수는 전체 컬러 스펙트럼

/* 
//SpectrumGradient Object Call 

var spectrum:SpectrumGradient = new SpectrumGradient(stage.stageWidth, stage.stageHeight, 0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000); 
this.addChild(spectrum); 
*/ 


package 
{ 
    import flash.display.BitmapData; 
    import flash.display.CapsStyle; 
    import flash.display.GradientType; 
    import flash.display.LineScaleMode; 
    import flash.display.Sprite; 
    import flash.geom.Matrix; 

    public class SpectrumGradient extends Sprite 
     { 
     public function SpectrumGradient(spriteWidth:Number, spriteHeight:Number, ...spriteColors) 
      { 
      //Setup spectrum sprite 
      var spectrum:Sprite = new Sprite(); 
      var spectrumAlphas:Array = new Array(); 
      var spectrumRatios:Array = new Array(); 
      var spectrumPartition:Number = 255/(spriteColors.length - 1); 

      for (var pushLoop:int = 0; pushLoop < spriteColors.length; pushLoop++) 
       { 
       spectrumAlphas.push(1); 
       spectrumRatios.push(pushLoop * spectrumPartition); 
       } 

      //Create spectrum sprite as evenly distributed linear gradient using supplied spriteColors 
      var spectrumMatrix:Matrix = new Matrix(); 
      spectrumMatrix.createGradientBox(spriteWidth, spriteHeight); 
      spectrum.graphics.lineStyle(); 
      spectrum.graphics.beginGradientFill(GradientType.LINEAR, spriteColors, spectrumAlphas, spectrumRatios, spectrumMatrix); 
      spectrum.graphics.drawRect(0, 0, spriteWidth, 1); 
      spectrum.graphics.endFill(); 

      //Assign bitmapData to the spectrum sprite 
      var bitmapData:BitmapData = new BitmapData(spectrum.width, spectrum.height, true, 0); 
      bitmapData.draw(spectrum); 

      var pixelColor:Number; 

      for (var i:int = 0; i < spriteWidth; i++) 
       { 
       //Retrieve the color number for each pixel of the spectrum sprite 
       pixelColor = bitmapData.getPixel(i, 0); 

       //Create new matrices for the white and black gradient lines 
       var matrixWhite:Matrix = new Matrix(); 
       matrixWhite.createGradientBox(1, spriteHeight/2, Math.PI * 0.5, 0, 0); 
       var matrixBlack = new Matrix(); 
       matrixBlack.createGradientBox(1, spriteHeight/2, Math.PI * 0.5, 0, spriteHeight/2); 

       //Each slice of the sprite is composed of two vertical lines: the first fades from white to the pixelColor, the second fades from pixelColor to black 
       graphics.lineStyle(1, 0, 1, false, LineScaleMode.NONE, CapsStyle.NONE); 
       graphics.lineGradientStyle(GradientType.LINEAR, [0xFFFFFF, pixelColor], [100, 100], [0, 255], matrixWhite); 
       graphics.moveTo(i, 0); 
       graphics.lineTo(i, spriteHeight/2); 
       graphics.lineGradientStyle(GradientType.LINEAR, [pixelColor, 0], [100, 100], [0, 255], matrixBlack); 
       graphics.moveTo(i, spriteHeight/2); 
       graphics.lineTo(i, spriteHeight); 
       } 

      } 
     } 
} 

답변

4

한 번에 모든 색상을 가질 수 없습니다를 생산하는 빨간색, 하늘색, 녹색, 노란색, 빨간색, 파란색, 마젠타 있습니다. 모든 RGB 색상은 256 x 256 x 256이므로 모든 색상을 표시하려면 4096 x 4096 픽셀이 필요합니다.

또한 모두를 표시하는 "자연스런"/ 현명한 방법은 없습니다. 적어도 지금까지 아무도 2 차원 색상 공간을 제시하지 못했습니다. 색상을 표시하려면 항상 2를 선택해야합니다. 일반적인 색상 선택기는 hue slider and a lightness/saturation plane 또는 hue/saturation plane and a lightness slider을 사용합니다.

첫 번째 (직사각형) 스펙트럼은 2 개의 중첩 된 그라디언트로 쉽게 그릴 수 있습니다. 가로 색은 색조, 세로 (반투명)는 밝기입니다. 빠르고 부드럽게 (개별 선이 보이지 않으면 확대/축소).

편집 :은 여기가 분명한 이유 바람직하다 하나의 그라데이션으로 달성 할 수있는 방법에 대한 실무 예제 : 파형을 사용하는 방법은 찾아 망치 같은 비트입니다

package { 
    import flash.display.*; 
    import flash.events.Event; 
    import flash.events.MouseEvent; 
    import flash.geom.Matrix; 

    public class GradientTest extends Sprite { 

     public function GradientTest() { 
      var colors:Array = [0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000]; 
      var part:Number = 0xFF/(colors.length-1); 
      var ratios:Array = [], alphas:Array = []; 
      var m:Matrix = new Matrix(); 
      m.createGradientBox(500, 20); 
      for (var i:int = 0; i < colors.length; i++) { 
       ratios.push(part * i); 
       alphas.push(100); 
      } 

      this.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, m); 
      this.graphics.drawRect(0, 0, 500, 20); 

      //just to get the RGB values under the mouse: 
      var b:BitmapData = new BitmapData(this.width, this.height, true, 0); 
      b.draw(this); 
      stage.addEventListener(MouseEvent.MOUSE_MOVE, function (e:Event):void { 
       if (hitTestPoint(mouseX, mouseY)) { 
        var s:String = b.getPixel(mouseX, mouseY).toString(16); 
        while (s.length < 6) s = "0" + s; 
        trace("#" + s);     
       } 
      }); 
     } 
    } 
} 

손톱. 비트 연산과 삼각법이 훌륭한 도구이기 때문에 단순한 솔루션을 선호하지는 않습니다.

+1

물론, 필자는 rect에서 1670 만 개의 모든 단일 색상을 표시하는 대신 색조/채도 평면 및 밝기 슬라이더에 대한 첨부 된 이미지와 유사하게 6 개의 기본 색상 색상 (빨강, 노랑, 초록, 녹청, 파랑, 자홍)을 사용하여 루프와 웨이브 폼을 만듭니다. – TheDarkIn1978

+0

@ TheDarkIn1978 - 게시글이 업데이트되었습니다. – back2dos

+0

많은 back2dos에게 감사드립니다. :) – TheDarkIn1978