here is a 2D interactive program that demonstrates how to solve this problem using the SSS solution.
5% of this code, tops, is the 2 functions to solve the triangle and plot the coordinates. The other 95% is displaying it all.
no media or anything, all 2d.
//Fun with triangles, by Mike Shihrer, aka Visigoth
//If you find this code useful, you may use it with no restrictions, but a small credit would be nice :)
set display mode 1024,768,32
//for ui
global side_inc#
global rotation_inc#
global hide_flag
hide_flag = 1
//adjust these if your keypress draw lines too fast or slow
//and if rotating triangle is too fast or slow
side_inc# = .05
rotation_inc# = .15
//variables for the internal triangle solution
global angA#
global angB#
global angC#
global sideA#
global sideB#
global sideC#
global xA#
global yA#
global xB#
global yB#
global xC#
global yC#
global r_ang#
//init internal side lengths
sideA# = 160.0
sideB# = 240.0
sideC# = 360.0
//variables for external triangle
global e_angA#
global e_angB#
global e_angC#
global e_sideA#
global e_sideB#
global e_sideC#
global e_xA#
global e_yA#
global e_xB#
global e_yB#
global e_xC#
global e_yC#
//init external side lengths
//assume fixed, except side c, since same as internal side c
e_sideA# = 240.0
e_sideB# = 480.0
e_sideC# = sideC#
//variables for offsetting the triangle on the display
global oX#
global oY#
oX# = 100.0
oY# = 100.0
//since we know all the sides, this is all we need
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
//////////////////////////////////
do
cls
ink rgb(255,255,255)
plot_triangles(sideA#,sideB#,sideC#)
print_data()
key_toggles()
loop
/////////////////////////////////
end
//these 2 functions are all you need to solve a triangle when all three sides are known
//first, you solve and get the angles.
//that is the first function
//second function determines coordinates, based on point A at 0,0
//THE MEAT AND BONES////////////////////////////////////////////////////
function solve_triangle_sss(a#,b#,c#,ea#,eb#,ec#)
//where c# is the longest side
//find largest angle first
//internal triangle
angC# = acos((a#^2 + b#^2 - c#^2) / (2*a#*b#))
//find next angle
angA# = asin((a# * sin(angC#)) / c#)
//find last angle
angB# = 180.00 - (angA# + angC#)
//external triangle
e_angC# = acos((ea#^2 + eb#^2 - ec#^2) / (2*ea#*eb#))
//find next angle
e_angA# = asin((ea# * sin(e_angC#)) / ec#)
//find last angle
e_angB# = 180.00 - (e_angA# + e_angC#)
endfunction
function get_coordinates(aA#,aB#,aC#,sa#,sb#,sc#,eaA#,eaB#,eaC#,esa#,esb#,esc#)
//where aA#, aB#,aC# are the angles
//where sa#,sb#,sc# are the sides
//angs are opposite sides
//largest side on bottom
//xA,yA, etc are the coordinates
//this diagram will be upside down on the display, but the data is correct
// xC,yC
// aC#
// /\
// / \ y0
// / \ |
// sb#/ \ sa# |
// / \ |
// / \ |
// aA# /____________\ aB# x0 |---------- x screen width()
// xA,yA sc# xB,yB y screen height
//
//
//
// xA,yA at 0,0
//
//internal tri
xA# = 0.0
yA# = 0.0
//this would be the "random" point in the middle of the problem
xC# = sb# * (cos(aA#))
yC# = sb# * (sin(aA#))
xB# = sc#
yB# = 0.0
//external
e_xA# = 0.0
e_yA# = 0.0
e_xC# = esb# * (cos(eaA#))
e_yC# = esb# * (sin(eaA#))
e_xB# = esc#
e_yB# = 0.0
//now you can reposition points by offsetting ,rotating, or scaling them
//see next few functions
endfunction
/////////////////////////////end MEAT AND BONES///////////////////////////////////////////////
//the rest of these functions show how the data can be used
function plot_triangles(l1#,l2#,l3#)
//if you can solve for 1 triangle, the other two are automatically solved, because the external triangle is known
//keep in mind, 2D screen coordinates are: x positive is to the right, y positive is down, so triangle will be upside down
if hide_flag = 0
//original results
//external tris
ink rgb(255,255,255)
line e_xA#,e_yA#,e_xB#,e_yB#
line e_xB#,e_yB#,e_xC#,e_yC#
line e_xC#,e_yC#,e_xA#,e_yA#
//internal tris
ink rgb(0,0,255)
line xA#,yA#,xB#,yB#
line xB#,yB#,xC#,yC#
line xC#,yC#,xA#,yA#
line xc#,yc#,e_xC#,e_yC#
endif
//offset
//internal
ink rgb(0,0,255)
line xA# + oX#,yA# + oY#,xB# + oX#,yB# + oY#
line xB# + oX#,yB# + oY#,xC# + oX#,yC# + oY#
line xC# + oX#,yC# + oY#,xA# + oX#,yA# + oY#
line xC#+ ox#,yC# + oY#,e_xC# + oX#,e_yC# + oY#
ink rgb(255,0,0)
//external
ink rgb(255,255,255)
line e_xA# + oX#,e_yA# + oY#,e_xB# + oX#,e_yB# + oY#
line e_xB# + oX#,e_yB# + oY#,e_xC# + oX#,e_yC# + oY#
line e_xC# + oX#,e_yC# + oY#,e_xA# + oX#,e_yA# + oY#
//display
set cursor xC#+ ox#,yC# + oY#
print "random point :" , xC#+ ox#,",",yC# + oY#
//rotate internal triangle around point A
//just for show
if hide_flag = 0
ink rgb(0,0,255)
newx1# = cos(r_ang#)
newy1# = sin(r_ang#)
newx2# = cos((360.0 + angA#) + r_ang#)
newy2# = sin((360.0 + angA#) + r_ang#)
line xA# + oX#, yA# + oY#, oX# + (newx1# * l3#), oY# + (newy1# * l3#)
line oX# + (newx1# * l3#), oY# + (newy1# * l3#),oX# + (newx2# * l2#), oY# + (newy2# * l2#)
line oX# + (newx2# * l2#), oY# + (newy2# * l2#),xA# + oX#,yA# + oY#
set cursor xA# + oX#, yA# + oY#
ink rgb(255,255,255)
print "angle :" , r_ang#
set cursor oX# + (newx1# * l3#),oY# + (newy1# * l3#)
print "Point B X :",oX# + (newx1# * l3#),", Point B Y :",oY# + (newy1# * l3#)
set cursor oX# + (newx2# * l2#), oY# + (newy2# * l2#)
print "Point C X :",oX# + (newx2# * l2#),",Point C Y :", oY# + (newy2# * l2#)
inc r_ang#,rotation_inc#
if r_ang# > 360.0
r_ang# = 0
endif
set cursor 0,0
endif
endfunction
function print_data()
x = screen width() / 2
y = 0
set cursor x,y
ink rgb(0,255,0)
print "Controls" : inc y,10 : set cursor x,y
print "keyboard 1,2,3 increase internal sides" : inc y,10 : set cursor x,y
print "keyboard 4,5,6 decrease internal sides" : inc y,10 : set cursor x,y
print "keyboard 7,8 increase external sides" : inc y,10 : set cursor x,y
print "keyboard 9,0 decrease external sides" : inc y,10 : set cursor x,y
print "h,s hide/show rotating triangle, origin triangle" : inc y,10 : set cursor x,y
print "q,w inc/dec origin offset X, e,r inc/dec origin offset Y"
//print "angles : " ,angA#,",",angB#,",",angC# : inc y,10 : set cursor x,y
//print "point A :" ,xA#,",",yA# : inc y,10 : set cursor x,y
//print "point B :" ,xB#,",",yB# : inc y,10 : set cursor x,y
//print "point C :" ,xC#,",",yC# : inc y,10 : set cursor x,y
//print "side A :" , sideA# : inc y,10 : set cursor x,y
//print "side B :" , sideB# : inc y,10 : set cursor x,y
//print "side C :" , sideC# : inc y,10 : set cursor x,y
//print "r_ang :" , r_ang# : inc y,10 : set cursor x,y
print scancode()
set cursor mousex() + 20,mousey() + 20
print mousex(),",",mousey()
endfunction
function key_toggles()
//keys 1,2,3 make sides A,B,C longer
//keys 4,5,6 make sided A,B,C shorter
//it is possible to have lengths of sides that will not make a triangle, which won't crash anything, you just won't get a triangle
if keystate(2) = 1
inc sideA#,side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(3) = 1
inc sideB#,side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(4) = 1
inc sideC#,side_inc#
e_sideC# = sideC#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(5) = 1
dec sideA#, side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(6) = 1
dec sideB#, side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(7) = 1
dec sideC#,side_inc#
e_sideC# = sideC#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(8) = 1
inc e_sideA#, side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(9) = 1
inc e_sideB#,side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(10) = 1
dec e_sideA#, side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(11) = 1
dec e_sideB#,side_inc#
solve_triangle_sss(sideA#,sideB#,sideC#,e_sideA#,e_sideB#,e_sideC#)
get_coordinates(angA#,angB#,angC#,sideA#,sideB#,sideC#,e_angA#,e_angB#,e_angC#,e_sideA#,e_sideB#,e_sideC#)
endif
if keystate(16) = 1
inc oX#,1.0
endif
if keystate(17) = 1
dec oX#,1.0
endif
if keystate(18) = 1
inc oY#,1.0
endif
if keystate(19) = 1
dec oY#,1.0
endif
//hide or show static triangles
if keystate(35) = 1
hide_flag = 1
endif
if keystate(31) = 1
hide_flag = 0
endif
endfunction