Jump to content
Sign in to follow this  
E1M1

Need help with classifying triangles - scrpt mixes up acute and obtuse

Recommended Posts

E1M1

Does anyone know why my script mixes up acute and obtuse?

2nd test should be acute angle

3rd should be obtuse angle

MsgBox(0,0,Test("1 0 2 0 1 2"))
MsgBox(0,0,Test("3 0 4 2 5 0"))
MsgBox(0,0,Test("6 0 7 0 8 2"))
;~ $TriangleCoords = "x1 xy x2 y2 x3 y3"
;~ Angles: If 1 of the angles are:
;         < 90 acute angle
;          > 90 obtuse angle
;         = 90 square corner
Func Test($TriangleCoords)
    ConsoleWrite(@CRLF)
 
    $Triangle = $TriangleCoords
    $Triangle = StringSplit($Triangle, " ")
 
    Dim $A[2], $B[2], $C[2], $AB[2], $BC[2], $CA[2]
 
    $A[0] = Number($Triangle[1])
    $A[1] = Number($Triangle[2])
 
    $B[0] = Number($Triangle[3])
    $B[1] = Number($Triangle[4])
 
    $C[0] = Number($Triangle[5])
    $C[1] = Number($Triangle[6])
 
    $AB[0] = $B[0] - $A[0]
    $AB[1] = $B[1] - $A[1]
 
    $BC[0] = $C[0] - $B[0]
    $BC[1] = $C[1] - $B[1]
 
    $CA[0] = $A[0] - $C[0]
    $CA[1] = $A[1] - $C[1]
 
    $ABLen = Sqrt($AB[0] ^ 2 + $AB[1] ^ 2)
    $BCLen = Sqrt($BC[0] ^ 2 + $BC[1] ^ 2)
    $CALen = Sqrt($CA[0] ^ 2 + $CA[1] ^ 2)
 
    If $ABLen = 0 Or $BCLen = 0 Or $CALen = 0 Then Return "ERROR"
 
 
    $pi = 3.14159265358979
    $radToDeg = 180 / $pi
 
 
    $BA_BC_Angle = Angle($AB,$BC)
    $AB_AC_Angle = Angle($AB,$CA)
    $CA_CB_angle = Angle($CA,$BC)
 
    ConsoleWrite($BA_BC_Angle&@CRLF)
    ConsoleWrite($AB_AC_Angle&@CRLF)
    ConsoleWrite($CA_CB_angle&@CRLF)
 
    If $BA_BC_Angle = 0 Or $AB_AC_Angle = 0 Or $CA_CB_angle = 0 Then Return "square corner"
 
    $BA_BC_Angle = ToTirstQuater(Abs(ACos($BA_BC_Angle) * $radToDeg))
    $AB_AC_Angle = ToTirstQuater(Abs(ACos($AB_AC_Angle) * $radToDeg))
    $CA_CB_angle = ToTirstQuater(Abs(ACos($CA_CB_angle) * $radToDeg))
 
    ConsoleWrite($BA_BC_Angle&@CRLF)
    ConsoleWrite($AB_AC_Angle&@CRLF)
    ConsoleWrite($CA_CB_angle&@CRLF)
 
    If $BA_BC_Angle < 90 and $AB_AC_Angle < 90 and $CA_CB_angle < 90 Then Return "acute angle"
 
    Return "obtuse angle"
EndFunc   ;==>Test
 
 
Func ScalarProduct($u,$v)
    Return $u[0]*$v[0] + $u[1]*$v[1]
EndFunc
 
Func Angle($u,$v)
    Return ScalarProduct($u,$v)/(Sqrt($u[0] ^ 2 + $u[1] ^ 2)*Sqrt($v[0] ^ 2 + $v[1] ^ 2))
EndFunc
 
Func ToTirstQuater($iAnge)
    If $iAnge > 90 Then Return 180 - $iAnge
    Return $iAnge
EndFunc

Pic shows triangles used in 3 tests

Posted Image

post-45701-0-40969200-1318180459_thumb.p

Edited by E1M1

edited

Share this post


Link to post
Share on other sites
jaberwacky

Edit: Actually, I now think the problem lies within this section of your code:

$AB[0] = $B[0] - $A[0]
$AB[1] = $B[1] - $A[1]
 
$BC[0] = $C[0] - $B[0]
$BC[1] = $C[1] - $B[1]
 
$CA[0] = $A[0] - $C[0]
$CA[1] = $A[1] - $C[1]

Well, no that can't be it because it correctly determines a right triangle. Ok, nevermind that and continue reading.

I think you're problem lies within this function: ToTirstQuater.

Here is my version of the code which, I believe, demonstrates the problem:

