回答編集履歴
7
コードを訂正
answer
CHANGED
@@ -72,6 +72,9 @@
|
|
72
72
|
---
|
73
73
|
追記2:
|
74
74
|
あまりきれいとは言えないかもしれませんが、一応前述の問題をクリアできそうなコードを挙げておきます。
|
75
|
+
追記3:
|
76
|
+
何度もすみませんが、さらに間違いに気づいたので追記2のコードを訂正します。追記2のコードでは(0,0)->(1,5)などの線分を描画すると余計な画素までプロットされてしまってました orz
|
77
|
+
|
75
78
|
```C
|
76
79
|
int dx = (x1 - x0) * 2; // 必ず2で割り切れるようにする
|
77
80
|
int dy = (y1 - y0) * 2; // 同上
|
@@ -80,18 +83,18 @@
|
|
80
83
|
int delta_x_mid = dy / 2;
|
81
84
|
int delta_x = delta_x_mid;
|
82
85
|
for (;;) {
|
83
|
-
plotPixel(x, y);
|
86
|
+
plotPixel(x, y); // ... この画素を「主画素」ということにします
|
84
87
|
if (y == y1) break;
|
85
88
|
if (y != y0) {
|
86
89
|
// y0 < y < y1であるような点でのみ左右の画素を追加すべきか判定
|
87
90
|
if (delta_x < delta_x_mid) {
|
88
|
-
// yが0.5だけ小さい座標
|
91
|
+
// yが0.5だけ小さい位置のx座標を吟味し主画素の左に追加すべきか判定
|
89
|
-
if (delta_x - dx / 2
|
92
|
+
if (delta_x - dx / 2 < 0) { //追記2では!=0となっていました。
|
90
93
|
plotPixel(x - 1, y);
|
91
94
|
}
|
92
95
|
} else if (delta_x > delta_x_mid) {
|
93
|
-
// yが0.5だけ大きい座標
|
96
|
+
// yが0.5だけ大きい位置のx座標を吟味し主画素の右に追加すべきか判定
|
94
|
-
if (delta_x + dx / 2
|
97
|
+
if (delta_x + dx / 2 > dy) { //追記2では!=dyとなっていました
|
95
98
|
plotPixel(x + 1, y);
|
96
99
|
}
|
97
100
|
}
|
6
誤記訂正
answer
CHANGED
@@ -7,13 +7,12 @@
|
|
7
7
|
(A) 本来の線分が通過する画素は必ずプロットする
|
8
8
|
(B) 線分の太さをなるべく細くする
|
9
9
|
|
10
|
-
という背反する要件のうち通常は(B)の方が重視される気がするのです・・・自
|
10
|
+
という背反する要件のうち通常は(B)の方が重視される気がするのです・・・自信はないですが。
|
11
11
|
|
12
|
-
|
13
12
|
----
|
14
13
|
それはともかく・・・残念ながら自分は(A)の要件を満たすアルゴリズムとしてポピュラーなものがあるかどうか知りません。しかしながらこれはプレゼンハムのアルゴリズムの考え方をそのまま踏襲して若干手を入れればできそうな気もします。
|
15
14
|
|
16
|
-
|
15
|
+
ご質問の線分の例でいうとx方向の差分が2, y方向の差分が3なのでy座標を1ずつずらしながらx座標を1増やすかどうかその都度判断しますね?プレゼンハムのアルゴリズム(の改良版かな?)の要点はこのずらすかどうかの判定を微分法の素朴なシミュレーションによりデジタル的に行う点です。複雑さを避けるため条件つきの限定的なアルゴリズムを書くと・・・
|
17
16
|
|
18
17
|
```C
|
19
18
|
// 始点の座標はx0, y0, 終点はx1, y1とする
|
5
改善コードを追記
answer
CHANGED
@@ -68,4 +68,41 @@
|
|
68
68
|
※: 「それっぽい」なんてアバウトな言い方をしましたがそれは「厳密に検証してないのでひょっとしたら本来の線分が通過する画素をプロットしそこねる場合もあるかも知れない」と思ったからです。すみませんが少々面倒だったので検証を省いちゃいました。不備があったらすみません。一つのアイデアとしてみていただければと思います。
|
69
69
|
|
70
70
|
==>追記:傾きを変えて複数の線分の描画を観察してみたところ、案の定、要件を満たさないかも知れないケース(実行例の図の左から2番目の線分)があることに気づきました。
|
71
|
-
これが許容できるならよいのですが、まずいならもっと境界条件等を慎重に検討する必要がありそうです。修正方法がわかったら回答へ反映したいと思いますが・・・思いつかないかも知れません。その時はゴメンナサイ
|
71
|
+
これが許容できるならよいのですが、まずいならもっと境界条件等を慎重に検討する必要がありそうです。修正方法がわかったら回答へ反映したいと思いますが・・・思いつかないかも知れません。その時はゴメンナサイ
|
72
|
+
|
73
|
+
---
|
74
|
+
追記2:
|
75
|
+
あまりきれいとは言えないかもしれませんが、一応前述の問題をクリアできそうなコードを挙げておきます。
|
76
|
+
```C
|
77
|
+
int dx = (x1 - x0) * 2; // 必ず2で割り切れるようにする
|
78
|
+
int dy = (y1 - y0) * 2; // 同上
|
79
|
+
int x = x0;
|
80
|
+
int y = y0;
|
81
|
+
int delta_x_mid = dy / 2;
|
82
|
+
int delta_x = delta_x_mid;
|
83
|
+
for (;;) {
|
84
|
+
plotPixel(x, y);
|
85
|
+
if (y == y1) break;
|
86
|
+
if (y != y0) {
|
87
|
+
// y0 < y < y1であるような点でのみ左右の画素を追加すべきか判定
|
88
|
+
if (delta_x < delta_x_mid) {
|
89
|
+
// yが0.5だけ小さい座標で線分がちょうど画素間に位置しないことを確認
|
90
|
+
if (delta_x - dx / 2 != 0) {
|
91
|
+
plotPixel(x - 1, y);
|
92
|
+
}
|
93
|
+
} else if (delta_x > delta_x_mid) {
|
94
|
+
// yが0.5だけ大きい座標で線分がちょうど画素間に位置しないことを確認
|
95
|
+
if (delta_x + dx / 2 != dy) {
|
96
|
+
plotPixel(x + 1, y);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
y++;
|
101
|
+
delta_x += dx;
|
102
|
+
if (delta_x >= dy) {
|
103
|
+
delta_x -= dy;
|
104
|
+
x++;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
```
|
108
|
+

