円と交わる直線の座標を求める関数を作ってみました。
直線の方程式オブジェクトには、
y軸に平行な場合yに値が格納され、
x軸に平行な場合xに値が格納され、
それ以外の場合はy=mx+nの形式でmとnの値が格納されます。
※ax+by+c=0と使い分けるためにy=mx+nを使用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import math # 円と交わる直線の座標を返却 def cli(line, x, y, r): points = [] if "y" in line: # y軸に平行な直線の場合 a = 0 b = 1 c = -(line["y"]) elif "x" in line: # x軸に平行な直線の場合 a = 1 b = 0 c = -(line["x"]) else: # y = mx + n a = line["m"] c = line["n"] b = -(c / line["n"]) l = a ** 2 + b ** 2 k = a * x + b * y + c d = l * r ** 2 - k ** 2 if d > 0: # 2点交わる ds = math.sqrt(d) apl = a / l bpl = b / l xc = x - apl * k yc = y - bpl * k xd = bpl * ds yd = apl * ds point = {} point["x"] = xc - xd point["y"] = yc + yd points.append(point) point = {} point["x"] = xc + xd point["y"] = yc - yd points.append(point) elif d == 0: # 1点交わる point = {} point["x"] = x - a * k / l point["y"] = y - b * k / l points.append(point) return points |
実際に動かしてみます。
x=2と(2, 2)半径4の円が交わる座標
1 2 3 4 5 6 7 |
# -*- coding: utf-8 import json # x=2と(2, 2)半径4の円が交わる座標 print("x=2と(2, 2)半径4の円が交わる座標") line = {"x": 2} print(json.dumps(cli(line, 2, 2, 4), indent=4)) |
1 2 3 4 5 6 7 8 9 10 11 |
x=2と(2, 2)半径4の円が交わる座標 [ { "x": 2.0, "y": 6.0 }, { "x": 2.0, "y": -2.0 } ] |
y=4と(2, 2)半径2の円が交わる座標
1 2 3 4 5 6 7 |
# -*- coding: utf-8 import json # y=4と(2, 2)半径2の円が交わる座標 print("y=4と(2, 2)半径2の円が交わる座標") line = {"y": 4} print(json.dumps(cli(line, 2, 2, 2), indent=4)) |
1 2 3 4 5 6 7 |
y=4と(2, 2)半径2の円が交わる座標 [ { "x": 2.0, "y": 4.0 } ] |
y=3x-2と(2, 3)半径1の円が交わる座標
1 2 3 4 5 6 7 |
# -*- coding: utf-8 import json # y=3x-2と(2, 3)半径1の円が交わる座標 print("y=3x-2と(2, 3)半径1の円が交わる座標") line = {"m": 3, "n": -2} print(json.dumps(cli(line, 2, 3, 1), indent=4)) |
1 2 3 4 5 6 7 8 9 10 11 |
y=3x-2と(2, 3)半径1の円が交わる座標 [ { "x": 2.0, "y": 4.0 }, { "x": 1.4, "y": 2.2 } ] |
y=3x-2と(5, 3)半径1の円が交わる座標(交わらない場合)
1 2 3 4 5 6 7 |
# -*- coding: utf-8 import json # y=3x-2と(5, 3)半径1の円が交わる座標 print("y=3x-2と(5, 3)半径1の円が交わる座標") line = {"m": 3, "n": -2} print(json.dumps(cli(line, 5, 3, 1), indent=4)) |
1 2 |
y=3x-2と(5, 3)半径1の円が交わる座標 [] |