CGL_3_C: Polygon-Point Containment (続き3)
終点が半直線上にあって、その次の線分がx軸に平行な場合か
Point(2, 3)
はそういう例になっていたはずだけど、
半直線の上から来て上に出ていくからたまたま問題が発生しなかった
まっとうに考えてここはテストケースを追加するところなんだろうな
ひとつの図形で全部テストしようとしたのもよくなかったかもしれない
そうじゃなくてもだんだん複雑になってきてテスト挙げきれてないけど
というよりもそれ以前か
場合分けがちゃんとできてない
だんだんややこしくなっているのはたぶんそもそもの方針が
よくなかったのではないか
でもいったんいけるところまでこのままいってみよう
その後で考え直す
まずは失敗するテストケースを追加する
p = Polygon([Point(1, 1),
Point(7, 1),
Point(5, 3),
Point(3, 3),
Point(1, 5)])
self.assertEqual(p.contains(Point(2, 3)), CN.INSIDE)
ちゃんとエラーになることを確認
ここを書き換えて、y座標が変わる頂点まで進むようにする
普通に多角形ならひとつ先まで進めばいいはずだけど
p3 = self.vertices[self.next(self.next(k))]
p3がp2と同じy座標なら次に行く
def contains(self, p: Point) -> Containment:
ps = Segment(p, Point(100000.0, p.y))
count = 0
for k in range(self.n):
p1 = self.vertices[k]
k = self.next(k)
p2 = self.vertices[k]
s = Segment(p1, p2)
if p.location(s) == PointLocation.ON_SEGMENT:
return Containment.ONLINE
if p.x < p1.x and float_equal(p.y, p1.y):
continue
if p.x < p2.x and float_equal(p.y, p2.y):
k = self.next(k)
while True:
p3 = self.vertices[k]
if not float_equal(p2.y, p3.y):
break
k = self.next(k)
if p1.y < p2.y < p3.y or p1.y > p2.y > p3.y:
count += 1
elif ps.intersects(s):
count += 1
return Containment.OUTSIDE if count % 2 == 0 \
else Containment.INSIDE
ジャッジ
よし通った