2010年1月30日土曜日

やっと色相環、完成。

望みがやっと達成されました。
綺麗に色相環が実現できました。
imagefilledarcとimagefilledellipseの両方を使って実現。
ありがたや。。。

<?php
    $img = imagecreatetruecolor(400, 400);
    $bg=imagecolorallocate($img,0,0,0);
    $r2=150;
    $s=1;$v=1;

function toH($a){
    $result=round((round($a,3)*255));
    return $result;
}
for($h=0;$h<360;$h++){
    $y0=$r2*(sin(deg2rad($h)));
    $x0=$r2*(cos(deg2rad($h)));
    $y=$y0+200;
    $x=$x0+200;
    
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){$r = $v;$g = $t;$b = $p;}
elseif($hi == 1){$r = $q;$g = $v;$b = $p;}
elseif($hi == 2){$r = $p;$g = $v;$b = $t;}
elseif($hi == 3){$r = $p;$g = $q;$b = $v;}
elseif($hi == 4){$r = $t;$g = $p;$b = $v;}
elseif($hi == 5){$r = $v;$g = $p;$b = $q;}
//else{$r = $v;$g = $v;$b = $v;}
$col=imagecolorallocate($img,toH($r),toH($g),toH($b));    
$col0=imagecolorallocate($img,0,0,0);    
imagefilledarc($img,200,200,300,300,$h,$h+1,$col
    ,IMG_ARC_PIE);
imagefilledellipse($img,200,200,200,200,$col0);

}
    header("Content-Type: image/png");
    imagepng($img);

?>

■今後の課題としては、色相環はできたので、
明度を下げてだんだん中心に向かってフェードさせる、
といったことを実現したいな、と。

IMG_ARC_NOFILLというstyle指定があって、淵だけが描かれるので、
それをつかって、中心に向かってだんだん明度Vを下げていこうかな、と。

外に向かっても少しずつ下げていくと綺麗かな。。

imagefilledarc()にて、色相環。

imagefilledarc($img,200,200,300,300,$h,$h+1,$col,IMG_ARC_PIE);
ということで、弧をつくってやると、また綺麗になりました。

第2、第3引数は、円の中心x.y座標。
第4、第5引数は、幅と高さ。
第6、第7引数は、開始角と終了角。
第8は、色。
第9は、どのような法則で描画させるかのオプションでした。
(該当PHPマニュアルページ)

色相環、完成!

とうとう色相環が出来ました!(^^)!
ずっとエラーが出ていて、悩みました。
$rという変数を半径にしていたのですが、
$rはredの値を格納する変数にもしていたので、
バッティングしていたのに気づけませんでした。。

ともあれ、とりあえず完成です。

でも、filledellipseで360個の円をHSVの値を変えて表現しているので、
赤い円が最後にオレンジを食ってます。

これを、弧で実現すればたぶん行けると思うんですが、とりあえず今日は終了。




<?php
    $img = imagecreatetruecolor(400, 400);
    $bg=imagecolorallocate($img,0,0,0);
    $r2=150;
    $s=1;$v=1;

function toH($a){
    $result=round((round($a,3)*255));
    return $result;
}
for($h=0;$h<360;$h++){
    $y0=$r2*(sin(deg2rad($h)));
    $x0=$r2*(cos(deg2rad($h)));
    $y=$y0+200;
    $x=$x0+200;
    
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){$r = $v;$g = $t;$b = $p;}
elseif($hi == 1){$r = $q;$g = $v;$b = $p;}
elseif($hi == 2){$r = $p;$g = $v;$b = $t;}
elseif($hi == 3){$r = $p;$g = $q;$b = $v;}
elseif($hi == 4){$r = $t;$g = $p;$b = $v;}
elseif($hi == 5){$r = $v;$g = $p;$b = $q;}
//else{$r = $v;$g = $v;$b = $v;}
$col=imagecolorallocate($img,toH($r),toH($g),toH($b));    
imagefilledellipse($img, $x, $y, 50, 50, $col);
}
    header("Content-Type: image/png");
    imagepng($img);

?>

2010年1月29日金曜日

HSVからRGBに変換した値の表示。

