CGL_2_B: Intersection (続き)
解説にこんなコードが載ってるとも思えない
もう少し考える
たぶんここがミソ
static const int COUNTER_CLOCKWISE = 1
static const int CLOCKWISE = -1
static const int ONLINE_BACK = 2
static const int ONLINE_FRONT = -2
static const int ON_SEGMENT = 0
特にON_SEGMENT = 0
ってとこ
たぶん掛け算して0になる
ので、ON_SEGMENTの場合から考えると
どれかの端点がON_SEGMENTであればとにかく共有点があるわけで
def intersects(self, other: 'Segment') -> bool:
d0 = self.p1.location(other)
d1 = self.p2.location(other)
d2 = other.p1.location(self)
d3 = other.p2.location(self)
としたとき、d0・d1・d2・d3のいずれかが0なら交差する
つまりd0 * d1 * d2 * d3 == 0
であれば交差する
どの端点もON_SEGMENTでない場合
図にしてみるとこんな感じ
片方がCOUNTER_CLOCKWISEならもう片方はCLOCKWISEでないと交わらない
片方がCOUNTER_CLOCKWISEで片方がCLOCKWISEなら交わるとは言い切れないけど
もう一方の線分も片方がCOUNTER_CLOCKWISEで片方がCLOCKWISEなら交わる
というのはd0 * d1 == -1 and d2 * d3 == -1
ってことだな
つまりこう
やたらとシンプルになった
def intersects(self, other: 'Segment') -> bool:
d0 = self.p1.location(other)
d1 = self.p2.location(other)
d2 = other.p1.location(self)
d3 = other.p2.location(self)
return d0 * d1 * d2 * d3 == 0 or \
(d0 * d1 == -1 and d2 * d3 == -1)
AC
これならいいだろう
解説
OK
そうそう
EnumをIntのように計算できるようにするには、EnumではなくIntEnumを継承します
class PointLocation(IntEnum):