回答編集履歴

7

コードを訂正

2018/10/01 05:04

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -146,6 +146,12 @@
146
146
 
147
147
  あまりきれいとは言えないかもしれませんが、一応前述の問題をクリアできそうなコードを挙げておきます。
148
148
 
149
+ 追記3:
150
+
151
+ 何度もすみませんが、さらに間違いに気づいたので追記2のコードを訂正します。追記2のコードでは(0,0)->(1,5)などの線分を描画すると余計な画素までプロットされてしまってました orz
152
+
153
+
154
+
149
155
  ```C
150
156
 
151
157
  int dx = (x1 - x0) * 2; // 必ず2で割り切れるようにする
@@ -162,7 +168,7 @@
162
168
 
163
169
  for (;;) {
164
170
 
165
- plotPixel(x, y);
171
+ plotPixel(x, y); // ... この画素を「主画素」ということにします
166
172
 
167
173
  if (y == y1) break;
168
174
 
@@ -172,9 +178,9 @@
172
178
 
173
179
  if (delta_x < delta_x_mid) {
174
180
 
175
- // yが0.5だけ小さい座標で線分がちょうど画素位置しないことを確認
181
+ // yが0.5だけ小さい位置のx座標を吟味し主画素の左追加すべきか判定
176
-
182
+
177
- if (delta_x - dx / 2 != 0) {
183
+ if (delta_x - dx / 2 < 0) { //追記2では!=0となっていました。
178
184
 
179
185
  plotPixel(x - 1, y);
180
186
 
@@ -182,9 +188,9 @@
182
188
 
183
189
  } else if (delta_x > delta_x_mid) {
184
190
 
185
- // yが0.5だけ大きい座標で線分がちょうど画素位置しないことを確認
191
+ // yが0.5だけ大きい位置のx座標を吟味し主画素の右追加すべきか判定
186
-
192
+
187
- if (delta_x + dx / 2 != dy) {
193
+ if (delta_x + dx / 2 > dy) { //追記2では!=dyとなっていました
188
194
 
189
195
  plotPixel(x + 1, y);
190
196
 

6

誤記訂正

2018/10/01 05:04

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -16,9 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- という背反する要件のうち通常は(B)の方が重視される気がするのです・・・自はないですが。
19
+ という背反する要件のうち通常は(B)の方が重視される気がするのです・・・自はないですが。
20
-
21
-
22
20
 
23
21
 
24
22
 
@@ -28,7 +26,7 @@
28
26
 
29
27
 
30
28
 
31
- 仮にご質問の線分の例でいうとx方向の差分が2, y方向の差分が3なのでy座標を1ずつずらしながらx座標を1増やすかどうかその都度判断しますね?プレゼンハムのアルゴリズム(の改良版かな?)の要点はこのずらすかどうかの判定を微分法の素朴なシミュレーションによりデジタル的に行う点です。複雑さを避けるため条件つきの限定的なアルゴリズムを書くと・・・
29
+ ご質問の線分の例でいうとx方向の差分が2, y方向の差分が3なのでy座標を1ずつずらしながらx座標を1増やすかどうかその都度判断しますね?プレゼンハムのアルゴリズム(の改良版かな?)の要点はこのずらすかどうかの判定を微分法の素朴なシミュレーションによりデジタル的に行う点です。複雑さを避けるため条件つきの限定的なアルゴリズムを書くと・・・
32
30
 
33
31
 
34
32
 

5

改善コードを追記

2018/10/01 03:33

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -139,3 +139,77 @@
139
139
  ==>追記:傾きを変えて複数の線分の描画を観察してみたところ、案の定、要件を満たさないかも知れないケース(実行例の図の左から2番目の線分)があることに気づきました。
140
140
 
141
141
  これが許容できるならよいのですが、まずいならもっと境界条件等を慎重に検討する必要がありそうです。修正方法がわかったら回答へ反映したいと思いますが・・・思いつかないかも知れません。その時はゴメンナサイ
142
+
143
+
144
+
145
+ ---
146
+
147
+ 追記2:
148
+
149
+ あまりきれいとは言えないかもしれませんが、一応前述の問題をクリアできそうなコードを挙げておきます。
150
+
151
+ ```C
152
+
153
+ int dx = (x1 - x0) * 2; // 必ず2で割り切れるようにする
154
+
155
+ int dy = (y1 - y0) * 2; // 同上
156
+
157
+ int x = x0;
158
+
159
+ int y = y0;
160
+
161
+ int delta_x_mid = dy / 2;
162
+
163
+ int delta_x = delta_x_mid;
164
+
165
+ for (;;) {
166
+
167
+ plotPixel(x, y);
168
+
169
+ if (y == y1) break;
170
+
171
+ if (y != y0) {
172
+
173
+ // y0 < y < y1であるような点でのみ左右の画素を追加すべきか判定
174
+
175
+ if (delta_x < delta_x_mid) {
176
+
177
+ // yが0.5だけ小さい座標で線分がちょうど画素間に位置しないことを確認
178
+
179
+ if (delta_x - dx / 2 != 0) {
180
+
181
+ plotPixel(x - 1, y);
182
+
183
+ }
184
+
185
+ } else if (delta_x > delta_x_mid) {
186
+
187
+ // yが0.5だけ大きい座標で線分がちょうど画素間に位置しないことを確認
188
+
189
+ if (delta_x + dx / 2 != dy) {
190
+
191
+ plotPixel(x + 1, y);
192
+
193
+ }
194
+
195
+ }
196
+
197
+ }
198
+
199
+ y++;
200
+
201
+ delta_x += dx;
202
+
203
+ if (delta_x >= dy) {
204
+
205
+ delta_x -= dy;
206
+
207
+ x++;
208
+
209
+ }
210
+
211
+ }
212
+
213
+ ```
214
+
215
+ ![イメージ説明](abe69cfa37b26e05aab9d71b712c22f3.png)

4

説明での論理の誤りを訂正

2018/09/30 18:24

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -50,7 +50,7 @@
50
50
 
51
51
  int y = y0;
52
52
 
53
- int delta_x_mid = dx / 2;
53
+ int delta_x_mid = dy / 2; // 最初のコードではdx/2としてましたがこちらが適切だと思います
54
54
 
55
55
  int delta_x = delta_x_mid;
56
56
 
@@ -78,7 +78,7 @@
78
78
 
79
79
  ```