一応、H=0~359の色相におけるRGBの値を256階層でテーブル表示させるコードが出来ました。
ずらっと長いテーブルが生成されます(^^;。

これを次は、GDででも色付けしてPNG化です。
楽しみなり。

その後、sin(),cos()あたりで色相環の完成か。
楽しみっす。。。
<?php

echo "<table cellpadding='1' border='1'>";
echo "<tr><th>H</th><th>R</th><th>G</th><th>B</th></tr>";
for($h=0;$h<360;$h++){
$s=1;$v=1;
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){
$r = $v;$g = $t;$b = $p;
}
elseif($hi == 1){
$r = $q;$g = $v;$b = $p;
}
elseif($hi == 2){
$r = $p;$g = $v;$b = $t;
}
elseif($hi == 3){
$r = $p;$g = $q;$b = $v;
}
elseif($hi == 4){
$r = $t;$g = $p;$b = $v;
}
elseif($hi == 5){
$r = $v;$g = $p;$b = $q;
}
else{
$r = $v;$g = $v;$b = $v;
}
echo "<tr><th>".$h."</th><td>".toHex($r)
."</td><td>",toHex($g),"</td><td>"
.toHex($b)."</td></td>";
}
echo "</table>";
function toHex($a){
    $result=round((round($a,3)*255));
    return $result;
}
?>
参考にさせていただいたページ。
http://movingahead.seesaa.net/article/139081151.html
感謝。

■後日に書いた追記です。
各度と円の6区分とRGB値と、x、y座標などを一覧表示させたテーブルページへのリンクをはっておきます。
 http://labo.web-do.com/php/colors/hsv_show.php
ちょっとRGBの背景色がいけてないんですが、眺めていると色々勉強になります。。

HSV色空間についてのメモ

最近、色相環をPHPで実現したいと思って、時々「どうしたら実現できるかなあ。。360度の6つの領域の色の変化を、各6領域でRGBをそれぞれ条件に沿って変化させるか。」などと考えていました。

が、ふと「HSV色空間」のことを知り、どうもその方向で実現できそうだとわかりました。
何事にも、先達のあらまほしきことなり。
やはり先賢は賢いなあ、と。


http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
wikipediaの「HSV色空間」へのリンク。
http://movingahead.seesaa.net/article/139081151.html
PHPで実現されたようであるかたのページリンク。
http://ja.wikipedia.org/wiki/%E5%90%88%E5%90%8C%E5%BC%8F
360を60で割って、その剰余を求める、ということが6領域をスマートに割り出す鍵であることが分かり、「mod」について勉強した際のwikipediaリンク。

少し理解できてきたので(まだかなり怪しいですが。。)、
GDでも使って色相環を実現したいな、と。

なんか、ずっと色相環を実現したかったんですよね~
憧れのような(笑)

がんばろっと。

(色々やることあるのに、何をやってるんだか、という突っ込みを自分に入れつつ。。)

2010年1月22日金曜日

やっと円が描けました。。

PHP+GDを使って円を描こうと思い、やっと描けました。
まだ、味も素っ気もねえですが。。(^^;
サインとコサインを使っての演習、ということで。

これから進化してゆきます。時計の文字盤とか、色をとりどりにするとか。RGBをいろいろ使って。。。



<?php

header('Content-type: image/png');

$image=imagecreate(400,400);
imagecolorallocate($image,200,200,200);
$color=imagecolorallocate($image,0,0,0);
for($i=0;$i<361;$i++){
        imagesetpixel($image,(200+(100*round(cos(deg2rad($i)),3))),(200+(100*round(sin(deg2rad($i)),3))),$color);
}
imagepng($image);
imagedestroy($image);

sinとcosを表にしてみました。(数学学習のため。。)

sinとcosの関係を理解したくて、ちょっとコードを書いてみました。
高校時代、意味不明でしたが、コードを書いているとわかってきました。

僕が関わる子供たちと、sin,cosの話をして、「どうやったら、わかるようになるかなあ。。」と考えていたので、こういうのはいいかな、と。
echo "<table border='1' cellspacing='0'>";
echo "<thead bgcolor='orange'><tr><th>角度</th><td>cos</td><td>sin</td></tr></thead>";
for($i=0;$i<361;$i=$i+30){
    echo "<tr><th align='right'>{$i}</th><td>".round(cos(deg2rad($i)),3)."</td><td>".round(sin(deg2rad($i)),3)."</td></tr>";
}
echo "</table>";

で、表示結果はこんな感じです。(round関数で、小数点以下3桁まで表示)




数学を簡単なプログラミングを通して学ぶと、一番効果的なんじゃないかと思うこのごろです。。

そのために一番子供たちに簡単に触れられるプログラミング言語はなんでしょうね。。。PHPは手軽ですが、ローカルに環境を作るのが難しいですし。。
探してみませんと。。