Delphiの全くの初心者何ですが。学校の授業で「Delphiで20−40個の同心円を書くプログラムをつくろう」という課題が出されたが、ぜんぜん検討がつかなくて...
procedure DrawCircle(cvs: TCanvas; radius:integer; centerX, centerY: integer);
begin
cvs.Ellipse(centerX-radius,centerY-radius,centerX+radius,centerY+radius);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
Canvas.Pen.Color := clBlue;
Canvas.Brush.Style := bsClear;
for i := 0 to 40 do
DrawCircle(Canvas, 10+i*3, 200, 200);
end;
方眼紙を買ってきます。
縦横メモリを引きます。
コンパスで円を書きます。
その線とかさなった、点を
方眼紙とにらめっこして、Canvas.Pixels[x,y]
でひたすら、書き込みます。
全部いれたらきっと 望みのものがきます。
単純に考えれば、anoneさんのようにEllipse関数を使うのが妥当でしょう。
学校の授業として、アルゴリズムを勉強したいのであれば、
1.sin/cos関数を使って円を描く
2.Bresenhamのアルゴリズムを用いて円を描く
のどちらかでしょう。
では上記以外の手法で。
これだとドラッグして動かすとかが簡易に実装可能です。
var
NewShape: array[0..19] of TShape;
procedure TForm1.Button1Click(Sender :TObject);
var i : Integer;
begin
for i:= 0 to 19 do
begin
NewShape[i] := TShape.Create(self);
NewShape[i].Parent := self;
NewShape[i].Left := 10 + i*10;
NewShape[i].Top := 10 + i*10;
NewShape[i].Width := 80;
NewShape[i].Height := 80;
NewShape[i].Shape := stCircle;
NewShape[i].Pen.Color := RGB((i*75)and $ff, (64+i*7)and $ff, (i*96+128)and $ff);
NewShape[i].Brush.Color := RGB((i*48+200)and $ff, (i*27 )and $ff, (i*17+ 96)and $ff);
end;
end;
> ウォレスさん
全然「同心円」になってないじゃん
「同心円を書」いてもないし
そのとおりです。送信した後読み直して気づきました。ごみレス(スレ、じゃなくレスです)にさらに追加して醜態をさらすのもどうかと思いましたので、様子を見ました。
勘弁してください。
宿題だから自分から進んでさせないと
身に付かないって。
仕事にしてるわけじゃないから、
身に付かなくてもいいっていうコトじゃ(マテ
お仕事関係の質問には身に付くよう直接答えない方がいいんですかね?
> お仕事関係の質問には身に付くよう直接答えない方がいいんですかね?
私はこの掲示板の管理人ではありませんので、私見です。
こういう掲示板の意図は、探せば解る回答を代わりに探して答えるのではなく、「なぜこうなるのか」に対する回答が良いと思います。
単刀直入な答えのみの場合より、考えて理解できた方がよいかと。
単純に、そのものずばりの答えだけが欲しいならば、今回の件で言えば、同じ講習を受けている学生さんに答えだけ聞いて提出するだけですし。
わたしは回答そのものズバリで十分だと思います。
たかがプログラミングの技術に多少すぐれているからといって、人生訓や教訓や
教育的配慮などは回答者の傲慢であると思います。
> たかがプログラミングの技術に多少すぐれているからといって、人生訓や教訓や
> 教育的配慮などは回答者の傲慢であると思います。
であるならば、そのものずばりの回答をするのも、回答者の傲慢ですよね。
否定はしませんが。
> であるならば、そのものずばりの回答をするのも、回答者の傲慢ですよね。
であるならば、の理由がわかりません。
質問者は回答をもとめてここに書き込んでいるわけです。
それ以外になにを求めていると思いますか?
追加で回答の説明を求めれられれば説明する、でなにか不都合がありますか?
> であるならば、の理由がわかりません。
言葉足らずですみません。
私は、人生訓、教訓などを、質問者・回答者に強要しているつもりはありません。
その上で、
「プログラミングの技術に多少優れているからといって」
とあるならば、回答のみをしても同じ事が言えるのではと思ったのです。回答する義務はないわけですから。
読み直してみると、傲慢はここにかかるのでなく、「人生訓・教訓・教育的配慮」にかかるのですね。
読み違いです。すみません。
# 前言撤回でお願いします
> それ以外になにを求めていると思いますか?
今回の件で言えば、「検討がつかない」というのが問題であって、「回答が欲しい」とは読めませんでした。
検討がつかないのであれば、複数の指針を提示するのがよいと判断しました。
> 追加で回答の説明を求めれられれば説明する、でなにか不都合がありますか?
不都合はないと思います。
質問が適確であれば、そのものずばりの回答をするのは適当かと思います。
# ただ、質問と回答のみで終わってしまう場合もあり、寂しい気もします。
私も以前「ブレゼンハムの円アルゴリズム」と何かの本で読んだことがありますが、最近は、
「ブレゼンハムの線アルゴリズム」
「ミッチェナーの円アルゴリズム」
に統一されてるみたい(?)
N-BASICのCRICLE命令(うる覚え)がこれを使っていましたね・・・
調べてみると二つになってますね。
http://www.alpha-net.ne.jp/users2/gmaru/programs_07/pg_graphic_09a1.html
Cですが、ここが日本語サイトでは詳しく書いてました。
# ブレゼンハムとミッチェナー、ほとんど同じ処理のような・・・
ブレゼンハムの円アルゴリズムは、「C言語による最新アルゴリズム辞典」に出ていました。
おお!
そういえばC言語による最新・・に出ていたような。微かに記憶が。
ブレゼンハムとミッチェナー、両方違うものだったんですね。
何れにしても、「円を描こう」というだけの課題であれば、三角関数を使うか、円描画命令を使うか、のどちらかが求められている手法でしょうね。
>Delphiで20−40個の同心円を書くプログラムをつくろう
あっ、
for文をつかって、
TextOut(X, Y '同心円');
私は、こちらの掲示板でよく質問させて頂き回答を頂いています。
私的な意見ですが、書き込みをした人は当然の事ながら最終的には的確な答えを求めています。
ただ、1+1=2 が解っていて 2+2=?? というレベルの方に4と答えだけを与えても3+3が解けないのではないかと思います。
にしのさんのおっしゃる通り、なぜそうなるのかという解説を頂けるととても理解しやすいものになります。こちらで質問する際は事前にGoogleなどで海外サイトなどまで検索してみますが、記述方法はわかっても、なかなか理解できないものです。
質問者は、回答者に対してそれなりの態度で聞くべきだと思いますし、回答を得た(ヒントからでも)のであれば、それなりにお礼を言うべきだと思います。
いろいろ意見をいただいて、ありがとうございました。下には私が書いたプログラムですが、うまくいかなかった。何が間違ったかな〜
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
for i:=1to 40do
begin
with PaintBox1. Canvas do begin
pen.color:=clBlue;Ellipse (1*i,1*i,10*i,10*i);
end;
end;
end;
end .
> Ellipse (1*i,1*i,10*i,10*i);
中心がずれてしまうでしょ。Canvas.Ellipse()の定義を良く見て考えてください。
> にしのさんのおっしゃる通り、なぜそうなるのかという解説を頂けるととても理解しやすいものになります。
「なぜそうなるか」というのは、正しい解答があってはじめて成り立つ疑問・質問
ですよね。回答を示さずには無意味だと思いませんか?
それから、示されたコードの意味がすぐに分かる方もいれば、そうでない方もいますでしょう。
また、コードの意味なんか気にしないで結果だけを求めている人も
います。
スレのタイトルにそった追加の質問は大歓迎ですので、望みどおりの結果になったと
しても、そのコードの意味の説明を求めることも出来るでしょう。
ふふふ。
だから方眼紙にコンパスで円を書いて・・・みろ
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
procedure En(X,Y,R : Integer); //X,Yが中心、Rは半径
begin
PaintBox1.Canvas.Ellipse(); // ここはじぶんで完成すること
//ヒント 足し算と引き算
end;
begin
for i:=1 to 40do
begin
with PaintBox1.Canvas do
begin
Brush.Style := bsClear;
pen.color:=clBlue;
En ( , , ); //ここも自分で完成すること
end;
end;
end;
anoneさんへ。
> 「なぜそうなるか」というのは、正しい解答があってはじめて成り立つ疑問・質問
> ですよね。回答を示さずには無意味だと思いませんか?
私も、回答があっての説明だと思います。
私が言いたかったのは、「回答を書かずに説明を書く」でなく「回答に説明を付けたほうがよい」ということです。
# 私の場合、たまに横着してコードを示さないこともありますが
anoneさんは、「回答だけ書けば、その後わからなければ質問が来る(こともある)のでそれに説明をつければよい」ということですよね。
それもありだと思います。
コードだけ知りたければ、説明は読まなければよいわけで。
えへへさんへ。
このコードだと、ヒントの場所に足し算と引き算はつかわないのでは?
Enを呼ぶ部分で計算すればよいような気がします。
# 私が思いつかないだけかもしれませんが
皆さん本当にありがとう
今も一生懸命プロゴラム考えいるけど・・・
もうちょっとわかりやすいヒントくれないかな・・・
わたしの最初の回答を試しましたか?
なぜうまくいくのか逆から考えてみたら分かりやすいと思います。
anoneさんへ:
anoneさんが教えてくれたプログラムうまく動きました。
でも、DELPHI の初心者で、まだanoneさんのプログラム理解できてないですが・・・
> でも、DELPHI の初心者で、まだanoneさんのプログラム理解できてないですが・・・
理解するつもりがあるのなら、どこがどうわからないのか聞いてみたらいいです。
> DELPHI の初心者で、まだanoneさんのプログラム理解できてないですが
Delphi の初心者は関係ないと思います。普通の算数の問題のような気がします。
TCanvas.Ellipse() はヘルプによると
・Ellipse は,以下のいずれかの値を設定することによって外接四角形を指定します。
・外接四角形が正方形の場合は,円が描画されます。
となっています。あの回答では正方形の左上と右下の点の座標を与えています。
で、正方形の内側に内接する円が描かれます。
同心円を描くためには、まず中心を固定する必要があります。中心点の座標から
正方形の左上と右下の点の座標を計算すると回答になります。それぞれ半径の分を
足したり引いたりするだけです。
バガバガしい質問かもしれない、笑わないでね
procedure DrawCircle(cvs: TCanvas; radius:integer; centerX, centerY: integer);//cvsはなんですか?
begin
cvs.Ellipse(centerX-radius,centerY-radius,centerX+radius,centerY+radius);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
Canvas.Pen.Color := clBlue;
Canvas.Brush.Style := bsClear;
for i := 0 to 40 do
DrawCircle(Canvas, 10+i*3, 200, 200);//ここがわからない
end;
cvs: TCanvas;
ですけど。例のとおり実行すると Form1 の描かれるでしょ。
DrawCircle(Canvas, 10+i*3, 200, 200);
のかわりに
DrawCircle(PaintBox1.Canvas, 10+i*3, 200, 200);
とすると PaintBox1 に
DrawCircle(Image1.Canvas, 10+i*3, 200, 200);
にすると Image1 に描かれます。関数や手続きはなるべく応用範囲を広くするように
作ります。あと、同じコードを何度も繰り返すのを避けるためとか。
うーむ、ようするに「関数」が分からないんですね。
ちょっとBBSで説明するには手にあまりますのでヘルプを読んでください。
どんなプログラミング言語でも重要です。
手続きをつかわないと
procedure TForm1.Button1Click(Sender: TObject);
var
i, chuusinX, chuusinY, hankei:integer;
begin
chuusinX := 200;
chuusinY := 200;
Canvas.Pen.Color := clBlue;
Canvas.Brush.Style := bsClear;
for i := 0 to 40 do
begin
hankei := 10+i*3;
Canvas.Ellipse(chuusinX-hankei, chuusinY-hankei, chuusinX+hankei, chuusinY+hankei);
end;
end;
になります。
Button1Click() も Ellipse() も関数・手続きの一種です。クラスに属している
関数・手続きをメソッドといいます。
最初の例のように自分で関数・手続きやメソッドを作って呼び出すこともできます。
anoneさんへ:
いろいろ教えてくれて本当にありがとう^0^
考え方についてわかった気がするんですが、まだ完全に理解できていません。
学校のパソコン室もうそろそろ閉室の時間ですので、月曜日又頑張ります。
ありがとうございます。
またね〜
anoneさんへ:
久しぶり!anoneさん教えてくれた二番目のプログラムについてよく理解ができました、プログラミングにもちょっと向いてきたきがします。本当にありがとうございます。
意見を下さった皆さんへ
いろいろありがとうございました
ツイート | ![]() |