kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

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でない場合
図にしてみるとこんな感じ

f:id:kb84tkhr:20190307215452j:plain

片方が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):