80
80
 
81
- こんな感じですね。ここでdelta_xの意味を考えてみると、一つの画素の幅が(便宜上)dxだとしたときの本来の線分がそのy座標でのxの本来の座標を近似する値といえます。つまり
81
+ こんな感じですね。ここでdelta_xの意味を考えてみると、一つの画素の幅が(便宜上)~~dx(間違えました!)~~dyだとしたときの本来の線分がそのy座標でのxの本来の座標を近似する値といえます。つまり
82
82
 
83
83
  ```text
84
84
 
@@ -92,7 +92,7 @@
92
92
 
93
93
  +-----+ +-----+ +-----+
94
94
 
95
- delta_x 0 dx/2 dx-1
95
+ delta_x 0 dy/2 dy-1
96
96
 
97
97
  ```
98
98
 

3

追記

2018/09/30 17:33

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

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

2

実行例が簡単すぎるので複数の線分をプロットした例にする

2018/09/30 17:21

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -128,9 +128,7 @@
128
128
 
129
129
 
130
130
 
131
- ![イメージ説明](b688f48ec2222a5f463ba57616309f83.png)
131
+ ![イメージ説明](e2731b4bc223c585e8ae09b606971e06.png)
132
-
133
-
134
132
 
135
133
  ---
136
134
 

1

不正確な記述を変更

2018/09/30 16:55

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
 
9
- とのことですが「基礎的なレンダリング」であるとは必ずしも言えない気がします。お望みの線分は方向によって見た目の線の太さが変わってしまいます。特徴として
9
+ とのことですが「基礎的なレンダリング」であるとは必ずしも言えない気がします。お望みの線分は~~方向によって見た目の線の太さが変わってしまいます~~多くの場合より太い線分が描画されてしまいます。特徴として
10
10
 
11
11
 
12
12