中点の描画を用いた線分描画

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pocket
記事: 49
登録日時: 9年前

中点の描画を用いた線分描画

#1

投稿記事 by pocket » 8年前

お世話になっております.

今回は中点の描画を再帰的に行って線分を描画するプログラムを作成しています.
使用言語はC言語です.
たとえば,(5,10)の点から(20,55)の点までの線分の描画を行うプログラムを考えます.
まず二点間の中点を求めて,その中点に色をつけます.(以降は(5,10)→(20,55)と表記します)
今回の場合,中点は(12,32)になりますので,この位置を赤色で塗ります.
そして,(5,10)→(12,32),(12,32)→(20,55)に対して中点描画を行います.
この流れで,再帰的に中点を描画することで線分の描画を実現しようと考えています.

以下に作成したコードの一部を記載します.
draw_lineという関数に二点のx,y座標を入力すると,線を描画します.

コード:

typedef unsigned short hword;

int main(){
	
	draw_line(120,10,50,130,RED);
	draw_line(120,10,210,150,RED);
	draw_line(50,130,210,150,RED);

}

void draw_line(hword xa, hword ya, hword xb, hword yb, hword color){
	hword xc, yc;
		
	xc = (xa + xb) / 2;	//中点計算(x)
	yc = (ya + yb) / 2;//中点計算(y)
	
	draw_point (xc, yc, color);//(xc,yc)座標にcolorの点を描画
	
	if((distance(xa,xb)>1) && (distance(ya,yb)>1)){//引数となる座標のxとyの距離が1になるまで再帰を続ける
        draw_line (xa, ya, xc, yc, color);
		draw_line (xc, yc, xb, yb, color);
    }
	
}

hword distance(hword a, hword b){
	hword temp;
	if(a>b){
		 return a-b;
	}else{
		return b-a; 
	}
}
実行結果の図を載せます.
線を三本引くことで三角形を描画しています.
ですが,底辺の線がおかしいです.
具体的には点の数が足りません.
おそらく再帰の条件である,

コード:

if((distance(xa,xb)>1) && (distance(ya,yb)>1)){
の部分に問題があると思われますが,なぜ問題なのかがわかりません.
このコードを書いた理由としては,中点を求めていくと,最終的には2点が隣り合うと考えたためです.
たとえば,(2,3)→(3,4)となった場合に,終了すればいいと考えました.
この考え方に問題があるのか,もし別の解決策等ありましたら,ご教授いただければと思います.
また,底辺以外の線が正常に描画されている理由についてもご教授いただければ幸いです.

よろしくお願いいたします.
画像
最後に編集したユーザー pocket on 2016年11月03日(木) 14:04 [ 編集 1 回目 ]


hide

Re: 中点の描画を用いた線分描画

#3

投稿記事 by hide » 8年前

コード:

if((distance(xa,xb)>1) && (distance(ya,yb)>1)){
//引数となる座標のxとyの距離が1になるまで再帰を続ける
これ怪しいですね、コメントとやってることが違います。
これだと、どちらも距離が1より大きい場合に再帰を続けています。
おそらく高さの差分 1になったときに抜けてしまっています。
描きたい線の角度が 垂直か水平に近いときに点を打つ数が減っているかと思います。

pocket
記事: 49
登録日時: 9年前

Re: 中点の描画を用いた線分描画

#4

投稿記事 by pocket » 8年前

あんどーなつさん

返信いただきありがとうございます.
ご指摘いただきましたとおり修正したところ,正常に描画できました.

ちなみに,なぜor演算子ではうまくいくのでしょうか?
また,and演算子を用いた場合でも,底辺以外が正常に描画されていたのはなぜなのでしょうか?

もう少し詳しく解説していただければ幸いです.
お時間があれば,ぜひお願いします.

hide

Re: 中点の描画を用いた線分描画

#5

投稿記事 by hide » 8年前

実際に数字でやってみましょうか

[hr]
斜めに線をひくとき
点 (0, 0) から (8, 8) まで線を引くとすると、前のプログラムでは
(0, 0) から (8, 8) でひこうとして (4, 4) に点を打つ
(0, 0) から (4, 4) でひこうとして (2, 2) に点を打つ
(0, 0) から (2, 2) でひこうとして (1, 1) に点を打つ
(0, 0) と (1, 1) は縦横の距離がそれぞれ1より大きくないので、次の点に移る。
以下省略
問題ありませんね。
[hr]
横に線をひくとき
点(0, 0) から (16, 0) まで線をひくとすると、
(0, 0) から (16, 0) でひこうとして (8, 0)に点を打つ
(0, 0) と (8, 0) は縦の距離が 0 なので、終了
[hr]
これではまずいですよね?

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

Re: 中点の描画を用いた線分描画

#6

投稿記事 by あんどーなつ » 8年前

なぜ・・・難しいですね。

底辺が描画できない説明なら簡単なのですが、
それ以外の2辺で描画できているように見えるのは、直線の傾きを少しづつ変えて見ると
分かりやすいと思います。すみません、私のほうでそこまでやる気力はないです。

pocket
記事: 49
登録日時: 9年前

Re: 中点の描画を用いた線分描画

#7

投稿記事 by pocket » 8年前

hideさん

非常にわかりやすい解説をありがとうございます.
確かに,and演算子では水平に線を引く場合,途中で再帰が終了しますね.
or演算子の場合は,x,yともに距離が1になるまで再帰が回るということだと思います.
x,yともに1以上という条件からand演算子を使ってしまいました.
内容をもう少し考えて演算子を選択すべきでした.


あんどーなつさん

お忙しいところをコメントいただき本当にありがとうございます.


お忙しいところを私の疑問に対してお時間を割いていただきました皆様に感謝いたします.
本当にありがとうございました.
これにて,解決とさせていただきます.

閉鎖

“C言語何でも質問掲示板” へ戻る