CGL_3_C: Polygon-Point Containment (続き5)
ちょっと寝かせてみたけど画期的なアイデアは浮かばず
あとは整理するくらい
location
を使うのであればy座標を使わなくても上下どちらにいるかわかるな
とか
whileループを二重にしなくてもcontinue使えばいいな
とか
class PointLocation(IntEnum):
def is_online(self):
return self in [PointLocation.ON_SEGMENT,
PointLocation.ONLINE_BACK,
PointLocation.ONLINE_FRONT]
class Polygon:
def contains(self, p: Point) -> Containment:
ps = Segment(p, Point(100000.0, p.y))
count = 0
prev_l = self.vertices[0].location(ps)
if prev_l.is_online():
prev_l = self.vertices[-1].location(ps)
for s in self.sides():
if p.location(s) == PointLocation.ON_SEGMENT:
return Containment.ONLINE
cur_l = s.p2.location(ps)
if cur_l.is_online() or prev_l == cur_l:
continue
if ps.intersects(s):
count += 1
prev_l = cur_l
return Containment.OUTSIDE if count % 2 == 0 \
else Containment.INSIDE
最初の辺がx軸に平行だったときと
頂点がちょうど半直線の上にあるときの特別扱いはどうもなくせなかった
という範囲内ではまあまあ見やすくはなった気はしている
自分的にはこれでファイナルアンサーということにしよう