PETRONODE

Triange Solver



Triangle

This code solves a triangle with sides a, b, c and the opposing angles alpha, beta, gamma

Download code



    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__[0], self.__sideNames__[1], self.__sideNames__[2]))

            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__[0], self.__angleNames__[1], self.__angleNames__[2]))

            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[0])

            except: a = -1

            try: b = float( ss[1])

            except: b = -1

            try: c = float( ss[2])

            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("")