I forgot to post this script that computes the number of digits that is used for Math. I have stolen it from Jean-Meeus Astronomical Algorithms page. 17. Hopefully this comes to use with Maverick! ( But I guess I would have heard it by now, if AppleScript starts using 32 digits (or more!)).
# accuracy test
# 15.6 internal digits
set x to 1
set j to 0
repeat while true
set x to x * 2
if x + 1 ≠x then
set j to j + 1
else
exit repeat
end if
end repeat
set numdigits to (j * 0.30103) as text
The constant 0.30103 is log10 2 (the base 10 logarithm of 2 ).
Now, that is a conversion, I’d rather do outside of the sine function. But I have discovered that many “professional” packages do map the argument of the trigonometric functions down into to a range of 360 in degrees, I guess they do that for getting higher precisision, or avoiding some sort of overflow, or maybe they think they do that mapping faster than for instance the sine function. Anyway, I think it is a smart thing to do.
Edit
Such preparations of the argument to the trigonometric functions, has of course something to do with the anticipated magnitude of them, nothing you would do if you thought the arguments to be within a couple of thousand degrees (in radians).
One of the hard things about this to me is that cosine doesn’t work also, but at different angles. I was checking if python had the same problem with pi and came up with this tester:
set t to "#
from math import *
exp1 = exp(1e-5) - 1
exp2 = expm1(1e-5)
print exp1, exp2, sin(pi/2), sin(pi), cos(pi/2), cos(pi)
#"
set cmd to "python -c " & quoted form of t
do shell script cmd
(*
>>> from math import exp, expm1
>>> exp(1e-5) - 1 # gives result accurate to 11 places
1.0000050000069649e-05
>>> expm1(1e-5) # result accurate to full precision
1.0000050000166668e-05
*)
I just put that exponent stuff in there because was wondering how they could get full precision.
Edited: oops, should have deleted that result from another test.
I made a couple of handlers for you, that aligns the result of the arcus function back to the right quadrant.
I also made a handler that identifies the right quadrant of the unity circle an angle is in.
This was just some thoughts about it. It is so much easier when you sit with your pocket calculator, and does the calculations, because then you know which quadrant the result is supposed to be in.
The sine is the true problem child here, because sometimes you’ll have to add 180, other times, 360, and there is no clue in the size of the returned angle of the arcus function, therefore it is best to get the quadrant, or define it, up front, and then use the cosalign, and sinalign, which you can view as counterparts to the atan2 handler.
set tangle to 0
set t1 to 1
set aq to id_quad(tangle)
set r1 to dtr(tangle)
if t1 = 1 then
set c1 to cos r1
set r1 to acos c1
set dt to rtd(r1)
set df to cosalign(dt, aq)
else if t1 = 2 then
set c1 to sin r1
set r1 to asin c1
set dt to rtd(r1)
set df to sinalign(dt, aq)
end if
on rtd(d)
return ((d * 180) / pi)
end rtd
on dtr(r)
return ((r * pi) / 180)
end dtr
to cosalign(d, q)
if (q > 2) then
return (360 - d)
else
return d
end if
end cosalign
to sinalign(d, q)
if (d + 2.0E-14) < 0 then
if q = 4 then
return 360 + d
else # q = 3
return 180 + (-1 * d)
end if
else if q = 2 then
return (180 - d)
else
return d
end if
end sinalign
on id_quad(d)
set d to d mod 360
if d < 0 then set d to d + 360
if d ≥ 0 and d < 90 then
return 1
else if d ≥ 90 and d < 180 then
return 2
else if d ≥ 180 and d < 270 then
return 3
else if d ≥ 270 and d < 360 then
return 4
end if
end id_quad
Edit
I added a constant value for testing for negative values with Satimage.osax in the sinalign handler, in order to get
correct results for 180Ë™.
I don’t understand your script. right now. Maybe because I’m distracted. When I change tangle, I just get the angle back. I’ll look into your script more.
Wow, that was fast. I was stuck on where to start and end a quadrant. I was thinking about other ways to do this too. interesting stuff.
Thanks,
kel
ps. One thing I noticed when running python in the Terminal is that you can see the significant places. But, when it’s returned from the do shell script, the same significant places are lessened. I could probably return the value as string.
set tangle to pi -- changed this from 0
set t1 to 1
set aq to id_quad(tangle)
set r1 to dtr(tangle)
if t1 = 1 then
set c1 to cos r1
set r1 to acos c1
set dt to rtd(r1)
set df to cosalign(dt, aq)
else if t1 = 2 then
set c1 to sin r1
set r1 to asin c1
set dt to rtd(r1)
set df to sinalign(dt, aq)
end if
{sin (r1), cos (r1)} -- added this for result
on rtd(d)
return ((d * 180) / pi)
end rtd
on dtr(r)
return ((r * pi) / 180)
end dtr
to cosalign(d, q)
if (q > 2) then
return (360 - d)
else
return d
end if
end cosalign
to sinalign(d, q)
if (d + 2.0E-14) < 0 then
if q = 4 then
return 360 + d
else # q = 3
return 180 + (-1 * d)
end if
else if q = 2 then
return (180 - d)
else
return d
end if
end sinalign
on id_quad(d)
set d to d mod 360
if d < 0 then set d to d + 360
if d ≥ 0 and d < 90 then
return 1
else if d ≥ 90 and d < 180 then
return 2
else if d ≥ 180 and d < 270 then
return 3
else if d ≥ 270 and d < 360 then
return 4
end if
end id_quad
A circle is divided into 360 degrees, which can be parted into four counter clockwise quadrants, the first from [0…90> the second from [90…180>, third from [180…270> and the fourth from [270…360>. That would be on a unity circle: a circle with a radius of 1.
It seems to me that if your argument to the last call was pi/2 or 90, and the handlers was sin pi/2, cos pi/2. or that the argument was pi, and the handlers that were fed that value was cos pi, and sin pi.
Both results would be correct, as 6.12323399573677E-17 is very equal to zero.
Think I almost have it except getting the cosine of the negative angles:
property T : missing value
set T to 3 * pi / 2
set T to T mod (2 * pi)
-- map the angle to first or fourth quadrant if needed
if (abs T) > (pi / 2) then
set T to pi - T
end if
{sin T, sin ((pi / 2) - T)} -- second result is wrong for 3*pi/2 because T is negative
I just wrote this handler, that maps a quantity to within the range of a modulus, (10,24,360,2pi, pi, etc. ), you can use that inside the call to sin, so you get a positive quantity, say in the range 0…pi.
set T to -3 * pi / 2
set m to (asin (sin mapWithinModulus(T, pi))) * 180 / pi
on mapWithinModulus(aDecNumber, aModulus)
set aDecNumber to aDecNumber mod aModulus
if aDecNumber < 0 then set aDecNumber to aDecNumber + aModulus
return aDecNumber
end mapWithinModulus
Meanwhile, I finally got the script working for sine and cosine. It probably needs some fixing up.
property T : missing value
property the_sign : 1 -- for cosine
set T to 3 * pi / 2
set T to T mod (2 * pi)
-- map to first or fourth quadrant
if T > (pi / 2) and T ≤ 3 * pi / 2 then
set the_sign to -1
set T to pi - T
end if
set cos_angle to (pi / 2) - (abs T)
{sin T, the_sign * (sin cos_angle)} -- second result is cosine of original angle
The second result is cosine of the original angle.
property T : missing value
set results_list to {}
repeat with n from 0 to 8
set the_sign to 1
set T to n * pi / 2
set T to T mod (2 * pi)
-- map to first or fourth quadrant
if T > (pi / 2) and T ≤ 3 * pi / 2 then
set the_sign to -1
set T to pi - T
end if
set cos_angle to (pi / 2) - (abs T)
set end of results_list to {sin T, the_sign * (sin cos_angle)} -- second result is cosine of original angle
end repeat
results_list
Edited: fixed bug for negative angle values less than -pi.
set results_list to {}
repeat with n from -12 to 12
set T to n * pi / 4
-- reduce the angle to < 2pi
set T to T mod (2 * pi)
if T < 0 then -- change to positive angle
set T to T + 2 * pi
end if
-- map to first or fourth quadrant with -pi/2 ≤ T ≤ pi/2
set cos_sign to 1
if T > (pi / 2) and T ≤ (3 * pi / 2) then
set cos_sign to -1
set T to pi - T
end if
set cos_angle to (pi / 2) - (abs T)
set end of results_list to {cos_sign * (sin cos_angle), sin T} -- first result is cosine of original angle
delay 0.2
--say (n as string)
end repeat
results_list
Edited the script. Something is not right with my AppleScript Editor or Satimage osax. The script hangs sometimes. Added the delay.
I have been pondering this a little, and still I find the best way, to rework expressions, so that I can use atan2 to return the result. But if you know your result is to lie within 0.180, then you can, as you know replace sin x with cos 90 -x, since cosinus, returns an ok value for the range 0…180 whereas sin returns from −90 degrees to 90 degrees, due to the 90 degrees shift in period. And of course the opposite when you know you are looking for an angle in the range −90 to 90 degrees. Otherwise, you can deduce it by looking at the sign of both sin and cos for the angle. (expensive, but never fails.)
sin = +, cos = + first quadrant.
sin = +, cos = − second quadrant
sin = -, cos = - third quadrant
sin = -, cos = + fourth qudarant.
The reason I used sine is because sine works for -pi/2 through pi/2 where it is -1 and 1 respectively and including at 0 angle. In other words it works on the y axis and positive x part of the x axis. So, sine doesn’t work riight only at pi. On the other hand cosine doesn’t work right at both -pi/2 and p/2. Hence, no matter what quadrant you choose for using cosine, it doesn’t work on at least one of the axis bordering any quadrant.
Still working on studying and incorporating your modulus script and thinking about maybe using degrees. But anyway, to use Satimage osax and many others, degrees still needs to be converted to radians.
I was rereading Wikipedias section on Trigonometry and change my mind. It is quite complete. Btw, I never heard of side-angle formulas either. To me it was always half-angle.