

以下の線分描画アルゴリズムは傾きaの絶対値が1以下でなければ正しく動作しないようですが、その理由と、任意の傾きに対応する方法を教えてください。

[code]

    void drawLine( int x0, int y0, /* 始点 */int x1, int y1, /* 終点 */
    　char r, char g, char b ) /* 線分色(RGB) */{
    　　　double x, y, a;
    　　　a = (double)(y1-y0)/(x1-x0);
    　　　/* x0 < x1 でない場合、
    　　　ここで始点と終点の座標を入れ替える */
    　　　/* writePixel(): 点描画関数 */
    　　　writePixel(x0, y0, r, g, b); // 始点描画
    　　　　x = x0;
    　　　　y = y0;
    　　　　while (x < x1) {
    　　　　　x = x + 1.0;
    　　　　　y = y + a;
    　　　　　writePixel(x, (int)(y + 0.5), r, g, b);
    　　　　}
    　}
    
[/code]

また、上記のプログラムを改良して、曲線を書く方法も教えてほしいです。  
よろしくお願いします。


CC BY-SA 4.0
2021-10-31T05:03:43.580
83353
2021-10-31T23:51:04.250
48882
question
c
線分描画アルゴリズムのプログラミング


A1. ループ内では常に `x+=1.0;` してますよね。傾き（の絶対値）が `1.0` を超える場合は `x` が１進むとき `y` は `a`
だけ進むつまり２ドットとか１０ドットとか進むわけです。そうすると打った点は飛び飛びになってしまい人間から見て直線を引いているように見えません。傾きが
`1.0` 未満の時 `x` が `1/a` つまりは２ドットや１０ドット進んでようやく `y` は `1`
増えるのでドット列が途切れない＝直線に見えるということです。

A2. `a>1` に対応するには `x` と `y` を入れ替えればいいわけです（宿題）

A3. 単に曲線といってもいっぱいありますので説明不可能。

原始的「マイコン」では浮動小数点数演算回路が入っていないので提示例のような `double`
を使うコードを書いても性能出ません。純粋に整数演算のみでこの手の描画を行うには `digital diffraction algorithm`
とか[ブレゼンハムのアルゴリズム](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AC%E3%82%BC%E3%83%B3%E3%83%8F%E3%83%A0%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)とかを使うとよいです。  
# 大昔に超やったなー、なっつかしー  
# まあいまどきの PC ならグラフィック処理支援ハードウエアが入っているので CPU でこんなことする必要は一切ない（お任せしたほうがよっぽど速い）

ブレゼンハムの解説が必要なら別質問にてどうぞ。


CC BY-SA 4.0
2021-10-31T23:51:04.250
83361
2021-10-31T23:51:04.250
8589
83353
answer