Inverse trig functions and atan2
This commit is contained in:
@@ -158,6 +158,140 @@ fun -double !tan -double &in
|
||||
return $store
|
||||
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
|
||||
set &m 2147483648
|
||||
set &a 1103515245
|
||||
|
||||
@@ -18,6 +18,22 @@ Gets the cos 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
|
||||
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user