Inverse trig functions and atan2
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*test.grnd
|
||||||
@@ -158,6 +158,140 @@ fun -double !tan -double &in
|
|||||||
return $store
|
return $store
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
|
fun -double !asin -double &in
|
||||||
|
pusharg $in
|
||||||
|
call !abs &store
|
||||||
|
greater $store 1 &store
|
||||||
|
if $store %error
|
||||||
|
|
||||||
|
# asin(a) is the root of sin(x)-a=0, -pi/2 <= x <= pi/2
|
||||||
|
# Using Newton's Method: x_k+1 = x_k - (sin(x_k)-a)/cos(x_k)
|
||||||
|
|
||||||
|
stod "0" &ans
|
||||||
|
@loop
|
||||||
|
pusharg $ans
|
||||||
|
call !sin &sin
|
||||||
|
subtract $sin $in &sin
|
||||||
|
pusharg $ans
|
||||||
|
call !cos &cos
|
||||||
|
divide $sin $cos &store
|
||||||
|
subtract $ans $store &ans
|
||||||
|
equal $store 0 &store
|
||||||
|
if $store %return
|
||||||
|
jump %loop
|
||||||
|
|
||||||
|
@return
|
||||||
|
return $ans
|
||||||
|
|
||||||
|
@error
|
||||||
|
error "Cannot find sin of a double with magnetude greater than 1" "mathError"
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun -double !acos -double &in
|
||||||
|
# asin(x) + acos(x) = pi/2
|
||||||
|
pusharg $in
|
||||||
|
call !asin &store
|
||||||
|
call !pi &pi
|
||||||
|
divide $pi 2 &pi
|
||||||
|
subtract $pi $store &store
|
||||||
|
return $store
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun -double !atan -double &in
|
||||||
|
# atan(a) is the root of tan(x)-a=0, -pi/2 <= x <= pi/2
|
||||||
|
# Using Newton's Method: x_k+1 = x_k - (tan(x_k)-a)/sec^2(x_k) = x_k - (tan(x_k)-a)cos^2(x_k)
|
||||||
|
|
||||||
|
stod "0" &ans
|
||||||
|
@loop
|
||||||
|
|
||||||
|
pusharg $ans
|
||||||
|
call !tan &num
|
||||||
|
subtract $num $in &num
|
||||||
|
|
||||||
|
pusharg $ans
|
||||||
|
call !cos &dom
|
||||||
|
multiply $dom $dom &dom
|
||||||
|
|
||||||
|
multiply $num $dom &store
|
||||||
|
subtract $ans $store &ans
|
||||||
|
|
||||||
|
pusharg $store
|
||||||
|
call !abs &store
|
||||||
|
lesser $store 0.000000000001 &store
|
||||||
|
if $store %return
|
||||||
|
|
||||||
|
jump %loop
|
||||||
|
|
||||||
|
@return
|
||||||
|
# Make answer in range [-pi/2, pi/2]
|
||||||
|
call !pi &pi
|
||||||
|
pusharg $ans
|
||||||
|
pusharg $pi
|
||||||
|
call !mod &ans
|
||||||
|
divide $pi 2 &pi
|
||||||
|
greater $ans $pi &store
|
||||||
|
if $store %negans
|
||||||
|
return $ans
|
||||||
|
|
||||||
|
@negans
|
||||||
|
call !pi &pi
|
||||||
|
subtract $ans $pi &ans
|
||||||
|
return $ans
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun -double !atan2 -double &y -double &x
|
||||||
|
call !pi &pi
|
||||||
|
divide $pi 2 &pi/2
|
||||||
|
|
||||||
|
# catch "mathError" ÷ByZero
|
||||||
|
set ÷ByZero true
|
||||||
|
divide $y $x &ratio
|
||||||
|
if $divideByZero %continue
|
||||||
|
jump %error
|
||||||
|
|
||||||
|
@continue
|
||||||
|
# When x > 0, return atan(y/x). When x < 0, return pi+atan(y/x) mod 2pi
|
||||||
|
greater $x 0 &store
|
||||||
|
if $store %atan
|
||||||
|
|
||||||
|
# When x < 0, check sign of y
|
||||||
|
lesser $y 0 &store
|
||||||
|
if $store %quadrant3
|
||||||
|
|
||||||
|
pusharg $ratio
|
||||||
|
call !atan &store
|
||||||
|
add $store $pi &store
|
||||||
|
return $store
|
||||||
|
|
||||||
|
@quadrant3
|
||||||
|
pusharg $ratio
|
||||||
|
call !atan &store
|
||||||
|
subtract $store $pi &store
|
||||||
|
return $store
|
||||||
|
|
||||||
|
@atan
|
||||||
|
pusharg $ratio
|
||||||
|
call !atan &store
|
||||||
|
return $store
|
||||||
|
|
||||||
|
@error
|
||||||
|
greater $y 0 &store
|
||||||
|
if $store %90deg
|
||||||
|
|
||||||
|
lesser $y 0 &store
|
||||||
|
if $store %neg90deg
|
||||||
|
|
||||||
|
error "Cannot find atan of (0,0)" "mathError"
|
||||||
|
divide $pi 2 &pi/2
|
||||||
|
|
||||||
|
@90deg
|
||||||
|
return $pi/2
|
||||||
|
|
||||||
|
@neg90deg
|
||||||
|
multiply $pi/2 -1 &store
|
||||||
|
return $store
|
||||||
|
endfun
|
||||||
|
|
||||||
fun -double !random -int &seed
|
fun -double !random -int &seed
|
||||||
set &m 2147483648
|
set &m 2147483648
|
||||||
set &a 1103515245
|
set &a 1103515245
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ Gets the cos of input.
|
|||||||
|
|
||||||
Gets the tan of input.
|
Gets the tan of input.
|
||||||
|
|
||||||
|
### fun -double !asin -double &input
|
||||||
|
|
||||||
|
Finds the angle *x* in the range [-pi/2, pi/2] such that sin(x) equals the input.
|
||||||
|
|
||||||
|
### fun -double !acos -double &input
|
||||||
|
|
||||||
|
Finds the angle *x* in the range [0, pi] such that cos(x) equals the input.
|
||||||
|
|
||||||
|
### fun -double !atan -double &input
|
||||||
|
|
||||||
|
Finds the angle *x* in the range [-pi/2, pi/2] such that tan(x) equals the input.
|
||||||
|
|
||||||
|
### fun -double !atan2 -double &y -double &x
|
||||||
|
|
||||||
|
Finds the angle in the range (-pi, pi] between the positive x axis and the point (x,y). This is equivalent to atan(y/x) for positive values of x.
|
||||||
|
|
||||||
### fun -double !intexp -double &base -int &power
|
### fun -double !intexp -double &base -int &power
|
||||||
|
|
||||||
Returns base^power, for positive integer values of power. Returns 1 if power is non-positive (and thus is inaccurate for negative values of power).
|
Returns base^power, for positive integer values of power. Returns 1 if power is non-positive (and thus is inaccurate for negative values of power).
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
'\''
|
extern "file"
|
||||||
|
|||||||
Reference in New Issue
Block a user