You must know three parameters about your triangle and TrigonMaster will solve the rest.
You must know the length of at least one side.
This is a screen capture of the Linux version.

This code will run on Windows and Linux
I have tested TrigonMaster with Windows XP, Windows 7, and Linux (Ubuntu).
Code: Select all
;Trigon Master by BasicallyPure
#VERSION = 107
#WHEN = "10/26/2011"
;PureBasic 4.51
;Tested on Linux - Ubuntu 10.04
;Tested on Windows XP and 7
EnableExplicit
;enumerations
;{ gadgets
Enumeration
#imgGad_Tri
#Spin_Aa
#Spin_Ab
#Spin_Ac
#Spin_Sa
#Spin_Sb
#Spin_Sc
#CheckBox_Reverse
#ChkBox_Lock_Aa
#ChkBox_Lock_Ab
#ChkBox_Lock_Ac
#ChkBox_LocK_Sa
#ChkBox_LocK_Sb
#ChkBox_LocK_Sc
#Checkbox_AutoScale
#Text_Title
#Editor_Note
#Editor_Analysis
#Btn_Right
#Btn_Equal
#Btn_Perimeter
#Btn_Area
#Str_Value
EndEnumeration
;}
;{ Images
Enumeration
#Image_Triangle
EndEnumeration
;}
;{ Fonts
Enumeration
#Font_10BoldHQ
#Font_12BoldHQ
#Font_Courier_10HQ
EndEnumeration
;}
;{ menu items
Enumeration
#exit
#about
#Enter_Key
EndEnumeration
;}
;{ procedure declarations
Declare.d AdjustTriangle (part.l, value.d)
Declare.d SpinStep(part, updn)
;}
;{ constant declarations
#Angle_A = %000001
#Angle_B = %000010
#Angle_C = %000100
#Side_a = %001000
#Side_b = %010000
#Side_c = %100000
#C_Red = $0000FF
#C_Green = $00FF00
#C_Blue = $FF0000
#C_White = $FFFFFF
#C_Black = $000000
;}
;{ Variable definitions
Define.d Sa = 1, Sb = 1, Sc = 1
Define.d Aa = Radian(60), Ab = Radian(60), Ac = Radian(60)
Define.l part, lock, gadget, flags, bigEvent, key, upDn, side, angle
Define.d value, newValue, perimeter, area
Define.s text
;}
;{ Macro definitions
Macro unlockAll ;used in 'Right' and 'Equal' button events
lock = 0
SetGadgetState(#ChkBox_Lock_Aa,0) : SetGadgetState(#ChkBox_Lock_Ab,0)
SetGadgetState(#ChkBox_Lock_Ac,0) : SetGadgetState(#ChkBox_LocK_Sa,0)
SetGadgetState(#ChkBox_LocK_Sb,0) : SetGadgetState(#ChkBox_LocK_Sc,0)
EndMacro
Macro sideStep(S1, S2, S3) ;used in SpinStep() procedure
value = S3
Select updn
Case 1 ;up
value + (S1 + S2 - S3) * 0.02
Case -1 ;down
value + (Abs(S1 - S2) - S3) * 0.02
EndSelect
EndMacro
Macro angleStep(angle) ;used in SpinStep() procedure
value = Degree(angle)
Select updn
Case 1 ;up
value + Degree((#PI - angle) * 0.02)
Case -1 ;down
value + Degree((0 - angle) * 0.02)
EndSelect
EndMacro
Macro CosLaw(S1,S2,S3,A1) ;cosine law for sides
S1 = Sqr(S2*S2 + S3*S3 - 2*S2*S3*Cos(A1))
EndMacro
Macro ArcCosLaw(A1,S1,S2,S3) ;ArcCosine law for angles
A1 = ACos((S1*S1 - S2*S2 - S3*S3) / (-2*S2*s3))
EndMacro
Macro SinLaw(S1,S2,A1,A2) ;sine law for sides
S1 = (S2 * Sin(A1)) / Sin(A2)
EndMacro
Macro ArcSinLaw(A1,S1,A2,S2) ;ArcSine law for angles
A1 = ASin(S1*Sin(A2) / S2)
EndMacro
Macro ASub(A1,A2,A3) ;angle by subtraction
A1 = #PI - A2 - A3
EndMacro
Macro LowLimit(S1,S2,A) ;enforce low limit for side
If S1 < S2 * Sin(A) : S1 = S2 * Sin(A) : EndIf
If S1 < S2 And A > #PI / 2 : S1 = S2 : EndIf
EndMacro
Macro HighLimit(S1,S2,A) ;enforce high limit for side
If S1 > S2 / Sin(A) : S1 = S2 / Sin(A) : EndIf
If S1 > S2 And A > #PI / 2 : S1 = S2 : EndIf
EndMacro
;}
;{ Open window and add gadgets
text = "Trigon Master"
flags = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 800, 450, text, flags)
If CreateMenu(0, WindowID(0))
MenuTitle("File")
MenuItem(#exit, "Exit")
MenuTitle("Help")
MenuItem(#about, "About Trigon Master")
EndIf
AddKeyboardShortcut(0,#PB_Shortcut_Return, #Enter_Key)
LoadFont(#Font_12BoldHQ, "Microsoft Sans Serif", 12, #PB_Font_Bold|#PB_Font_HighQuality)
LoadFont(#Font_Courier_10HQ, "Courier New", 10, #PB_Font_HighQuality)
CreateImage(#Image_Triangle,300,300)
ImageGadget(#imgGad_Tri, 10, 45, 300, 300, ImageID(#Image_Triangle), #PB_Image_Border)
TextGadget(#Text_Title, 35, 10, 250, 23, "Solve Triangle Parameters", #PB_Text_Center)
SetGadgetFont(#Text_Title, FontID(#Font_12BoldHQ))
;
EditorGadget(#Editor_Note, 325, 10, 355,40, #PB_Editor_ReadOnly)
text = "To scale a triangle: Unlock all sides. Lock any angle," + #CRLF$
text + "then change the side opposite the locked angle."
SetGadgetText(#Editor_Note,text)
;
EditorGadget(#Editor_Analysis, 530, 60, 255, 275, #PB_Editor_ReadOnly)
SetGadgetFont(#Editor_Analysis, FontID(#Font_Courier_10HQ))
;
; ****************** Angle controls **********************
Frame3DGadget(#PB_Any, 325,55, 195, 125, "Angle adjust")
; Angle A
SpinGadget(#Spin_Aa, 330, 75,122,25,-1,1)
SetGadgetColor(#Spin_Aa, #PB_Gadget_BackColor, #C_Red)
SetGadgetColor(#Spin_Aa, #PB_Gadget_FrontColor, #C_White)
SetGadgetState(#Spin_Aa,0)
CheckBoxGadget(#ChkBox_Lock_Aa, 460, 078, 55, 20, "Lock")
; Angle B
SpinGadget(#Spin_Ab, 330, 110, 122, 25, -1, 1)
SetGadgetColor(#Spin_Ab, #PB_Gadget_BackColor, #C_Green)
SetGadgetColor(#Spin_Ab, #PB_Gadget_FrontColor, #C_Black)
SetGadgetState(#Spin_Ab,0)
CheckBoxGadget(#ChkBox_Lock_Ab, 460, 113, 55, 20, "Lock")
; Angle C
SpinGadget(#Spin_Ac, 330, 145, 122, 25, -1, 1)
SetGadgetColor(#Spin_Ac, #PB_Gadget_BackColor, #C_Blue)
SetGadgetColor(#Spin_Ac, #PB_Gadget_FrontColor, #C_White)
SetGadgetState(#Spin_Ac,0)
CheckBoxGadget(#ChkBox_Lock_Ac, 460, 148, 55, 20, "Lock")
;
; ******************* Side controls ***********************
Frame3DGadget(#PB_Any, 325,210, 195, 125, "Side adjust")
; Side a
SpinGadget(#Spin_Sa, 330, 230, 122, 25, -1, 1)
SetGadgetColor(#Spin_Sa, #PB_Gadget_BackColor, #C_Red)
SetGadgetColor(#Spin_Sa, #PB_Gadget_FrontColor, #C_White)
SetGadgetState(#Spin_Sa,0)
CheckBoxGadget(#ChkBox_LocK_Sa, 460, 233, 55, 20, "Lock")
; Side b
SpinGadget(#Spin_Sb, 330, 265, 122, 25, -1, 1)
SetGadgetColor(#Spin_Sb, #PB_Gadget_BackColor, #C_Green)
SetGadgetColor(#Spin_Sb, #PB_Gadget_FrontColor, #C_Black)
SetGadgetState(#Spin_Sb,0)
CheckBoxGadget(#ChkBox_LocK_Sb, 460, 268, 55, 20, "Lock")
; Side c
SpinGadget(#Spin_Sc, 330, 300, 122, 25, -1, 1)
SetGadgetColor(#Spin_Sc, #PB_Gadget_BackColor, #C_Blue)
SetGadgetColor(#Spin_Sc, #PB_Gadget_FrontColor, #C_White)
SetGadgetState(#Spin_Sc,0)
CheckBoxGadget(#ChkBox_LocK_Sc, 460, 303, 55, 20, "Lock")
;
; **************** Image controls **************************
Frame3DGadget(#PB_Any, 15,360, 200, 38, "Image controls")
CheckBoxGadget(#CheckBox_Reverse, 25, 375,80, 20, "Reverse")
CheckBoxGadget(#Checkbox_AutoScale, 115, 375,95, 20, "auto scale")
SetGadgetState(#Checkbox_AutoScale,#PB_Checkbox_Checked)
;
; *************** Force Angles controls ********************
Frame3DGadget(#PB_Any, 325,350, 170, 60, "Force Angles")
ButtonGadget(#Btn_Right, 335, 370, 65, 25, "Right")
ButtonGadget(#Btn_Equal, 420, 370, 65, 25, "Equal")
;
; *************** Force Size controls **********************
Frame3DGadget(#PB_Any, 530,340, 255, 70, "Force Size")
ButtonGadget(#Btn_Perimeter, 680, 352, 80, 25, "Perimeter")
SetGadgetState(#Btn_Perimeter,1)
ButtonGadget(#Btn_Area, 680, 382, 80, 25, "Area")
StringGadget(#Str_Value, 540, 365, 120, 25, "")
;
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
LoadFont(#Font_10BoldHQ, "Microsoft Sans Serif", 10, #PB_Font_Bold|#PB_Font_HighQuality)
For gadget = #Spin_Aa To #Spin_Sc
SetGadgetFont(gadget,FontID(#Font_10BoldHQ))
Next gadget
CompilerEndIf
Else
MessageRequester("Error", "Can't open window 'Trigon Master'!", 0)
End
EndIf
;}
;{ initial operations
AdjustTriangle(#False,value) ;draw the default triangle
;}
;{ >>>>> Event loop <<<<<
Repeat
bigEvent = WaitWindowEvent()
If bigEvent = #PB_Event_Menu
Select EventMenu()
Case #Enter_Key
If GetActiveGadget() <> #Str_Value
AdjustTriangle(part, value)
EndIf
Case #exit
flags = #PB_MessageRequester_YesNo
If MessageRequester("","Quit Trigon Master?",flags) = #PB_MessageRequester_Yes
End
EndIf
Case #about
text = "Trigon Master - version " + StrF(#VERSION / 100.0,2)
text + #CRLF$ + "Copyright " + Chr(169) + " BasicallyPure"
text + #CRLF$ + #WHEN
text + #CRLF$ + "License: free"
MessageRequester("", text, 0)
EndSelect
EndIf
If bigEvent = #PB_Event_Gadget
gadget = EventGadget()
Select gadget
Case #Spin_Aa To #Spin_Sc
part = Pow(2,gadget - #Spin_Aa)
value = ValD(GetGadgetText(gadget))
Select EventType()
Case -1,0,1
upDn = GetGadgetState(gadget) : SetGadgetState(gadget,0)
AdjustTriangle(part, SpinStep(part, upDn))
EndSelect
Case #ChkBox_Lock_Aa To #ChkBox_LocK_Sc
part = Pow(2,gadget - #ChkBox_Lock_Aa)
lock ! part ;toggle side or angle lock
If gadget > #ChkBox_Lock_Ac ;a side lock was toggled
lock & (%000111 + part) ;unlock other sides
For side = #ChkBox_LocK_Sa To #ChkBox_LocK_Sc ;uncheck other boxes
If side <> gadget : SetGadgetState(side,0) : EndIf
Next side
Else ;an angle lock was toggled
lock & (%111000 + part) ;unlock other angles
For angle = #ChkBox_Lock_Aa To #ChkBox_Lock_Ac ;unlock other boxes
If angle <> gadget : SetGadgetState(angle,0) : EndIf
Next angle
EndIf
Case #CheckBox_Reverse, #Checkbox_AutoScale
AdjustTriangle(#False, value)
Case #Btn_Equal
unlockAll ; macro
value = perimeter / 3
AdjustTriangle(#Side_a,value)
AdjustTriangle(#Side_b,value)
AdjustTriangle(#Side_c,value)
Case #Btn_Right
unlockAll ; macro
value = perimeter / (2 + Sqr(2))
If ValD(GetGadgetText(#Spin_Aa)) = 90
AdjustTriangle(#Angle_B, 90)
SetGadgetState(#ChkBox_Lock_Ab,1) : lock | #Angle_B
AdjustTriangle(#Side_a,value)
AdjustTriangle(#Side_c, value)
ElseIf ValD(GetGadgetText(#Spin_Ac)) = 90
AdjustTriangle(#Angle_A, 90)
SetGadgetState(#ChkBox_Lock_Aa,1) : lock | #Angle_A
AdjustTriangle(#Side_b,value)
AdjustTriangle(#Side_c, value)
Else
AdjustTriangle(#Angle_C, 90)
SetGadgetState(#ChkBox_Lock_Ac,1) : lock | #Angle_C
AdjustTriangle(#Side_a,value)
AdjustTriangle(#Side_b, value)
EndIf
Case #Btn_Area, #Btn_Perimeter
newValue = ValD(GetGadgetText(#Str_Value))
If newValue > 0
part = lock ;remember lock states
lock = #Angle_A ;lock only angle A
value = Sa
If gadget = #Btn_Perimeter
;set the perimeter to a specified value
value / perimeter * newValue
ElseIf gadget = #Btn_Area
;set the area to a specified value
value * Sqr(newValue / area)
EndIf
AdjustTriangle(#Side_a, value)
lock = part ;restore the lock states
EndIf
EndSelect
EndIf
Until bigEvent = #PB_Event_CloseWindow
;} end event loop
End
Procedure.d AdjustTriangle(part.l, value.d)
;recalculate and redraw the triangle using the new part and value
;part specifies one of the 3 sides or 3 angles to modify
;value specifies the magnitude of the part
;part = #false draws triangle without value adjustments
;{ variables used in this procedure
Static.d scale = 1
Static.l SideX, SideY, SideZ
Static.l AngleX, AngleY, AngleZ
Static.l GadgetString
Static.d Sx, Sy, Sz, Ax, Ay, Az
Protected.l x, y, a, b, c
Protected.d n, width, height, oldAngle
Protected.s text
Shared Sa, Sb, Sc ;triangle sides
Shared Aa, Ab, Ac ;triangle angles
Shared lock, perimeter, area
;}
Select part
;{ assign the generic adjustment variables
Case #Side_a, #Angle_A
If part = #Angle_A : GadgetString = #Spin_Aa
Else : GadgetString = #Spin_Sa : EndIf
SideX = #Side_a : SideY = #Side_b : SideZ = #Side_c
AngleX = #Angle_A : AngleY = #Angle_B : AngleZ = #Angle_C
Sx = Sa : Sy = Sb : Sz = Sc : Ax = Aa : Ay = Ab : Az = Ac
Case #Side_b, #Angle_B
If part = #Angle_B : GadgetString = #Spin_Ab
Else : GadgetString = #Spin_Sb : EndIf
SideX = #Side_b : SideY = #Side_c : SideZ = #Side_a
AngleX = #Angle_B : AngleY = #Angle_C : AngleZ = #Angle_A
Sx = Sb : Sy = Sc : Sz = Sa : Ax = Ab : Ay = Ac : Az = Aa
Case #Side_c, #Angle_C
If part = #Angle_C : GadgetString = #Spin_Ac
Else : GadgetString = #Spin_Sc : EndIf
SideX = #Side_c : SideY = #Side_a : SideZ = #Side_b
AngleX = #Angle_C : AngleY = #Angle_A : AngleZ = #Angle_B
Sx = Sc : Sy = Sa : Sz = Sb : Ax = Ac : Ay = Aa : Az = Ab
;}
EndSelect
Select part ;perform the generic adjustments
Case #Side_a, #Side_b, #Side_c
;{ generic side adjustment (sideX)
If SideX & lock
SetGadgetText(GadgetString,Left(StrD(Sx,11),12))
ProcedureReturn
EndIf
If value < 1E-10 : value = 1E-10 : EndIf
Sx = value
If AngleX & lock
If SideY & lock ;adjust Angle Y, Z and side z
LowLimit(Sx,Sy,Ax) ;enforce lower limit
ArcSinLaw(Ay,Sy,Ax,Sx) : ASub(Az,Ax,Ay) : CosLaw(Sz,Sx,Sy,Az)
ElseIf SideZ & lock ;adjust Angle Z, Y and side y
LowLimit(Sx,Sz,Ax) ;enforce lower limit
ArcSinLaw(Az,Sz,Ax,Sx) : ASub(Ay,Ax,Az) : CosLaw(Sy,Sx,Sz,Ay)
Else ;adjust sides z, y
SinLaw(Sz,Sx,Az,Ax) : CosLaw(Sy,Sx,Sz,Ay)
EndIf
ElseIf AngleY & lock
If SideY & lock ;adjust Angle X, Z and side z
HighLimit(Sx,Sy,Ay) ;enforce upper limit
ArcSinLaw(Ax,Sx,Ay,Sy) : ASub(Az,Ax,Ay) : CosLaw(Sz,Sx,Sy,Az)
Else ;adjust side y and Ang X, Z
CosLaw(Sy,Sx,Sz,Ay) : ArcCosLaw(Ax,Sx,Sy,Sz) : ArcCosLaw(Az,Sz,Sx,Sy)
EndIf
ElseIf AngleZ & lock
If SideZ & lock ;adjust Angle X, Y and side y
HighLimit(Sx,Sz,Az) ;enforce upper limit
ArcSinLaw(Ax,Sx,Az,Sz) : ASub(Ay,Ax,Az) : CosLaw(Sy,Sx,Sz,Ay)
Else ;adjust side z and Angle X, Y
CosLaw(Sz,Sx,Sy,Az) : ArcCosLaw(Ax,Sx,Sy,Sz) : ArcCosLaw(Ay,Sy,Sz,Sx)
EndIf
Else ;adjust all angles
If Sx >= Sy + Sz : Sx = Sy + Sz - 1E-10 : EndIf
If Sx + Sy <= Sz : Sx = Sz - Sy + 1E-10 : EndIf
If Sx + Sz <= Sy : Sx = Sy - Sz + 1E-10 : EndIf
ArcCosLaw(Ax,Sx,Sy,Sz) : ArcCosLaw(Ay,Sy,Sz,Sx) : ArcCosLaw(Az,Sz,Sx,Sy)
EndIf
;}
Case #Angle_A, #Angle_B, #Angle_C
;{ generic angle adjustment (AngleX)
If AngleX & lock
SetGadgetText(GadgetString,Left(StrD(Degree(Ax),11),12))
ProcedureReturn
EndIf
If value >= 180 : value = 180 - 1E-6 : EndIf
If value < 1E-6 : value = 1E-6 : EndIf
oldAngle = Ax : Ax = Radian(value)
If AngleY & lock ;adjust angle Z
If Ax + Ay >= #PI : Ax = #PI - Ay - 1E-10 : EndIf
ASub(Az,Ax,Ay)
If SideX & lock ;adjust sides y, z
SinLaw(Sy,Sx,Ay,Ax) : CosLaw(Sz,Sx,Sy,Az)
ElseIf SideZ & lock ;adjust sides x, y
SinLaw(Sx,Sz,Ax,Az) : CosLaw(Sy,Sx,Sz,Ay)
Else ;adjust sides x, z
SinLaw(Sx,Sy,Ax,Ay) : CosLaw(Sz,Sx,Sy,Az)
EndIf
ElseIf AngleZ & lock ;adjust angle Y
If Ax + Az >= #PI : Ax = #PI - Az - 1E-10 : EndIf
ASub(Ay,Ax,Az)
If SideX & lock ; adjust sides y, z
SinLaw(Sy,Sx,Ay,Ax) : CosLaw(Sz,Sx,Sy,Az)
ElseIf SideY & lock ;adjust sides x, z
SinLaw(Sx,Sy,Ax,Ay) : CosLaw(Sz,Sx,Sy,Az)
Else ;adjust sides x, y
SinLaw(Sx,Sz,Ax,Az) : CosLaw(Sy,Sx,Sz,Ay)
EndIf
ElseIf SideX & lock ;adjust Angle Y, Z and sides y, z
Ay + (oldAngle - Ax) / 2
ASub(Az,Ax,Ay) : SinLaw(Sy,Sx,Ay,Ax) : CosLaw(Sz,Sx,Sy,Az)
ElseIf SideY & lock ;adjust Angle Y and sides x, z
ASub(Ay,Ax,Az) : SinLaw(Sx,Sy,Ax,Ay) : CosLaw(Sz,Sx,Sy,Az)
ElseIf SideZ & lock ;adjust Angle Z and sides x, y
ASub(Az,Ax,Ay) : SinLaw(Sx,Sz,Ax,Az) : CosLaw(Sy,Sx,Sz,Ay)
Else ;nothing locked, adjust side x and Angle Y, Z
CosLaw(Sx,Sy,Sz,Ax) : ArcCosLaw(Ay,Sy,Sz,Sx) : ArcCosLaw(Az,Sz,Sx,Sy)
EndIf
;}
EndSelect
Select part
;{ update side & angle variables from generic adjustment variables
Case #Side_a, #Angle_A
Sa = Sx : Sb = Sy : Sc = Sz : Aa = Ax : Ab = Ay : Ac = Az
Case #Side_b, #Angle_B
Sb = Sx : Sc = Sy : Sa = Sz : Ab = Ax : Ac = Ay : Aa = Az
Case #Side_c, #Angle_C
Sc = Sx : Sa = Sy : Sb = Sz : Ac = Ax : Aa = Ay : Ab = Az
;}
EndSelect
;{ display the results
n = Sb * Cos(Ac)
width = Sa
If n < 0
width - n
ElseIf n > Sa
width + n - Sa
EndIf
height = Sb * Sin(Ac)
If GetGadgetState(#Checkbox_AutoScale) = #PB_Checkbox_Checked
If IsNAN(width) Or IsNAN(height)
text = "Result was 'Not A Number'." + #CRLF$
text + "All paramaters will be reset."
MessageRequester("Error!",text)
Sa = 1 : Sb = 1 : Sc = 1
Aa = Radian(60) : Ab = Radian(60) : Ac = Radian(60)
width = 1 : scale = 250 : height = Sin(Ac) : n = Sb * Cos(Ac)
unlockAll
Else
If width > height
scale = 250 / width
Else
scale = 250 / height
EndIf
EndIf
EndIf
x = (300 - width * scale) / 2
If n < 0 : x - n * scale : EndIf
y = 300 - (300 - height * scale) / 2
a = Sa * scale : b = Sb * scale : c = Sc * scale
If GetGadgetState(#CheckBox_Reverse) = #PB_Checkbox_Checked
x = 300 - x : y = 300 - y : a * -1 : b * -1: c * -1
EndIf
StartDrawing(ImageOutput(#Image_Triangle))
;erase
Box(0, 0, 300, 300, #C_Black)
; draw vertices
Circle(x + a, y, 3, #C_Green)
Circle(x, y, 3, #C_Blue)
Circle(x + b*Cos(Ac), y - b*Sin(Ac), 3, #C_Red)
;draw side a
LineXY(x, y, x + a, y , #C_Red)
;draw side b
LineXY(x, y, x + b*Cos(Ac), y - b*Sin(Ac) , #C_Green)
;draw side c
LineXY(x + a, y, x + a - c * Cos(Ab), y - c * Sin(Ab) , #C_Blue)
StopDrawing()
SetGadgetState(#imgGad_Tri,ImageID(#Image_Triangle))
SetGadgetText(#Spin_Aa,Left(StrD(Degree(Aa),11),12))
SetGadgetText(#Spin_Ab,Left(StrD(Degree(Ab),11),12))
SetGadgetText(#Spin_Ac,Left(StrD(Degree(Ac),11),12))
SetGadgetText(#Spin_Sa,Left(StrD(Sa,11),12))
SetGadgetText(#Spin_Sb,Left(StrD(Sb,11),12))
SetGadgetText(#Spin_Sc,Left(StrD(Sc,11),12))
text = " Triangle analysis:" + #CRLF$ + #CRLF$
x = 1E4 : a = Aa*x : b = Ab*x : c = Ac*x
y = #PI/2 * x ;use for right angle comparison
;angle classification
If a = y Or b = y Or c = y
text + " a 'right' triangle" + #CRLF$
ElseIf a < y And b < y And c < y
text + " an 'acute' triangle" + #CRLF$
Else
text + " an 'obtuse' triangle" + #CRLF$
EndIf
;side classification
a = Round(Sa*x, 2) : b = Round(Sb*x, 2) : c = Round(Sc*x, 2)
If a = b And b = c
text + " an 'equilateral' triangle" + #CRLF$
ElseIf a = b Or a = c Or b = c
text + " an 'isosceles' triangle" + #CRLF$
Else
text + " a 'scalene' triangle" + #CRLF$
EndIf
perimeter = Sa + Sb + Sc
area = (Sa * Sb * Sin(Ac)) / 2
text + #CRLF$
text + " red length = " + Left(StrD(Sa,11),12) + #CRLF$
text + " green length = " + Left(StrD(Sb,11),12) + #CRLF$
text + " blue length = " + Left(StrD(Sc,11),12) + #CRLF$ + #CRLF$
text + " red angle = " + Left(StrD(Degree(Aa),11),12) + #CRLF$
text + " green angle = " + Left(StrD(Degree(Ab),11),12) + #CRLF$
text + " blue angle = " + Left(StrD(Degree(Ac),11),12) + #CRLF$
text + #CRLF$ + " perimeter = " + StrD(perimeter) + #CRLF$
text + #CRLF$ + " area = " + StrD(area)
SetGadgetText(#Editor_Analysis,text)
;}
EndProcedure
Procedure.d SpinStep(part, updn)
;calculate increment and return new value for triangle spingadgets
Shared Sa, Sb, Sc, Aa, Ab, Ac
Protected value.d
Select part
Case #Side_a
sideStep(Sb, Sc, Sa) ; macro
Case #Side_b
sideStep(Sa, Sc, Sb) ; macro
Case #Side_c
sideStep(Sa, Sb, Sc) ; macro
Case #Angle_A
angleStep(Aa) ; macro
Case #Angle_B
angleStep(Ab) ; macro
Case #Angle_C
angleStep(Ac) ; macro
EndSelect
ProcedureReturn value
EndProcedure