CGL_7_D: Cross Points of a Circle and a Line
ふむ
円と直線の交点
学校でなら連立方程式を解きにかかるところだけど
ここではベクトルを使って解いていくようだからそっちで考える
ヒントは射影っぽい絵
まあやればできるよね
って印象
中心Oから直線への射影をA、一方の交点をBとするとOB = rで
あとABの距離を出して
ABは外積使って関数作ったけど、それを使うか
射影をすでに求めてたら三平方の定理で求めるか
どっちが楽かな
せっかく関数があるからまずはそっちでやるか
でAB方向の単位ベクトルaを作ってA+AB*a
できるけどなんかちょっとめんどくさく見えるなあ
連立方程式解くのと比べてどうだろう
解いた式を計算するだけならそっちのほうが楽そうに思える
ベクトルでやるにしてももっといい考え方がある?
まあいいやそのまま書く
こうな
class Circle:
def cross_point(self, line: Line) -> List[Point]:
proj = line.projection(self.c)
dist = self.c.distance_to_line(line)
tan = sqrt(self.r * self.r - dist * dist)
u = line.vector() / line.vector().abs()
return sorted([proj - tan * u, proj + tan * u])
x座標で並べ替えるのがこの関数の仕事かというと微妙な気もする
main
def main() -> None:
cx, cy, r = [int(x) for x in input().split()]
c = Circle(Point(cx, cy), r)
q = int(input())
for _ in range(q):
x0, y0, x1, y1 = [int(x) for x in input().split()]
line = Line(Point(x0, y0), Point(x1, y1))
left, right = c.cross_point(line)
print(left.x, left.y, right.x, right.y)
テスト2でWA
mjsk
何
回答がこれ
-0.43468860 -0.90058083 0.95192997 -0.30631573
-0.77700043 0.62950007 0.93916259 0.34347290
-0.84991694 -0.52691669 0.92050517 -0.39073037
-0.94804172 0.31814603 -0.63686394 -0.77097621
-0.24253563 0.97014250 0.24253563 -0.97014250
-0.31622777 -0.94868330 0.31622777 0.94868330
-0.32432432 -0.94594595 0.00000000 -1.00000000
0.26322452 -0.96473460 0.83266589 0.55377570
自分の実行結果がこれ
-0.43468859527183135 -0.9005808265450704 0.9519299745821757 -0.30631572517906747
-0.7770004252101379 0.6295000708683562 0.9391625873722993 0.3434729021046168
-0.849916939625135 -0.526916687663472 0.9205051749192524 -0.39073037116005754
-0.9480417217214212 0.318146026024974 -0.6368639386559374 -0.7709762147042192
-0.24253562503633297 0.9701425001453319 0.24253562503633297 -0.9701425001453319
-0.31622776601683794 -0.9486832980505138 0.31622776601683794 0.9486832980505138
-0.3243243243243234 -0.945945945945946 6.106226635438361e-16 -1.0
0.2632245247831982 -0.964734600578138 0.8326658861757059 0.5537756964685491
じー
106226635438361e-16
お前か
えーとこういう場合はstr.format()でフォーマットを指定するんだな
回答例と合わせるには{:.8f}
か
こうね
print("{:.8f} {:.8f} {:.8f} {:.8f}".format(
left.x, left.y, right.x, right.y))
AC
考え方も解説と同じ