TrigonMaster
Posted: Sat Sep 17, 2011 7:10 pm
TrigonMaster is a utility program that will solve triangle parameters for you.
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).
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