お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"渦巻きを描く"



 ふと思いついて、渦巻きを描いてみました。(^^;
以前教えていただいたベジエで円や楕円を描く方法を応用したらできるんじゃな
いかと思ってやってみた次第です。象限によっていろいろやっているのであまり
スマートでない(行列式を使うともっとスマート?)ような気がしますが、数学弱
いので勘弁して下さい。(^^;;

 ボタンを一つおいたフォームのボタンクリックイベントにイカのように書いて
下さい。



procedure TForm1.Button1Click(Sender: TObject);
type
  TQArc=Array[0..3] of TPoint;
const
  cx=300;
  cy=300;        //渦の中心
  r0=10;         //最初のR
  dr=10;         //rの変化量(90度毎)
  arcCount=20;   //1/4円の数
  angleStep=10;  //回転時の粗さ
  speed=10;      //回転時のsleepタイム ms
var
  m:Double;      //ベジエで円を書くための制御点定数
  shogen:integer;       //0〜3
  i,ii,j:integer;
  aa,rr:Array of TQArc;//ベジエ曲線用の点を保持
  c:array[0..3] of TPoint;//各象限の中心
  currR:integer;       //現R
  function rot(p:TPoint;angle:Extended{rad}):TPoint;
  begin
    result.x:=Trunc((p.x-cx)*cos(angle)+(p.y-cy)*sin(angle))+cx;
    result.y:=Trunc((p.x-cx)*-sin(angle)+(p.y-cy)*cos(angle))+cy;
  end;
begin
  //初期化
  shogen:=0;
  m:=4.0/3.0*(sqrt(2)-1.0);

  //処理

  currR:=r0;
  setLength(aa,arcCount);
  setLength(rr,arcCount);
  //中心を決定
  c[0]:=Point(cx-dr div 2,cy-dr div 2);
  c[1]:=Point(cx-dr div 2,cy+dr div 2);
  c[2]:=Point(cx+dr div 2,cy+dr div 2);
  c[3]:=Point(cx+dr div 2,cy-dr div 2);
  for i:= 0 to arcCount-1 do
  begin
    //回転していない状態で点を定義
    case shogen of
    0:begin
        aa[i][0]:=Point(c[0].x+currR         ,c[0].y               );
        aa[i][1]:=Point(c[0].x+currR         ,c[0].y-Round(currR*M));
        aa[i][2]:=Point(c[0].x+Round(currR*M),c[0].y-currR         );
        aa[i][3]:=Point(c[0].x               ,c[0].y-currR         );
      end;
    1:begin
        aa[i][0]:=Point(c[1].x               ,c[1].y-currR         );
        aa[i][1]:=Point(c[1].x-Round(currR*M),c[1].y-currR         );
        aa[i][2]:=Point(c[1].x-currR         ,c[1].y-Round(currR*m));
        aa[i][3]:=Point(c[1].x-currR         ,c[1].y               );
      end;
    2:begin
        aa[i][0]:=Point(c[2].x-currR         ,c[2].y);
        aa[i][1]:=Point(c[2].x-currR         ,c[2].y+Round(currR*M));
        aa[i][2]:=Point(c[2].x-Round(currR*M),c[2].y+currR);
        aa[i][3]:=Point(c[2].x               ,c[2].y+currR);
      end;
    3:begin
        aa[i][0]:=Point(c[3].x               ,c[3].y+currR         );
        aa[i][1]:=Point(c[3].x+Round(currR*M),c[3].y+currR         );
        aa[i][2]:=Point(c[3].x+currR         ,c[3].y+Round(currR*m));
        aa[i][3]:=Point(c[3].x+currR         ,c[3].y               );
      end;
    end;
    inc(shogen);
    currR:=currR+dr;
    if shogen=4 then shogen:=0;
  end;
  //ぐりぐり回転
  for ii:=0 to 100 do
  begin
    //回転させる
    for i:= 0 to arcCount-1 do
    begin
      for j:=0 to 3 do
      begin
        rr[i][j]:=rot(aa[i][j],ii/angleStep);
      end;
    end;
    //描画
    Canvas.Pen.Color:=clRed;
    for i:= 0 to arcCount-1 do
    begin
      canvas.PolyBezier(rr[i]);
    end;
    sleep(speed);
    application.processmessages;
    Canvas.pen.Color:=color;
    for i:= 0 to arcCount-1 do
    begin
      canvas.PolyBezier(rr[i]);
    end;
  end;
end;

☆☆☆  かわいいコードにゃ旅をさせよう いざサンプル蔵へ!! ☆☆☆
                                 99/10/29(金) 07:28 凛(MXB01744)

Original document by 凛              氏 ID:(MXB01744)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum