kb84tkhrのブログ

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

CGL_1_A: Projection

やっと戻る
型ヒントとかテストとかやったけど
型ヒントはほどほどにつけてテストは省略、くらいで進めよう

点から直線への射影を求める問題
これはプログラミングと言うより数学の問題だな
何十年ぶりだこういう計算するの

点を通って与えられた直線に垂直な直線を求めて連立方程式を解く、
っていう素朴なやり方でもできると思うけど
たぶんせっかく作ったライブラリでやるんだよね?
内積とか使ったりして

こうか

f:id:kb84tkhr:20190216172243p:plain

ところでここがすこし引っかかっている

出力は 0.00000001 以下の誤差を含んでもよいものとします。

これは出力形式も指定してることになるんだろうか
こんな出力例だけど

出力例 1
3.1200000000 4.1600000000

こっちは小数点以下10桁
誤差は小数点以下8桁目が1だからたぶん関係ないな
まあWAって言われてから考えよう

誤差が問題になりそうなのは・・・引き算あたりかな?
p1とp2がなんかもうめっちゃ近いときとか?
こっちもWAって(略

Segmentのメソッドということにした

class Segment:

    def __init__(self, p1: Point = None, p2: Point = None) -> None:
        self.p1: Point = Point() if p1 is None else p1
        self.p2: Point = Point() if p2 is None else p2

    def vector(self) -> Vector:
        return self.p2 - self.p1

    def projection(self, p: Point) -> Point:
        v = self.vector()
        vp = p - self.p1
        return v.dot(vp) / v.norm() * v + self.p1

使うときはLineとして使うけど

def main():
    x1, y1, x2, y2 = [int(x) for x in input().split()]
    p1 = Point(x1, y1)
    p2 = Point(x2, y2)
    l = Line(p1, p2)

    q = int(input())

    for _ in range(q):
        x, y = [int(x) for x in input().split()]
        p = Point(x, y)
        a = l.projection(p)
        print(a.x, a.y)

出力形式は何も指定してないのでこういう風に出力する

3.12 4.16

どうかな → AC

main()の中でひととおり終わっちゃってるので、
関数にだけだと型ヒントつけるところがあんまりない
こういう状態でもそれなりにはチェックしてくれているっぽい

a = l.projection(p.x)ってしてみると

CGL_1_A.py:15: error: Argument 1 to "projection" of "Segment" has incompatible type "float"; expected "Point"

なんて言ってくれる