PR

Pythonで円と交わる直線の座標を求める関数

Python Python
Python

円と交わる直線の座標を求める関数を作ってみました。
直線の方程式オブジェクトには、
y軸に平行な場合yに値が格納され、
x軸に平行な場合xに値が格納され、
それ以外の場合はy=mx+nの形式でmとnの値が格納されます。

※ax+by+c=0と使い分けるためにy=mx+nを使用しています。

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の円が交わる座標

# -*- 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))
x=2と(2, 2)半径4の円が交わる座標
[
    {
        "x": 2.0,
        "y": 6.0
    },
    {
        "x": 2.0,
        "y": -2.0
    }
]

y=4と(2, 2)半径2の円が交わる座標

# -*- 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))
y=4と(2, 2)半径2の円が交わる座標
[
    {
        "x": 2.0,
        "y": 4.0
    }
]

y=3x-2と(2, 3)半径1の円が交わる座標

# -*- 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))
y=3x-2と(2, 3)半径1の円が交わる座標
[
    {
        "x": 2.0,
        "y": 4.0
    },
    {
        "x": 1.4,
        "y": 2.2
    }
]

y=3x-2と(5, 3)半径1の円が交わる座標(交わらない場合)

# -*- 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))
y=3x-2と(5, 3)半径1の円が交わる座標
[]
タイトルとURLをコピーしました