# Trigonometry Libraries

Hello.

This first post consists of a trigonometry library based on the bc command line utility that ships with all Mac’s, it precision, is as good as it gets, but no better than Satimage.osax, and probably much slower.

All angles are supposed to be given in radians, and functions that returns angles as result, (the tangens functions), also returns those in radians.

To convert from a degree to a radian, multiply with pi / 180, conversely, to convert from radians to an angle, multiply with 180 / pi.

``````script bcTrigsLib

on run
set cos_val to my _cos(60 * pi / 180)
set sin_val to my _sin(30 * pi / 180)
set tan_val to my _tan(30 * pi / 180)
set tan_deg to (my _atan(0.57733026919)) * 180 / pi
set cos_deg to (my _acos(0.5)) * 180 / pi
set sin_deg to (my _asin(0.5)) * 180 / pi
set atan_angl to (my _atan2({(my _cos(60 * pi / 180)), (my _sin(60 * pi / 180))})) * 180 / pi
end run
to _cos(aReal)
local tids, theRadian, tempvar
# must adjust for Locale decimal separator before calling bc
set theRadian to aReal as text
tell (a reference to AppleScript's text item delimiters)
set {tids, contents of it} to {contents of it, ","}
set tempvar to text items of theRadian
set contents of it to "."
set theRadian to tempvar as text
set contents of it to tids
end tell
return (do shell script "echo \"scale=20; c(" & theRadian & ")\" |bc -l | tr -s '.' ','") as number
end _cos

to _sin(aReal)
local tids, theRadian, tempvar
# must adjust for Locale decimal separator before calling bc
set theRadian to aReal as text
tell (a reference to AppleScript's text item delimiters)
set {tids, contents of it} to {contents of it, ","}
set tempvar to text items of theRadian
set contents of it to "."
set theRadian to tempvar as text
set contents of it to tids
end tell
return (do shell script "echo \"scale=20; s(" & theRadian & ")\" |bc -l | tr -s '.' ','") as number
end _sin

to _tan(aReal)
local tids, theCosine, tempvar
# must adjust for Locale decimal separator before calling bc
set theTangent to aReal as text
tell (a reference to AppleScript's text item delimiters)
set {tids, contents of it} to {contents of it, ","}
set tempvar to text items of theTangent
set contents of it to "."
set theTangent to tempvar as text
set contents of it to tids
end tell

return (do shell script "echo \"scale=20;  s(" & theTangent & ")/ c( " & theTangent & ") \" |bc -l  | tr -s '.' ','") as number

end _tan

to _acos(in_unity_range)
if (in_unity_range < -1 or in_unity_range > 1) then
error "Argument not in the range -1 â‰¤ arg â‰¤ 1" number 5001
else

local tids, theCosine, tempvar
# must adjust for Locale decimal separator before calling bc
set theCosine to in_unity_range as text
tell (a reference to AppleScript's text item delimiters)
set {tids, contents of it} to {contents of it, ","}
set tempvar to text items of theCosine
set contents of it to "."
set theCosine to tempvar as text
set contents of it to tids
end tell
# http://en.wikipedia.org/wiki/Inverse_trigonometric_functions, (a = atan in bc request below).
return (do shell script "echo \"scale=20; ( a(sqrt((1 - (" & theCosine & "^2) ))/" & theCosine & ")) \" |bc -l  | tr -s '.' ','") as number
end if

end _acos

to _asin(in_unity_range)
if (in_unity_range < -1 or in_unity_range > 1) then
error "Argument not in the range -1 â‰¤ arg â‰¤ 1" number 5001
else
return ((pi / 2) - (my _acos(in_unity_range)))
# http://en.wikipedia.org/wiki/Inverse_trigonometric_functions
end if
end _asin

to _atan(aReal)
local tids, theCosine, tempvar
# must adjust for Locale decimal separator before calling bc
set theTangent to aReal as text
tell (a reference to AppleScript's text item delimiters)
set {tids, contents of it} to {contents of it, ","}
set tempvar to text items of theTangent
set contents of it to "."
set theTangent to tempvar as text
set contents of it to tids
end tell

return (do shell script "echo \"scale=20;  a(" & theTangent & ") \" |bc -l  | tr -s '.' ','") as number
end _atan

to _atan2(tupleOfReals)
# List of two reals
if length of tupleOfReals < 2 then
error "bcTrigsLib: Bad argument: needs two reals" number 5002
else if item 1 of tupleOfReals = 0 then
error "bcTrigsLib: Bad argument: can't divide by zero." number 5001
else if item 2 of tupleOfReals = 0 then
return 0
else
return my _atan(((item 1 of tupleOfReals) / (item 2 of tupleOfReals)))
end if
end _atan2

end script
tell bcTrigsLib to run

``````

Hello.

Here is a library of trigonometric functions, compiled from various sources, they are all implemented in AppleScript, and the better part of them are from the AppleScript source book.

I’d really recommend using bc, or Satimage.osax, since the handlers here, are both slower, and has a lower accuracy.

It may still be interesting for someone to either use them, or just have a look at them, and that was the rationale behind this post.

``````on sine_of(x)
repeat until x â‰¥ 0 and x < 360
if x â‰¥ 360 then
set x to x - 360
end if
if x < 0 then
set x to x + 360
end if
end repeat

--convert from degrees to radians
set x to x * (2 * pi) / 360

set answer to 0
set numerator to x
set denominator to 1
set factor to -(x ^ 2)

repeat with i from 3 to 40 by 2
set answer to answer + numerator / denominator
set numerator to numerator * factor
set denominator to denominator * i * (i - 1)
end repeat

return answer
end sine_of

on cosine_of(x)
repeat until x â‰¥ 0 and x < 360
if x â‰¥ 360 then
set x to x - 360
end if
if x < 0 then
set x to x + 360
end if
end repeat

--convert from degrees to radians
set x to x * (2 * pi) / 360

set answer to 0
set numerator to 1
set denominator to 1
set factor to -(x ^ 2)

repeat with i from 2 to 40 by 2
set answer to answer + numerator / denominator
set numerator to numerator * factor
set denominator to denominator * i * (i - 1)
end repeat

return answer
end cosine_of

--x is in degrees
on tangens_of(x)
set answer to sine_of(x) / (cosine_of(x))
return answer
end tangens_of

--x is ratio of opposite to adjacent sides of triangle
on inverse_tangent_of(x)
set complimentFlag to false
if x > 1 or x < -1 then
set x to 1 / x
set complimentFlag to true
else if x = 1 then
return 45.0
end if

set answer to 0
set numerator to x
set denominator to 1
set ratio to x
set factor to -(x ^ 2)

repeat while abs (ratio) > 1.0E-4
set answer to answer + ratio
set numerator to numerator * factor
set denominator to denominator + 2
set ratio to numerator / denominator
end repeat

--convert from radians to degrees
set answer to answer * 360 / (2 * pi)

if complimentFlag is true then
set answer to 90 - answer
end if

return answer
end inverse_tangent_of

on inverse_sine_of(x)
if x = 1 then
return 90
else if x = -1 then
return -90
else
return (inverse_tangent_of(x / ((1 - (x ^ 2)) ^ 0.5)))
end if
end inverse_sine_of

on inverse_cosine_of(x)
return (90 - inverse_sine_of(x))
end inverse_cosine_of

on inverse_tangent2_of(x, y)
if x = 0 then
if y = 0 then
error "inverse_tangent2_of : y = 0 " number 9000
else if y > 0 then
return 90
else
return -90
end if
else if x > 0 then
return inverse_tangent_of(y / x)
else if y â‰¥ 0 then
return inverse_tangent_of(y / x) + 180
else
return inverse_tangent_of(y / x) - 180
end if
end inverse_tangent2_of
``````