見出し画像

Pythonで三角形の面積を求めるプログラムを作ろう

最後にソースコードを書いておいたのでご自由にコピペして使ってください。


まずは構想から

せっかく面積を求めてくれるプログラムを作るのですから、どうせなら作るのが楽n便利なものにしたいですよね。それこそ学校の宿題(三平方の応用など)をやってくれるようなものにしたいと思うのが普通です。
普通に調べれば出てきたりしますが、ルートなどを入力すると小数が出てきてしまい、解答としてそのまま丸写ししてプリントに書く…なんてことはできません。
今回作るのは、結構な確率でn√mの形にしてくれるコードなので、ほぼ全部丸写しで宿題が楽になります!!

使用する公式

ここからは少し数学の話が関わってきます。
苦手な方は飛ばしてもらってかまいません。
(どうせ見てもあんまり役に立たないし)

ヘロンの公式

ここでは証明などの詳しい解説はせず紹介だけにしますが、三角形の3辺から面積を求められるとても便利な公式です。
三角形の3辺をそれぞれ$${a,b,c}$$
また
$${s=\frac{a+b+c}{2}}$$とすると、三角形の面積$${S}$$は、
$${S=\sqrt{s(s-a)(s-b)(s-c)}}$$

自作の面積を求める式

これも詳しい説明は省きますが、△ABCの底辺に垂線を引き、三平方の定理を利用して式を整理すると出てきます。
三角形の3辺をそれぞれ$${a,b,c}$$、三角形の面積$${S}$$は、
$${S=\frac{a}{2}×\sqrt{b^2-(\frac{a^2+b^2-c^2}{2a})^2}}$$

なぜ式を2つも使うのか?

さて、上の項目を見てこう思った人が多いと思います。
「ヘロンの公式だけではダメなのか?」
それは愚問というものでth
Pythonに限らず大抵のプログラミング言語に共通することですが、$${\sqrt{2}}$$などと入力すると1.41421356…と小数に直してから計算されてしまいます。これは基本的にどうしようもないのですが、計算後の掛け算$${3\sqrt{2}}$$を4.24264…と表示されては困ります。なのでそのまま表示したいのですが、ヘロンの公式だと√内が分数になる可能性が高いため結果が小数になる可能性も高くなってしまいます。これが検索して出てくるサイトの出力がよく小数になる理由の一つです。一方で、下側の式だとルート内は2乗同士の引き算なのでルート内が分数になる可能性が低いです。長くなってしまいましたが、これが式を2つ使う理由です

プログラムコード

プログラムのコードを貼っておきます。
ご自由にコピペ等で使ってください。
使用方法(操作方法)はプログラムをPython Shellで実行すると出るようになっています。

import math

# math.sqrt()をsqrt()だけで動くようにする
def sqrt(number):
    return math.sqrt(number)

# √m を n√m の形に整理する
def root(m):
    if sqrt(m) % 1 == 0:
        #√内が平方数の場合は√を外す
        return (k(sqrt(m)),"Password")
    else:
        #√内を素因数分解して整理する
        nlist = []
        n = 1
        for i in range(2,100):
            while m % i == 0 and m / 1 != 1:
                if (m/i) % i == 0:
                    n = n * i
                    m = m / (i**2)
                else:
                    nlist.append(i)
                    m = m / i
            i += 1
        for l in nlist:
            m = m * l
        return (n,k(m))

# root関数から出てきた値を"n√m"の形で出力する
def root_solve(number):
    u = root(number)
    if u[1] == "Password":
        u = u[0]
    else:
        u1 = str(u[0])
        if u1 == "1":
            u1 = ""
        u2 = str(u[1])
        u = u1 + "√" + u2
    print(u)
    
# 1.0 のようないらない.0を消す
def k(number):
    if isinstance(number,float) and number.is_integer():
        return int(number)
    return number
    
def solve(a,b,c):
    try:
        if a % 1 == 0 and b % 1 == 0 and c % 1 == 0:
            #ヘロンの公式の利用
            d = (a+b+c) / 2
            e = d * (d-a) * (d-b) * (d-c)
            s = root(e)
            if s[1] == "Password":
                s = s[0]
            else:
                s3 = str((s[0]) * (sqrt(s[1])))
                s1 = str(s[0])
                s2 = str(s[1])
                if s1 == "1":
                    s1 = ""
                #n√mの形の時は近似値を表示
                s = s1 + "√" + s2 + " ≈ " + s3
            print(s)
        else:
            #自作の公式
            s1 = a / 2
            s2 = b**2 - ((a**2+b**2-c**2)/(2*a))**2
            s1 = k(s1)
            s2 = k(s2)
            s3 = s1 * sqrt(s2)
            s3 = str(s3)
            if sqrt(s2) % 1 != 0:
                if s2 % 1 != 0:
                    s = s1 * sqrt(s2)
                else:
                    s1 = (root(s2))[0]
                    s2 = (root(s2))[1]
                    s1 = str(s1)
                    s2 = str(s2)
                    #n√mの形の時は近似値を表示
                    s = s1 + "√" + s2 + " ≈ " + s3
            else:
                s = k(s1 * sqrt(s2))
            print(s)
    except:
        #三角形が存在しないとき(√内が負になるとき)の処理
        print("""この三角形は存在しない可能性があります。
値を入力し直してください。""")

#プログラム起動時の説明
print("""
このプログラムでは以下の値を以下の関数を入力することで求めることができます。
・△ABCの3辺の長さが分かるときの△ABCの面積
 solve(a,b,c)   (a,b,cは3辺のそれぞれの長さ)
 例:solve(3,4,5) 出力:6
 ※√nはsqrt(n)と打ってください。
   また、入力する値に無理数が含まれている場合、面積が無理数で出力される場合があります。
・ルート内の整理(√48 = 4√6など)
 root_solve(number)   (numberは整理したいルートの中身の値)
 例:root_solve(12) 出力:2√3
""")

必然的に処理中に√内の整理も行う必要もあったためその機能も付けてみました。難点としては3辺の合計が奇数になってしまうとルート内に小数が含まれてしまうことです。しかし、数学の問題というものは答えが綺麗なキリのいい数字になるものが多いです。地味にめんどくさい三平方の定理の応用問題をやらなくて済むプログラムなので便利です。Pythonさえインストールされていればできるので、この機会にぜひやってみてください!

この記事が気に入ったらサポートをしてみませんか?