using System;
public class Test
{
public static void Main( )
{
// your code goes here
}
// 関数:ノーマル生成
private Bitmap GetNormal( )
{
Bitmap bm = new Bitmap( WIDTH, HEIGHT) ;
// 傾斜の強度
int x1 = int .Parse ( comboBox1.SelectedItem .ToString ( ) ) * - 1 ;
int x2 = int .Parse ( comboBox1.SelectedItem .ToString ( ) ) ;
double dPre, dNow, dNex;
double y1, y2;
int result, r, g, b = 255 ;
int [ , ] RN = new int [ WIDTH, HEIGHT] ;
int [ , ] GN = new int [ WIDTH, HEIGHT] ;
// 端の1ピクセルの法線カラーは 127 の固定値に設定
for ( int i = 0 ; i < WIDTH; i++ )
{
RN[ i, 0 ] = 127 ;
GN[ i, 0 ] = 127 ;
RN[ i, HEIGHT - 1 ] = 127 ;
GN[ i, HEIGHT - 1 ] = 127 ;
}
for ( int j = 0 ; j < HEIGHT; j++ )
{
RN[ 0 , j] = 127 ;
GN[ 0 , j] = 127 ;
RN[ WIDTH - 1 , j] = 127 ;
GN[ WIDTH - 1 , j] = 127 ;
}
// 横方向で法線算出
for ( int j = 1 ; j < HEIGHT - 1 ; j++ )
for ( int i = 1 ; i < WIDTH - 1 ; i++ )
{
dPre = pdataGray[ i - 1 , j] ;
dNow = pdataGray[ i, j] ;
dNex = pdataGray[ i + 1 , j] ;
y1 = dPre - dNow;
y2 = dNex - dNow;
result = GetRadianFrom2Vec( x1, x2, y1, y2) ;
RN[ i, j] = result;
}
// 縦方向で法線算出
for ( int j = 1 ; j < HEIGHT - 1 ; j++ )
for ( int i = 1 ; i < WIDTH - 1 ; i++ )
{
dPre = pdataGray[ i, j - 1 ] ;
dNow = pdataGray[ i, j] ;
dNex = pdataGray[ i, j + 1 ] ;
y1 = dPre - dNow;
y2 = dNex - dNow;
result = GetRadianFrom2Vec( x1, x2, y1, y2) ;
GN[ i, j] = result;
}
// 法線カラーを適用
for ( int j = 0 ; j < HEIGHT; j++ )
for ( int i = 0 ; i < WIDTH; i++ )
{
r = 255 - RN[ i, j] ;
g = 255 - GN[ i, j] ;
bm.SetPixel ( i, j, Color.FromArgb ( r, g, b) ) ;
}
return bm;
}
// 関数:2つのベクトルのなす角度を求める
private int GetRadianFrom2Vec( double x1, double x2, double y1, double y2)
{
double rad1, rad2, rad3;
int result;
// X軸ベクトルとのなす角を求める
rad1 = Math.Atan2 ( y1, x1) ;
rad2 = Math.Atan2 ( y2, x2) ;
// 結果がマイナスの場合にプラスに変換
int i1 = Math.Sign ( rad1) ;
if ( i1 == - 1 ) rad1 += ( Math.PI * 2 ) ;
// 90度の補正を入れる(傾斜を法線にするため)
rad1 = rad1 - ( Math.PI / 2 ) ;
rad2 = rad2 + ( Math.PI / 2 ) ;
// 最終的な角を求める
rad3 = ( rad1 + rad2) / 2 ;
// 1πラジアンが1になるよう補正
rad3 = rad3 / Math.PI ;
// 8bitの値に変換
result = ( int ) ( rad3 * 255 ) ;
result = Math.Max ( 0 , result) ;
result = Math.Min ( 255 , result) ;
return ( result) ;
}
}
dXNpbmcgU3lzdGVtOwoKcHVibGljIGNsYXNzIFRlc3QKewoJcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQoJewoJCS8vIHlvdXIgY29kZSBnb2VzIGhlcmUKCX0KCQoJLy8g6Zai5pWw77ya44OO44O844Oe44Or55Sf5oiQCgkJcHJpdmF0ZSBCaXRtYXAgR2V0Tm9ybWFsKCkKCQl7CgkJCUJpdG1hcCBibSA9IG5ldyBCaXRtYXAoV0lEVEgsIEhFSUdIVCk7CgoJCQkvLyDlgr7mlpzjga7lvLfluqYKCQkJaW50IHgxID0gaW50LlBhcnNlKGNvbWJvQm94MS5TZWxlY3RlZEl0ZW0uVG9TdHJpbmcoKSkgKiAtMTsKCQkJaW50IHgyID0gaW50LlBhcnNlKGNvbWJvQm94MS5TZWxlY3RlZEl0ZW0uVG9TdHJpbmcoKSk7CgoJCQlkb3VibGUgZFByZSwgZE5vdywgZE5leDsKCQkJZG91YmxlIHkxLCB5MjsKCQkJaW50IHJlc3VsdCwgciwgZywgYiA9IDI1NTsKCQkJaW50WyxdIFJOID0gbmV3IGludFtXSURUSCwgSEVJR0hUXTsKCQkJaW50WyxdIEdOID0gbmV3IGludFtXSURUSCwgSEVJR0hUXTsKCgkJCS8vIOerr+OBrjHjg5Tjgq/jgrvjg6vjga7ms5Xnt5rjgqvjg6njg7zjga8gMTI3IOOBruWbuuWumuWApOOBq+ioreWumgoJCQlmb3IgKGludCBpID0gMDsgaSA8IFdJRFRIOyBpKyspCgkJCXsKCQkJCVJOW2ksIDBdID0gMTI3OwoJCQkJR05baSwgMF0gPSAxMjc7CgkJCQlSTltpLCBIRUlHSFQgLSAxXSA9IDEyNzsKCQkJCUdOW2ksIEhFSUdIVCAtIDFdID0gMTI3OwoJCQl9CgkJCWZvciAoaW50IGogPSAwOyBqIDwgSEVJR0hUOyBqKyspCgkJCXsKCQkJCVJOWzAsIGpdID0gMTI3OwoJCQkJR05bMCwgal0gPSAxMjc7CgkJCQlSTltXSURUSCAtIDEsIGpdID0gMTI3OwoJCQkJR05bV0lEVEggLSAxLCBqXSA9IDEyNzsKCQkJfQoKCQkJLy8g5qiq5pa55ZCR44Gn5rOV57ea566X5Ye6CgkJCWZvciAoaW50IGogPSAxOyBqIDwgSEVJR0hUIC0gMTsgaisrKQoJCQkJZm9yIChpbnQgaSA9IDE7IGkgPCBXSURUSCAtIDE7IGkrKykKCQkJCXsKCQkJCQlkUHJlCT0gcGRhdGFHcmF5W2kgLSAxLCBqXTsKCQkJCQlkTm93CT0gcGRhdGFHcmF5W2ksIGpdOwoJCQkJCWROZXgJPSBwZGF0YUdyYXlbaSArIDEsIGpdOwoJCQkJCXkxID0gZFByZSAtIGROb3c7CgkJCQkJeTIgPSBkTmV4IC0gZE5vdzsKCgkJCQkJcmVzdWx0ID0gR2V0UmFkaWFuRnJvbTJWZWMoeDEsIHgyLCB5MSwgeTIpOwoKCQkJCQlSTltpLCBqXSA9IHJlc3VsdDsKCQkJCX0KCQkJLy8g57im5pa55ZCR44Gn5rOV57ea566X5Ye6CgkJCWZvciAoaW50IGogPSAxOyBqIDwgSEVJR0hUIC0gMTsgaisrKQoJCQkJZm9yIChpbnQgaSA9IDE7IGkgPCBXSURUSCAtIDE7IGkrKykKCQkJCXsKCQkJCQlkUHJlID0gcGRhdGFHcmF5W2ksIGogLSAxXTsKCQkJCQlkTm93ID0gcGRhdGFHcmF5W2ksIGpdOwoJCQkJCWROZXggPSBwZGF0YUdyYXlbaSwgaiArIDFdOwoJCQkJCXkxID0gZFByZSAtIGROb3c7CgkJCQkJeTIgPSBkTmV4IC0gZE5vdzsKCgkJCQkJcmVzdWx0ID0gR2V0UmFkaWFuRnJvbTJWZWMoeDEsIHgyLCB5MSwgeTIpOwoKCQkJCQlHTltpLCBqXSA9IHJlc3VsdDsKCQkJCX0KCgkJCS8vIOazlee3muOCq+ODqeODvOOCkumBqeeUqAoJCQlmb3IgKGludCBqID0gMDsgaiA8IEhFSUdIVDsgaisrKQoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBXSURUSDsgaSsrKQoJCQkJewoJCQkJCXIgPSAyNTUgLSBSTltpLCBqXTsKCQkJCQlnID0gMjU1IC0gR05baSwgal07CgoJCQkJCWJtLlNldFBpeGVsKGksIGosIENvbG9yLkZyb21BcmdiKHIsIGcsIGIpKTsKCQkJCX0KCQkJCgkJCXJldHVybiBibTsKCQl9CgkJLy8g6Zai5pWw77yaMuOBpOOBruODmeOCr+ODiOODq+OBruOBquOBmeinkuW6puOCkuaxguOCgeOCiwoJCXByaXZhdGUgaW50IEdldFJhZGlhbkZyb20yVmVjKGRvdWJsZSB4MSwgZG91YmxlIHgyLCBkb3VibGUgeTEsIGRvdWJsZSB5MikKCQl7CgkJCWRvdWJsZSByYWQxLCByYWQyLCByYWQzOwoJCQlpbnQgcmVzdWx0OwoKCQkJLy8gWOi7uOODmeOCr+ODiOODq+OBqOOBruOBquOBmeinkuOCkuaxguOCgeOCiwoJCQlyYWQxID0gTWF0aC5BdGFuMih5MSwgeDEpOwoJCQlyYWQyID0gTWF0aC5BdGFuMih5MiwgeDIpOwoJCQkvLyDntZDmnpzjgYzjg57jgqTjg4rjgrnjga7loLTlkIjjgavjg5fjg6njgrnjgavlpInmj5sKCQkJaW50IGkxID0gTWF0aC5TaWduKHJhZDEpOwoJCQlpZiAoaTEgPT0gLTEpIHJhZDEgKz0gKE1hdGguUEkgKiAyKTsKCgkJCS8vIDkw5bqm44Gu6KOc5q2j44KS5YWl44KM44KL77yI5YK+5pac44KS5rOV57ea44Gr44GZ44KL44Gf44KB77yJCgkJCXJhZDEgPSByYWQxIC0gKE1hdGguUEkgLyAyKTsKCQkJcmFkMiA9IHJhZDIgKyAoTWF0aC5QSSAvIDIpOwoKCQkJLy8g5pyA57WC55qE44Gq6KeS44KS5rGC44KB44KLCgkJCXJhZDMgPSAocmFkMSArIHJhZDIpIC8gMjsKCgkJCS8vIDHPgOODqeOCuOOCouODs+OBjDHjgavjgarjgovjgojjgYboo5zmraMKCQkJcmFkMyA9IHJhZDMgLyBNYXRoLlBJOwoJCQkvLyA4Yml044Gu5YCk44Gr5aSJ5o+bCgkJCXJlc3VsdCA9IChpbnQpKHJhZDMgKiAyNTUpOwoJCQlyZXN1bHQgPSBNYXRoLk1heCgwLCByZXN1bHQpOwoJCQlyZXN1bHQgPSBNYXRoLk1pbigyNTUsIHJlc3VsdCk7CgoJCQlyZXR1cm4gKHJlc3VsdCk7CgkJfQp9