|
4
説明での論理の誤りを訂正
answer
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
int dy = y1 - y0; // 前提により必ず正の値
|
25
25
|
int x = x0;
|
26
26
|
int y = y0;
|
27
|
-
int delta_x_mid =
|
27
|
+
int delta_x_mid = dy / 2; // 最初のコードではdx/2としてましたがこちらが適切だと思います
|
28
28
|
int delta_x = delta_x_mid;
|
29
29
|
for (;;) {
|
30
30
|
plotPixel(x, y);
|
@@ -38,14 +38,14 @@
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
```
|
41
|
-
こんな感じですね。ここでdelta_xの意味を考えてみると、一つの画素の幅が(便宜上)dxだとしたときの本来の線分がそのy座標でのxの本来の座標を近似する値といえます。つまり
|
41
|
+
こんな感じですね。ここでdelta_xの意味を考えてみると、一つの画素の幅が(便宜上)~~dx(間違えました!)~~dyだとしたときの本来の線分がそのy座標でのxの本来の座標を近似する値といえます。つまり
|
42
42
|
```text
|
43
43
|
+-----+ +-----+ +-----+
|
44
44
|
| | | | | |
|
45
45
|
* | | * | | *
|
46
46
|
| | | | | |
|
47
47
|
+-----+ +-----+ +-----+
|
48
|
-
delta_x 0
|
48
|
+
delta_x 0 dy/2 dy-1
|
49
49
|
```
|
50
50
|
図の`*`が本来の線分が通過する点のあたりとみなせるということです。この意味にさえ気づけば上記のコードの「ここに挿入」とコメントした位置にこんな処理を追加すればそれっぽい線分(※)がプロットできると思います。
|
51
51
|
```C
|
3
追記
answer
CHANGED
@@ -65,4 +65,7 @@
|
|
65
65
|
|
66
66
|

|
67
67
|
---
|
68
|
-
※: 「それっぽい」なんてアバウトな言い方をしましたがそれは「厳密に検証してないのでひょっとしたら本来の線分が通過する画素をプロットしそこねる場合もあるかも知れない」と思ったからです。すみませんが少々面倒だったので検証を省いちゃいました。不備があったらすみません。一つのアイデアとしてみていただければと思います。
|
68
|
+
※: 「それっぽい」なんてアバウトな言い方をしましたがそれは「厳密に検証してないのでひょっとしたら本来の線分が通過する画素をプロットしそこねる場合もあるかも知れない」と思ったからです。すみませんが少々面倒だったので検証を省いちゃいました。不備があったらすみません。一つのアイデアとしてみていただければと思います。
|
69
|
+
|
70
|
+
==>追記:傾きを変えて複数の線分の描画を観察してみたところ、案の定、要件を満たさないかも知れないケース(実行例の図の左から2番目の線分)があることに気づきました。
|
71
|
+
これが許容できるならよいのですが、まずいならもっと境界条件等を慎重に検討する必要がありそうです。修正方法がわかったら回答へ反映したいと思いますが・・・思いつかないかも知れません。その時はゴメンナサイ
|
2
実行例が簡単すぎるので複数の線分をプロットした例にする
answer
CHANGED
@@ -63,7 +63,6 @@
|
|
63
63
|
```
|
64
64
|
試しにやってみたところこんな感じになりました。
|
65
65
|
|
66
|
-

|
67
|
-
|
68
67
|
---
|
69
68
|
※: 「それっぽい」なんてアバウトな言い方をしましたがそれは「厳密に検証してないのでひょっとしたら本来の線分が通過する画素をプロットしそこねる場合もあるかも知れない」と思ったからです。すみませんが少々面倒だったので検証を省いちゃいました。不備があったらすみません。一つのアイデアとしてみていただければと思います。
|
1
不正確な記述を変更
answer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
> 基礎的なレンダリングなので、オーソドックスなアルゴリズムがある
|
4
4
|
|
5
|
-
とのことですが「基礎的なレンダリング」であるとは必ずしも言えない気がします。お望みの線分は方向によって見た目の線の太さが変わってしまいます。特徴として
|
5
|
+
とのことですが「基礎的なレンダリング」であるとは必ずしも言えない気がします。お望みの線分は~~方向によって見た目の線の太さが変わってしまいます~~多くの場合より太い線分が描画されてしまいます。特徴として
|
6
6
|
|
7
7
|
(A) 本来の線分が通過する画素は必ずプロットする
|
8
8
|
(B) 線分の太さをなるべく細くする
|