MsgBox(0, 0, Test("1 0 2 0 1 2"))
MsgBox(0, 0, Test("3 0 5 0 4 2"))
MsgBox(0, 0, Test("6 0 7 0 8 2"))
 
;~ $TriangleCoords = "x1 y1 x2 y2 x3 y3"
;~ Angles: If 1 of the angles are:
;        < 90 acute angle
;         > 90 obtuse angle
;        = 90 square corner
 
Func Test($TriangleCoords)
    Local Const $Triangle = StringSplit($TriangleCoords, " ")
 
    Local $A[2]
    $A[0] = Number($Triangle[1])
    $A[1] = Number($Triangle[2])
 
    Local $B[2]
    $B[0] = Number($Triangle[3])
    $B[1] = Number($Triangle[4])
 
    Local $C[2]
    $C[0] = Number($Triangle[5])
    $C[1] = Number($Triangle[6])
 
    Local $AB[2]
    $AB[0] = $B[0] - $A[0]
    $AB[1] = $B[1] - $A[1]
 
    Local $BC[2]
    $BC[0] = $C[0] - $B[0]
    $BC[1] = $C[1] - $B[1]
 
    Local $CA[2]
    $CA[0] = $A[0] - $C[0]
    $CA[1] = $A[1] - $C[1]
 
    Local Const $ABLen = Sqrt($AB[0] ^ 2 + $AB[1] ^ 2)
    Local Const $BCLen = Sqrt($BC[0] ^ 2 + $BC[1] ^ 2)
    Local Const $CALen = Sqrt($CA[0] ^ 2 + $CA[1] ^ 2)
 
    If $ABLen = 0 Or $BCLen = 0 Or $CALen = 0 Then Return "ERROR"
 
    Local $BA_BC_Angle = Angle($AB, $BC)
    Local $AB_AC_Angle = Angle($AB, $CA)
    Local $CA_CB_Angle = Angle($CA, $BC)
 
    ConsoleWrite("-----------------------------------------" & @CRLF)
    ConsoleWrite("$BA_BC_Angle: " & $BA_BC_Angle & @CRLF)
    ConsoleWrite("$AB_AC_Angle: " & $AB_AC_Angle & @CRLF)
    ConsoleWrite("$CA_CB_Angle: " & $CA_CB_Angle & @CRLF & @CRLF)
    ConsoleWrite("Sum: " & $BA_BC_Angle + $AB_AC_Angle + $CA_CB_Angle & @CRLF)
 
    If $BA_BC_Angle = 90 Or $AB_AC_Angle = 90 Or $CA_CB_Angle = 90 Then
        ConsoleWrite("-----------------------------------------" & @CRLF & @CRLF)
        Return "square corner"
    EndIf
 
    $BA_BC_Angle = ToTirstQuater($BA_BC_Angle)
    $AB_AC_Angle = ToTirstQuater($AB_AC_Angle)
    $CA_CB_Angle = ToTirstQuater($CA_CB_Angle)
 
    ConsoleWrite(@CRLF & "$BA_BC_Angle: " & $BA_BC_Angle & @CRLF)
    ConsoleWrite("$AB_AC_Angle: " & $AB_AC_Angle & @CRLF)
    ConsoleWrite("$CA_CB_Angle: " & $CA_CB_Angle & @CRLF & @CRLF)
    ConsoleWrite("Sum: " & $BA_BC_Angle + $AB_AC_Angle + $CA_CB_Angle & @CRLF)
    ConsoleWrite("-----------------------------------------" & @CRLF & @CRLF)
 
    If $BA_BC_Angle > 90 Or $AB_AC_Angle > 90 Or $CA_CB_Angle > 90 Then Return "obtuse angle"
 
    If $BA_BC_Angle < 90 And $AB_AC_Angle < 90 And $CA_CB_Angle < 90 Then Return "acute angle"
EndFunc   ;==>Test
 
Func dot_product($v, $u)
    Return $v[0] * $u[0] + $v[1] * $u[1]
EndFunc   ;==>ScalarProduct
 
Func angle($v, $u)
    Local Const $dot_product = dot_product($v, $u)
    Local Const $length_of_v = Sqrt($v[0] ^ 2 + $v[1] ^ 2)
    Local Const $length_of_u = Sqrt($u[0] ^ 2 + $u[1] ^ 2)
    Local Const $cos_theta = ($dot_product / ($length_of_v * $length_of_u))
    Return Round(ACos($cos_theta) * (180 / 3.14159265358979), 3)
EndFunc
 
Func ToTirstQuater($iAnge)
    If $iAnge > 90 Then Return Abs(180 - $iAnge)
    Return Abs($iAnge)
EndFunc   ;==>ToTirstQuater

This has been a lot of fun. I've learned more about trigonometry than I ever learned in school.

Edited by LaCastiglione

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×