はじめまして、Delphi初心者です。
正方形の書き方と、正三角形の書き方が分かりません。
正方形はRectangleを使わないで描きたいのです。
正三角形は中点を使って描きたいのです。
さっぱり分からなくて、手も足も出ない状態なので
どなたか教えてください。お願いします。
紙に正方形を書く方法は分かってるね?
同じ長さの4本の直線を互いに直角に書けばいい。
PC画面(Canvas)に直線を書く関数は、MoveToとLineTo。
中点を使って三角形を紙に書く方法がわかれば、PC画面にも書ける。
正方形の書き方は分かりますが、直角に書くのをどうやって表せばいいんでしょうか?
特別な宣言というか、直角を(right angle)と書くとか…(r-_-)r
そういうのってあるんですか?
あと、線の始めをX1,Y1。線の終わりをX2,Y2。と宣言して書いたんですが、
private宣言を{X1,Y1,X2,Y2:integer;}したのに使えないんですが。
integerは間違いなんですかねぇ。。。
Logo言語ではないので、正方形、三角形の頂点座標を指定して各頂点を結ぶ直線を描画。
MoveTo(x,y)が直線の開始点、LineTo(x,y)が終了点だけど、「クラス変数」を「クラスメソッドではない関数」内で使う場合には、MoveTo(Form1.X, Form1.Y)のようにクラスの指定が必要。
線や図形は、Canvas(カンバス、キャンバス)の上に描きます。
Canvasというのは、油絵のキャンバスと同じ意味です。
ここに描きます。
全ての図形は、基本的に線をつなげて構成します。
円を描くメソッド(関数)もありますが、内部では細かい線分で分けて描画
しています。
(1)新規にプロジェクトを作成。
(2)ボタン(TButton)を一つ配置。Form1の上ならどこでも可。
(3)このボタンをダブルクリックします。
procedure TForm1.Button1Click(Sender: TObject);
begin
end;
というコードができます。ここにコードを追加して以下の様にします。
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
X1,X2,Y1,Y2: Integer;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
X1:=50;
X2:=300;
Y1:=60;
Y2:=60;
Form1.Canvas.MoveTo(X1,Y1);
Form1.Canvas.LineTo(X2,Y2);
end;
これは、Form1のCanvasの座標(50,60)から(300,60)まで線を引くことになります。
これに直角に線を引きたいなら、自分で計算して、考えて引きます。
座標は常にドット値です。上のForm1で言えば、
左の[オブジェクト・インスペクタ]のWidthがForm1のドット数で、
Heightの値がFormの縦方向のドット数です。
数値は、privateでもpublic部にでも変数を定義して使用できます。
正三角形を描きたいなら、描くための計算式通りに実行する
プログラムコードを自分で作成する必要があります。
数学的なことが理解できていないと無理があります。
ついでに勉強してしまうという考え方もあります。
ついでに、もし、上手く動作しない場合は、このように、簡単なコードで
確認して、それを示さないと、中々解決しませんね。
何故なら、貴方のPC上、Delphiで行っていることが、こちらからは全く
見えないからです。
「正三角形は中点を使って描きたいのです」
の意味がわかりません。
一体何を言いたいのか?
人間がコンパスと定規を使って作画するあの方法のこと?
でもコンピュータ上でそれを模する意図とはなんですか?
指定した座標を中心とする円の円周上に3点がある正三角形を書きたいのではないかと思うのですが、計算式だけ考えて、素でコードを書こうとすると結構めんどくさいです。
ある点をクリックして、ドラッグして三角形の大きさを決めて
OnMouseUpで描画するとか。そんな感じかな。
こういうのは、ロジックから考えたほうが手っ取り早いです。
とりあえず、指定した座標を(PX,PY)とし、半径を R とするなら
(PX,PY)から、その真上(↑方向)にR だけ移動した
円周上にある点を (X1,Y1)として、それを基準に
他の2点 (X2,Y2) (X3,Y3)を求めていけば、簡単にできるでしょう。
後は点を線で結ぶだけです。
(X1,X2)=(PX,PY - R)です。
private
に
FStartPoint:TPoint;
を宣言
implementation
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then
FStartPoint:= Point(X,Y);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
DistX,DistY: integer;
x1,y1,x2,y2: integer;
begin
if ssLeft in Shift then
begin
DistX:= abs( X - FStartPoint.X);
//DistY:= abs( Y - FStartPoint.Y); //楕円
DistY:= DistX; //円
x1:= FStartPoint.X - DistX;
x2:= FStartPoint.X + DistX;
y1:= FStartPoint.Y - DistY;
y2:= FStartPoint.Y + DistY;
Canvas.Ellipse( x1,y1,x2,y2);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
//CON_MATH_R_TRANS_D=57.2957801818848; // (180/pi)
CON_MATH_D_TRANS_R=0.0174632929265499; // (pi/180)
var
DistX,DistY: integer;
x1,y1,
x2,y2,
x3,y3: integer;
begin
DistX:= abs( X - FStartPoint.X);
//DistY:= abs( Y - FStartPoint.Y); //楕円の円周上に3点を置く場合
DistY:= DistX; //円の円周上に3点を置く場合
x1:= FStartPoint.X;
y1:= FStartPoint.Y - DistY;
x2:= trunc(FStartPoint.X + (cos(CON_MATH_D_TRANS_R * (30)) * DistX));
y2:= trunc(FStartPoint.Y + (sin(CON_MATH_D_TRANS_R * (30)) * DistY));
x3:= trunc(FStartPoint.X - (cos(CON_MATH_D_TRANS_R * (-30)) * DistX));
y3:= trunc(FStartPoint.Y - (sin(CON_MATH_D_TRANS_R * (-30)) * DistY));
Canvas.MoveTo(x1,y1);
Canvas.LineTo(x2,y2);
Canvas.LineTo(x3,y3);
Canvas.LineTo(x1,y1);
end;
多くの方々からたくさんのアドバイス、ありがとうございます。
Delphi初心者でして、無防備に質問を投げ掛けた事。
分かりにくかったようで大変失礼いたしました。
つまりは、1本の直線を引いた所から正三角形と正方形を同時に描き出すプログラムを作りたかったのです。
正方形の場合、それぞれの点から直角に直線を書き出して、正方形を作る。
正三角形の場合、最初に引いた1本の線の中点を求めた上で、それぞれの点から直線を書き正三角形を作る。
と、これらの作業をしたかったのです。
この説明でもうまく伝わらないかと…自分では精一杯なんですが^^;
しばらく漠然と考えていたのでさっぱりできませんでしたが、
みなさんにアドバイスを頂いたお陰でなんとかプログラムは完成いたしました。
どうもありがとうございました。
失礼します。
「直線」ではなく「線分」。
あと、正方形、正三角形とも、一辺が確定すれば一意に決定します(正確には、鏡像が2種類だけど)。
これらは中学生が学校で習うレベルです。
任意の三角形がと1点が与えられたとき、この点が三角形の内部にあるかどうか? とかになるとかなり難易度が高くなります。