16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"斜め楕円の描画"
この発言に対し以下のコメントが寄せられています
#00601 凛 さん RE:斜め楕円の描画
■長軸短軸径がa,b 傾斜角度がrad(ラジアン)の楕円を x0,y0平行移動して描く
注)
Win95の PolyBezier(hdc,dt,18+1) を利用していますから Delphi1では
使えません。
// 精度 1/10000 の斜め楕円描画
// fEllipse6の精度は16bit整数の範囲で1LSBの誤差程度しかありませんから
// Win95で使用するぶんには十分でしょう。
function fEllipse6(hdc:THandle;a,b,rad,x0,y0:double):boolean;
var i,j:integer;
dt :array[0..18]of TPoint;
var dx :array[0..18]of double;
var dy :array[0..18]of double;
var x,y,s,c,r3:double;
begin
r3:=sqrt(3);
dx[0]:=1;
dy[0]:=0;
dx[1]:=1;
dy[1]:=8/3 -4.0/3.0*r3;
dx[2]:=4/3*r3 -3/2;
dy[2]:=7/6*r3 -4/3;
c:=2*pi/6;
s:=sin(c);
c:=cos(c);
for i:=1 to 5 do
for j:=0 to 2 do begin
x:= dx[ (i-1)*3+j];
y:= dy[ (i-1)*3+j];
dx[i*3+j]:= x*c-y*s;
dy[i*3+j]:= x*s+y*c;
end;
dx[18]:=1;
dy[18]:=0;
s:=sin(rad); c:=cos(rad);
for i:=0 to 18 do begin
dt[i].x:=round(c*a*dx[i]-s*b*dy[i]+x0);
dt[i].y:=round(c*b*dy[i]+s*a*dx[i]+y0);
end;
Result:=PolyBezier(hdc,dt,18+1);
end;
// 精度 1/1000 の斜め楕円描画
// fEllipse4の精度は1/1000はありますから画面への描画程度なら十分でしょう
function fEllipse4(hdc:THandle;a,b,rad,x0,y0:double):boolean;
var i,j:integer;
dt :array[0..12]of TPoint;
var dx :array[0..12]of double;
var dy :array[0..12]of double;
var x,y,s,c:double;
begin
dx[0]:=1;
dy[0]:=0;
dx[1]:=1;
dy[1]:=4.0/3.0*(sqrt(2)-1.0);
dx[2]:=dy[1];
dy[2]:=1;
c:=2*pi/4;
s:=sin(c);
c:=cos(c);
for i:=1 to 3 do
for j:=0 to 2 do begin
x:= dx[ (i-1)*3+j];
y:= dy[ (i-1)*3+j];
dx[i*3+j]:= x*c-y*s;
dy[i*3+j]:= x*s+y*c;
end;
dx[12]:=1;
dy[12]:=0;
s:=sin(rad); c:=cos(rad);
for i:=0 to 12 do begin
dt[i].x:=round(c*a*dx[i]-s*b*dy[i]+x0);
dt[i].y:=round(c*b*dy[i]+s*a*dx[i]+y0);
end;
Result:=PolyBezier(hdc,dt,13);
end;
[アルゴリズム解説]
半径1単位円の1/6を ベジェ曲線に当て嵌め、それを座標変換する事で
楕円を描かせます。
■ベジェ曲線の方程式は
x(t)= (1-t)^3*x1+3(1-t)^2*t*x2+3(1-t)*t^2*x3+t^3*x4
y(t)= (1-t)^3*y1+3(1-t)^2*t*y2+3(1-t)*t^2*y3+t^3*y4
■ベジェ曲線への当て嵌め方は
1) 端点が一致する事
x1=cos(0),y1=sin(0) ,x4=cos(Φ),y4=sin(Φ);
2) 中間点が一致する事
(x1+3x2+3x3+x4)/8 =cos(Φ/2)
(y1+3y2+3y3+y4)/8 =sin(Φ/2)
3) 微分が t=0,t=1で一致する事
t=0 ---> x2=x1
t=1 ---> -x3+x4 / -y3+y4 =-tan(Φ)
上記で Φ=2π/6 として求めたものが fEllipse6 Φ=2π/4の時がfEllipse4
■利用方法
FormのonPaintに
fEllipse4(Canvas.Handle,50,100,pi/3,100,100);
のように書けば、長軸100短軸50 60度傾斜した楕円が描けます。
■応用
Φ=2π/12 とすれば 1E-6の精度が得られますが、Windowsの描画の世界
では不要な精度でしょう。
Original document by 裏目小僧 氏 ID:(GGA03463)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|