  Triangle Solver (Python 3.x)   Solves a triangle by any permutation of sides and angles given Download source code: Universal_Triangle_Solver.py   import numpy as np class Triangle: def __init__( self, s = [-1.0,-1.0,-1.0], a = [-1.0,-1.0,-1.0]): self.__sideNames__ = ['a', 'b', 'c'] self.__angleNames__ = ['alpha', 'beta', 'gamma'] self.sides = np.array( s) self.angles = np.array( a) self.Verbose = False self.Solve() return def Solve( self): self.__solveAngle__(2,0,1) self.__solveAngle__(0,1,2) self.__solveAngle__(1,2,0) self.__solveSide__(2,0,1) self.__solveSide__(0,1,2) self.__solveSide__(1,2,0) self.__solveAngle__(2,0,1) self.__solveAngle__(0,1,2) self.__solveAngle__(1,2,0) return def Print( self): for i in range(3): print( "{:s} = {:.3f}\t {:s} = {:.3f}".format( self.__sideNames__[i], self.sides[i], self.__angleNames__[i], self.angles[i])) return def SolveInteractive( self): self.sides = self.__getInput__( "{:s} {:s} {:s}".format( self.__sideNames__, self.__sideNames__, self.__sideNames__)) i = self.__CountDefinedSides__() if i <= 0: print( "WARNING: At least two angles should be given") if i < 3: self.angles = self.__getInput__( "{:s} {:s} {:s}".format( self.__angleNames__, self.__angleNames__, self.__angleNames__)) else: self.angles = -np.ones(3) if self.Verbose: print( "Initial Triangle:") self.Print() self.Solve() if self.Verbose: print( "Solution Triangle:") self.Print() return def __getInput__(self, question): i = 0 s = str( input( question + " = ")) ss = s.split(" ") try: a = float( ss) except: a = -1 try: b = float( ss) except: b = -1 try: c = float( ss) except: c = -1 return np.array( [a,b,c]) def __CountDefinedSides__(self): i = 0 for s in self.sides: if s > 0: i += 1 return i def __solveAngle__(self, il, i, ir): if self.angles[i] > 0: return if self.angles[il] > 0 and self.angles[ir] > 0: self.angles[i] = self.__SimpleAngle__(il, i, ir) return if self.angles[il] > 0 and self.sides[il] > 0 and self.sides[i] > 0: self.angles[i] = self.__SineTheoremAngle__(il, i) return if self.angles[ir] > 0 and self.sides[ir] > 0 and self.sides[i] > 0: self.angles[i] = self.__SineTheoremAngle__(ir, i) return if self.sides[il] > 0 and self.sides[ir] > 0 and self.sides[i] > 0: self.angles[i] = self.__CosineTheoremAngle__(il, i, ir) return return def __solveSide__(self, il, i, ir): if self.sides[i] > 0: return if self.angles[il] > 0 and self.sides[il] > 0 and self.angles[i] > 0: self.sides[i] = self.__SineTheoremSide__(il, i) return if self.angles[ir] > 0 and self.sides[ir] > 0 and self.angles[i] > 0: self.sides[i] = self.__SineTheoremSide__(ir, i) return if self.sides[il] > 0 and self.sides[ir] > 0 and self.angles[i] > 0: self.sides[i] = self.__CosineTheoremSide__(il, i, ir) return return def __SimpleAngle__( self, il, i, ir): if self.Verbose: print("Using sum of angles for {:s}".format(self.__angleNames__[i])) return 180 - self.angles[il] - self.angles[ir] def __SineTheoremAngle__( self, i0, i): if self.Verbose: print("Using sine theorem for {:s}".format(self.__angleNames__[i])) d = self.sides[i] / self.sides[i0] d *= np.sin( np.pi*self.angles[i0]/180) if d<0: return -1 return np.arcsin( d)*180/np.pi def __CosineTheoremAngle__( self, il, i, ir): if self.Verbose: print("Using cosine theorem for {:s}".format(self.__angleNames__[i])) d = self.sides[il] * self.sides[il] d += self.sides[ir] * self.sides[ir] d -= self.sides[i] * self.sides[i] d /= 2 * self.sides[il] * self.sides[ir] try: a = 180 * np.arccos( d) / np.pi except: return -1 return a def __SineTheoremSide__( self, i0, i): if self.Verbose: print("Using sine theorem for {:s}".format(self.__sideNames__[i])) d = np.sin( np.pi*self.angles[i] / 180.0) d /= np.sin( np.pi*self.angles[i0] / 180.0) d *= self.sides[i0] if d<0: return -1 return d def __CosineTheoremSide__( self, il, i, ir): if self.Verbose: print("Using cosine theorem for {:s}".format(self.__sideNames__[i])) a = np.cos( self.angles[i] * np.pi / 180.0) d = self.sides[il] * self.sides[il] d += self.sides[ir] * self.sides[ir] d -= 2.0 * self.sides[il] * self.sides[ir] * a if d <= 0: return -1.0 return np.sqrt( d) ## ## Uncomment for testing ## ##print( "Test three sides") ##T = Triangle([10.0,12.0,7.0]) ##T.Print() ## ##print( "\nTest two sides and angle in-between") ##T.sides = np.array([10.0,-1.0,7.0]) ##T.angles = np.array([-1.0,87.953,-1.0]) ##T.Solve() ##T.Print() ## ##print( "\nTest two sides and angle on the side") ##T.sides = np.array([10.0,12.0,-1.0]) ##T.angles = np.array([-1.0,87.953,-1.0]) ##T.Solve() ##T.Print() ## ##print( "\nTest one side and two angles") ##T.sides = np.array([-1.0,12.0,-1.0]) ##T.angles = np.array([56.388,-1.0,35.659]) ##T.Solve() ##T.Print() ## ##print( "\nTest incomplete data") ##T.sides = np.array([-1.0,-1.0,-1.0]) ##T.angles = np.array([56.388,-1.0,35.659]) ##T.Solve() ##T.Print() ## print( "Triangle calculations.\nSend Control-C to stop.\n") T = Triangle() T.Verbose = True while True: T.SolveInteractive() print("") (C) M.Yakimov, 2006 