【Python】高校の数学で習った「円の方程式」を使って、円を描いてみた

# はじめに
高校の数学で習った円の方程式は覚えてますでしょうか？

```math
(x-a)^2+(y-b)^2 = r^2
```
こちらが**「円の方程式」**です！
どんな場合でも**「中心の座標(a,b)」**と**「半径r」**の2つが分かれば、**円の方程式を使って円を描くこと**ができます。

この記事では**以下の3つの方法**で、**円の方程式**と**Python**を使って円を描いていきます。

```
1. 円の中心と円周上の1点を指定する方法
2. 正方形の対角を2点指定する方法
3. 円周上の3点を指定する方法
```


# 環境

- Windows 10 home
- Python 3.7.1


matplotlib,numpy,sympyのライブラリを使うので以下のコマンドでそれぞれインストールしておきましょう。

```
> pip install matplotlib

> pip install numpy

> pip install sympy
```



# 1. 円の中心と円周上の1点を指定する方法

## 1-1. 手順
① : 与えられた2点間の距離を求める。(半径)

- 2点間の距離の求め方は以下の公式になります。

```math
AB = \sqrt{(x2 - x1)^2 + (y2 - y1)^2}
```

② : 1点目を円の中心、①で求めた値を半径とする円を描画する。

## 1-2. ソースコード

```Circle1.py
import matplotlib.pyplot as plt
import numpy as np

# 円周上の1点
x1 = 500
y1 = 300

# 円の中心
a = 200
b = 300

# 1: 与えられた2点間の距離を求める。（半径）
r = np.sqrt((a-x1)**2 + (b-y1)**2)

# 2: 円の方程式
x = np.arange(a-r, a+r+1)

y = np.sqrt(r**2 - (x-a)**2) + b
yy = -y + 2*b

# グラフを描画
plt.plot(x, y)
plt.plot(x, yy)
plt.axis("equal")
plt.grid(color="0.8")
plt.show() # 画面に表示
```

## 1-3. 実行結果
<img width="320" alt="素材1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/b8ed2305-4551-69b2-ae4c-f262f82de772.png">

このようになれば、成功です。

# 2. 正方形の対角を2点指定する方法

## 2-1. 手順
① : 与えられた2点の中点を求める。(円の中心)

- 線分の中点を求める方程式は以下の通りです。

```math
x = \frac{x1 + x2}{2}
\hspace{20pt}
y = \frac{y1 + y2}{2}
```

② : ①で求めた点と、2点目を通ってy軸と平行な直線との距離を求める。(半径)
③ : ①で求めた点を円の中心、②で求めた値を半径とする円を描画する。

## 2-2. ソースコード

```Circle2.py
import matplotlib.pyplot as plt
import numpy as np

# 円周上の2点
x1 = 0
y1 = 400

x2 = 400
y2 = 0

# 1: 与えられた2点の中点を求める。（円の中心）
a = (x2+x1)/2
b = (y2+y1)/2

# 2: 1で求めた点と、2点目を通ってy軸と平行な直線との距離を求める。（半径）
r = x2-a

# 3: 円の方程式
x = np.arange(a-r, a+r+1)

y = np.sqrt(r**2 - (x-a)**2) + b
yy = -y + 2*b

# グラフを描画
plt.plot(x, y)
plt.plot(x, yy)
plt.axis("equal")
plt.grid(color="0.8")
plt.show() # 画面に表示
```

## 2-3. 実行結果
<img width="320" alt="素材2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/ea95e682-5022-a527-b93d-6c42794fe36d.png">


このようになれば、成功です。

# 3. 円周上の3点を指定する方法

## 3-1. 手順
① : 与えられた3点から、各辺の式を求める。
② : 各辺の垂直二等分線の式を求める。
③ : 垂直二等分線の交点を求める。(円の中心)
④ : ③で求めた点と、与えられた1つの点との距離を求める。(半径)
⑤ : ③で求めた点を円の中心、④で求めた値を半径とする円を描画する。

## 3-2. ソースコード

```Circle3.py
import matplotlib.pyplot as plt
import numpy as np
from sympy import Symbol, solve

# 円周上の3点
x1 = -100
y1 = 300

x2 = 500
y2 = 300

x3 = 200
y3 = 600

# 1: 与えられた3点から、各辺の式を求める。
aa = Symbol("aa")
bb = Symbol("bb")

ex1 = x1*aa+bb-y1
ex2 = x3*aa+bb-y3
result1 = solve([ex1,ex2],[aa,bb])#x1,y1とx3,y3の2点からなる直線の式

ex1 = x2*aa+bb-y2
result2 = solve([ex1,ex2],[aa,bb])#x2,y2とx3,y3の2点からなる直線の式

# 2: 各辺の垂直二等分線の式を求める。
ex1 = (-1/result1[aa])*((x3+x1)/2)+bb-((y3+y1)/2)
result3 = solve(ex1,bb)#result1の辺の垂直二等分線

ex2 = (-1/result2[aa])*((x3+x2)/2)+bb-((y3+y2)/2)
result4 = solve(ex2,bb)#result2の辺の垂直二等分線

# 3: 垂直二等分線の交点を求める。（円の中心）
ex1 = (-1/result1[aa])*aa+result3[0]-bb
ex2 = (-1/result2[aa])*aa+result4[0]-bb

result5 = solve([ex1,ex2],[aa,bb])

a = round(result5[aa])#円の中心のx座標
b = round(result5[bb])#円の中心のy座標

# 4: 3で求めた点と、与えられた1つの点との距離を求める。（半径）
r = np.sqrt(((a-x1)**2)+((b-y1)**2))#円の半径の計算

# 5: 円の方程式
x = np.arange(a-r, a+r+1)

y = np.sqrt(r**2 - (x-a)**2) + b
yy = -y + 2*b

# 6: グラフを描画
plt.plot(x, y)
plt.plot(x, yy)
plt.axis("equal")
plt.grid(color="0.8")
plt.show() # 画面に表示
```

## 3-3. 実行結果
<img width="320" alt="素材1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/359d9a26-c20a-e580-2d78-787f4583a63d.png">

このようになれば、成功です。

# 終わりに
ここまで読んでいただき、ありがとうございました。
高校数学の記事をあげたのですが、急にどうした!?って感じです。というのも、数学を勉強し直そうと思い、谷尻かおりさんの「Pythonで学び直す高校数学」という本を手に取った次第であります。
今回、取り上げた記事の内容はその本の第3章にある「方程式で図形を描く」という部分の最後のコラムのチャレンジ問題になります。その問題の解答がなかった?ので、自分なりに挑戦してみて、それを記事にしました。参考になったら嬉しいです。