'''
解三角形
@作者 码老师
@微信公众号 学思营 ID:xuesying
@公司 深圳五行星软件有限公司
@日期 2021-6-1(更新)
@使用方法
from solvingtriangle import Triangle #导入解三角形对象
1、已知三边
Triangle(12,13,7)
2、已知一边二角
Triangle(12,A=35,B=67)、Triangle(a=12,A=35,B=67)、Triangle(a=12,B=35,C=67)
Triangle(b=12,A=35,B=67)、Triangle(b=12,A=35,B=67)、Triangle(b=12,B=35,C=67)
Triangle(c=12,A=35,B=67)、Triangle(c=12,A=35,B=67)、Triangle(c=12,B=35,C=67)
3、边角边
Triangle(12,15,C=67)、Triangle(a=12,b=15,C=67)
Triangle(a=12,c=15,B=67)
Triangle(b=12,c=15,A=67)
4、其它二边一角——不是直角三角形无解
Triangle(12,12sinB,B=67)、Triangle(12sinA,12,A=67)
Triangle(12,b=12sinB,B=67)、Triangle(12sinA,b=12,A=67)
Triangle(a=12,b=12sinB,B=67)、Triangle(a=12sinA,b=12,A=67)
Triangle(b=12,c=12sinC,C=67)、Triangle(b=12sinB,c=12,B=67)
Triangle(a=12,c=12sinC,C=67)、Triangle(a=12sinA,c=12,A=67)
Triangle(12,c=12sinC,C=67)、Triangle(12sinA,c=12,A=67)
5、已解三角形内切圆
_radius(半径), _distance(里A角距离), _angle(与AB的夹角) = Triangle.createIncircle()
6、已解三角形外接圆
_radius, _distance, _angle = Triangle.createCircumcircle()
打印结果:
print(Triangle(12,13,7))
'''
from math import *
zeroNum=0.0001 #判断0值
def adjust(val):
if abs(val)<zeroNum:
return 0
elif abs(abs(val)-1)<zeroNum:
if val>0:
return 1
else:
return -1
else:
return val
class Triangle():
#是否已经初始化
__initOk=False
def isInit(self):
return self.__initOk
#边
__a=None
def geta(self):
return self.__a
__b=None
def getb(self):
return self.__b
__c=None
def getc(self):
return self.__c
#角
__A=None
def getA(self):
return self.__A
__B=None
def getB(self):
return self.__B
__C=None
def getC(self):
return self.__C
#解决钝角三角形问题
def __solvObtuseAngle(self):
if abs(self.__A+self.__B+self.__C-pi)>=zeroNum:
if self.__a>max(self.__b,self.__c):
self.__A=pi-self.__A
elif self.__b>max(self.__a,self.__c):
self.__B=pi-self.__B
else:
self.__C=pi-self.__C
#三边初始化——解三角形
def __initE3(self, a, b, c, A, B, C):
if a<=0 or b<=0 or c<=0:
return False
if a+b<=c or a+c<=b or b+c<=a:
return True
#用秦九韶公式计算三角形的2倍面积
_2S=(a**2*b**2-((a**2+b**2-c**2)/2)**2)**.5
#_2S=a*c*sin(B)
self.__A=asin(adjust(_2S/(b*c)))
self.__B=asin(adjust(_2S/(a*c)))
self.__C=asin(adjust(_2S/(a*b)))
self.__a=a
self.__b=b
self.__c=c
#解决钝角三角形问题
self.__solvObtuseAngle()
self.__initOk=True
return True
#3角1边初始化——解三角形
def __initE1A3(self, a, b, c):
#absin∠C=acsin∠B=bcsin∠A
if a>0:
self.__a=a
self.__b=a*sin(self.__B)/sin(self.__A)
self.__c=a*sin(self.__C)/sin(self.__A)
elif b>0:
self.__b=b
self.__a=b*sin(self.__A)/sin(self.__B)
self.__c=b*sin(self.__C)/sin(self.__B)
elif c>0:
self.__c=c
self.__a=c*sin(self.__A)/sin(self.__C)
self.__b=c*sin(self.__B)/sin(self.__C)
#2角1边初始化——解三角形
def __initE1A2(self, a, b, c, A, B, C):
if a<=0:
if (b<=0) ^ (c<=0):
pass
else:
return False
else:
if b<=0 and c<=0:
pass
else:
return False
if A<=0:
if B<=0 or C<=0 or B+C>=180:
print("三角∠A=%s、∠B=%s、∠C=%s不能构成三角形!" % (str(A), str(B), str(C)))
return True
self.__B=B*pi/180
self.__C=C*pi/180
self.__A=pi-self.__B-self.__C
#初始化边
self.__initE1A3( a, b, c)
elif B<=0:
if A<=0 or C<=0 or A+C>=180:
print("三角∠A=%s、∠B=%s、∠C=%s不能构成三角形!" % (str(A), str(B), str(C)))
return True
self.__A=A*pi/180
self.__C=C*pi/180
self.__B=pi-self.__A-self.__C
#初始化边
self.__initE1A3( a, b, c)
elif C<=0:
if A<=0 or B<=0 or A+B>=180:
print("三角∠A=%s、∠B=%s、∠C=%s不能构成三角形!" % (str(A), str(B), str(C)))
return True
self.__A=A*pi/180
self.__B=B*pi/180
self.__C=pi-self.__A-self.__B
#初始化边
self.__initE1A3( a, b, c)
else:
if A+B+C!=180:
print("三角∠A=%s、∠B=%s、∠C=%s不能构成三角形!" % (str(A), str(B), str(C)))
return True
self.__A=A*pi/180
self.__B=B*pi/180
self.__C=C*pi/180
#初始化边
self.__initE1A3( a, b, c)
self.__initOk=True
return True
#2边1角初始化——解三角形
def __initE2A1(self, a, b, c, A, B, C):
#边角边
if a>0 and b>0 and c<=0:
if C>0 and C<180: #a,b夹C
self.__a=a
self.__b=b
self.__C=C*pi/180
#作a边上的高
_h=b*sin(self.__C)
_x=b*cos(self.__C)
self.__c=((a-_x)**2+_h**2)**.5
self.__B=asin(adjust(_h/self.__c))
self.__A=asin(adjust(a*sin(self.__C)/self.__c))
#解决钝角三角形问题
self.__solvObtuseAngle()
else: #直角三角形才有解
if A>0 and A<90 and b>a and abs(a-b*sin(A*pi/180))<zeroNum: #∠B必然是90°
self.__a=a
self.__b=b
self.__c=(b**2-a**2)**.5
self.__A=A*pi/180
self.__C=pi/2-self.__A
self.__B=pi/2
elif B>0 and B<90 and a>b and abs(b-a*sin(B*pi/180))<zeroNum: #∠A必然是90°
self.__a=a
self.__b=b
self.__c=(a**2-b**2)**.5
self.__B=B*pi/180
self.__C=pi/2-self.__B
self.__A=pi/2
else:
return True
elif a>0 and b<=0 and c>0:
if B>0 and B<180: #a,c夹B
self.__a=a
self.__c=c
self.__B=B*pi/180
#作a边上的高
_h=c*sin(self.__B)
_x=c*cos(self.__B)
self.__b=((a-_x)**2+_h**2)**.5
self.__C=asin(adjust(_h/self.__b))
self.__A=asin(adjust(a*sin(self.__B)/self.__b))
#解决钝角三角形问题
self.__solvObtuseAngle()
else:
if A>0 and A<90 and c>a and abs(a-c*sin(A*pi/180))<zeroNum: #∠C为直角
self.__a=a
self.__b=(c**2-a**2)**.5
self.__c=c
self.__A=A*pi/180
self.__B=pi/2-self.__A
self.__C=pi/2
elif C>0 and C<90 and a>c and abs(c-a*sin(C*pi/180))<zeroNum: #∠A为直角
self.__a=a
self.__b=(a**2-c**2)**.5
self.__c=c
self.__C=C*pi/180
self.__B=pi/2-self.__C
self.__A=pi/2
else:
return True
elif a<=0 and b>0 and c>0:
if A>0 and A<180: #b,c夹A
self.__b=b
self.__c=c
self.__A=A*pi/180
#作b边上的高
_h=c*sin(self.__A)
_x=c*cos(self.__A)
self.__a=((b-_x)**2+_h**2)**.5
self.__C=asin(adjust(_h/self.__a))
self.__B=asin(adjust(b*sin(self.__A)/self.__a))
#解决钝角三角形问题
self.__solvObtuseAngle()
else:
if B>0 and B<90 and c>b and (b-c*sin(B*pi/180)) < zeroNum: #C直角
self.__B=B*pi/180
self.__a=c*cos(self.__B)
self.__b=b
self.__c=c
self.__A=pi/2-self.__B
self.__C=pi/2
elif C>0 and C<90 and b>c and (c-b*sin(C*pi/180)) < zeroNum: #B为直角
self.__C=C*pi/180
self.__a=b*cos(self.__C)
self.__b=b
self.__c=c
self.__A=pi/2-self.__C
self.__B=pi/2
else:
return True
else:
return None
self.__initOk=True
return True
#内切圆和外接圆,使用元组(radius,distance,angle)
#class Circle():
# radius=None #半径
# distance=None #离A距离
# angle=None #与AB边(即c)的夹角
#创建内切圆
def createIncircle(self):
#角平分线交点
_radius=self.__b*self.__c*sin(self.__A)/(self.__a+self.__b+self.__c)
_distance=_radius/sin(self.__A/2)
_angle=self.__A/2
return _radius, _distance, _angle
#创建外接圆
def createCircumcircle(self):
#中垂线交点
_radius=self.__a/(2*sin(self.__A))
_distance=_radius
if self.__C<pi/2:
_angle=pi/2-self.__C
else:
_angle=pi/2-self.__C
return _radius, _distance, _angle
def __str__(self):
if self.__initOk:
return "三角形边长a=%s,b=%s,c=%s,\n角∠A=%s,∠B=%s,∠C=%s" % (str(self.__a),str(self.__b),str(self.__c),str(self.__A*180/pi),str(self.__B*180/pi),str(self.__C*180/pi))
else:
return "输入的参数未能构成唯一的三角形"
#初始化
def __init__(self, a=-1 , b=-1, c=-1, A=-1, B=-1, C=-1):
if self.__initE3(a, b, c, A, B, C): #3边
pass
elif self.__initE1A2(a, b, c, A, B, C): #2角1边
pass
elif self.__initE2A1( a, b, c, A, B, C): #2边1角
pass
else:
print("输入的参数未能构成唯一的三角形")
if __name__ == "__main__":
print("1、已知三边")
print(Triangle(12,13,7))
print("2、已知一边二角")
print(Triangle(12,A=35,B=67))
print(Triangle(a=12,A=35,B=67))
print(Triangle(a=12,B=35,C=67))
print(Triangle(b=12,A=35,B=67))
print(Triangle(b=12,A=35,B=67))
print(Triangle(b=12,B=35,C=67))
print(Triangle(c=12,A=35,B=67))
print(Triangle(c=12,A=35,B=67))
print(Triangle(c=12,B=35,C=67))
print("3、边角边")
print(Triangle(12,15,C=67))
print(Triangle(a=12,b=15,C=67))
print(Triangle(a=12,c=15,B=67))
print(Triangle(b=12,c=15,A=67))
print("4、其它二边一角——不是直角三角形无解")
print(Triangle(12,12*sin(67*pi/180),B=67))
print(Triangle(12*sin(67*pi/180),12,A=67))
print(Triangle(12,b=12*sin(67*pi/180),B=67))
print(Triangle(a=12,b=12*sin(67*pi/180),B=67))
print(Triangle(a=12*sin(67*pi/180),b=12,A=67))
print(Triangle(b=12,c=12*sin(67*pi/180),C=67))
print(Triangle(b=12*sin(67*pi/180),c=12,B=67))
print(Triangle(a=12,c=12*sin(67*pi/180),C=67))
print(Triangle(a=12*sin(67*pi/180),c=12,A=67))
print(Triangle(12,c=12*sin(67*pi/180),C=67))
print(Triangle(12*sin(67*pi/180),c=12,A=67))
_t=7*3**.5
_tr=Triangle(14,7,_t)
_radius, _distance, _angle = _tr.createIncircle()
print("radius=",_radius," distance=",_distance," angle=",_angle*180/pi)
_radius, _distance, _angle = _tr.createCircumcircle()
print("radius=",_radius," distance=",_distance," angle=",_angle*180/pi)