2011-01-08 6 views
2

平行四辺形(RGB点の2次元配列)を三角形(RGB点の2次元配列)に投影する擬似コードアルゴリズムとは私の場合、同じ辺の大きさ(二等辺三角形)を持つ右三角形に四角形を入れ、四角形の最大辺を持つ同じサイズの六角形を使用します。だから擬似コードでそのようなことを行う方法は?私RGB平行四辺形をRGB三角形に投影するための擬似コードアルゴリズムを取得する場所

alt textのために正しくない結果 -

ので、一般的に、我々は150、高さ200幅三角形花火CS5と

にそれを歪ませるeant 300x200

alt text

たとえばました

Photoshop CS5の正しい結果

alt text

だから私は、フォトショップが変換するための擬似コードとは何でしょうか?

+1

あなたが達成しようとしていることのいくつかの写真は、私たちが問題を理解するのに役立つかもしれません。 – mtrw

+0

画像を追加=) – Rella

+0

ああ、実際には、矩形の上端が無限遠にある視点に投写しています。または、少なくとも遠く離れて1つのピクセルとして表示されています。 –

答えて

2

あなたの質問を誤解しているかどうかはわかりませんが、私の考えはここにあります。私は、投影が、三角形の斜辺が長方形の最も長い辺と同じ方向を向いていると仮定しています。なぜなら、それらは同じサイズになると言っていたからです。いくつかの粗画像(正確な縮尺ではない):

長方形H = 4、W = 10

--------- 
|  | 
|  | 
--------- 

トライアングルのHyp = 10、S1 = 8、S2 = 6

 . 
    . | 
.  | 
-------- 

そこで、私の提案矩形の「ブロック」が三角形の点と等しく、各三角形の点が関連する矩形ブロックのRGB平均であり、元のオブジェクトの縮尺に応じてブロックが重複する可能性があるというマッピングを行うことである。

具体的には、上記の例に戻ってまず比、高さ比率は固定、矩形は高さ4、三角形は高さ6です。したがって、三角形の垂直方向の各ピクセルは6/4,1.5長方形の中にある。今度は ".5"に対処する2つのオプションがあります。切り上げまたは切り捨てを考えたり、ブロック全体を使用したり、分数セクションに加重を使うことができます。後者の場合はそれほど簡単ではないので、さらに検討する予定です。

垂直方向に移動すると、小数部はその行のピクセルの小数部の重みに変換されるので、垂直方向に平均化し、ピクセルが128と137(単純化のために1つのコンポーネントのみを見ている)の場合、平均は

(128+(0.5 * 137))/ 1.5 =(128 + 68.5)/1.5 = 196.5/1.5 = 131

今、我々は分別探しているので、我々は小数部分我々避難所を追跡する必要があります上記の次のピクセルが100であれば、

(137 * 0.5)+100)/1.5=(68.5 + 100)/1.5=168.5/1.5 = 112。3

次に、三角形の幅が減少するにつれて、三角形の幅を垂直に上に移動する同様の方法に従って、hypotenuse =四角形の底辺では、これは自明に1になります。例えば1.23であり、上記のように計算を行うことができる。

最後にいくつかの大まかな擬似コード:

map(rectangle, triangle) { 

    decimal yRatio = triangle.height/rectangle.height 
    decimal lastY = 0;//we need decimal indeices for fractional averages 

    for each line in dest height (yIndex, 0 based) { 
    //here you could even find the average width of the rectangle 
    //over the block height, but we won't bother 
    decimal xRatio = triangle[yIndex].width/rectangle[floor(yIndex*yRatio)].width 
    decimal lastX = 0; //again a decimal for fractional averages 

    for each pixel in dest line width (xIndex, 0 based) { 

     decimal pixelAverage = 0; 
     decimal tempYRatio = yRatio; 
     decimal destY = yRatio * yIndex; 

     //Here we calculate the source pixel block average 
     while(tempYRatio > 0) { 
      //the portion of this row of pixels we use is the minimum 
      //of the distance to the next integer, and what we need 
      decimal yFraction = minimum(tempYRatio, nextInt(destY) - destY); 

      decimal tempXRatio = xRatio; 
      decimal destX = xRatio * xIndex; 
      while(tempXRatio > 0) { 
      decimal xFraction = minimum(tempXRatio, nextInt(destX) - destX); 
      //now add the weighted pixel to the average 
      average += rectangle[floor(destY)][floor(destX)]*xFraction*yFraction; 

      tempXRatio -= xFraction; //reduce the block size 
      destX += xFraction;  //and shift the source index 
      } 

      tempYRatio -= yFraction; //reduce the block size 
      destY += yFraction;  //and shift the source index 
     } 

     destination[yIndex][xIndex] = average/(xRatio*yRatio); 
    } 
    } 
} 
//a helper function to find the next integer value 
integer nextInt(decimal d) { 
    integer ret = ceiling(d); 
    return d == ret ? d+1 : ret; 
} 

これは私の頭の上からなので、私はそれが完全に正しいことを保証することはできませんが、それは平均を行っ最低で良いスタートする必要があります個々の画素のRGB成分のそれぞれと適切に対応する。

+0

あなたの答えは大変ありがとうございます。私は質問を更新しました。 – Rella

関連する問題