How does Math.tan(x) actually work? (Javascript) [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I'm trying to understand the math behind the Math.tan method but it doesn't make any sense. Can someone please explain to me how it works?
Firstly the mathematical formula to solve for a tangent angle is Tangent = Opposite/Adjacent. Which means I need to know two sides of the triangle to figure out the tangent angle. However the Math.tan method only accept a single argument in radians, not the length of two sides, so I don't understand how it's figuring out the angle of the tangent.
Next in examples they show passing impossibly huge radian values into the method and getting back a value. For example, W3 schools shows the example of Math.tan(90) but 90 radians equals 5,156.6 degrees which is an impossible angle for a corner of a right triangle.
How does this method work, what's happening behind the scenes that turns 90 radians into a tangent angle of -1.995200412208242

First let's talk about what a tangent is: Tangent is y/x for the coordinate at a specific point (see this YouTube video for an example).
So if you want the tangent of pi over 2, on a graph, that's at a 90 degree angle, so the coordinate is (0, 1). Then you just divide 1/0.
However, Math.tan isn't very precise. In Chrome 52, Math.tan(Math.PI / 2) (from the video above) is 16331239353195370, even though it should evaluate to the Infinity value in JavaScript (the mathematical value is actually undefined since it works out to 1/0).
According to this answer, the V8 implementation is:
function MathTan(x) {
return MathSin(x) / MathCos(x);
}
(As a side note: The value that Chrome actually outputs is larger than Number.MAX_SAFE_INTEGER, which you can prove by running Number.MAX_SAFE_INTEGER < Math.tan(Math.PI / 2) // => true, so Chrome takes it to be "close to infinity".)
Edit
The reason for the lack of a precise value is that pi is generally represented as a fixed value (since we have limitations in computer memory), even though it should be "Infinity" or "undefined" outside of the context of programming. For example, in my browser, Math.PI is fixed at 3.141592653589793.

Related

Animating along a curve using Javascript & simple math

I feel like the solution is very simple, but in all honestly I failed math multiple times in high school, so I'm barely grasping even the basic concepts right now.
The idea is very simple.. I want to have a bunch of graphical objects tween animate from one side of a 300x300px div to the other side along randomized curved paths as if they were being tossed or dropped from the top left to the bottom right (and vice versa, back and forth).
I know I need to use some form of Trigonometry to solve this (sin, cos, tan??). I also already know how to get my two points (randomizing Y points, and then randomly putting x points on the positive or negative side of the 300px width). But the part where I have to actually calculate steps along a curve is beyond me.
Here's a crappy diagram of basically what I'm attempting.. I searched Google but all of the examples were way overcomplicated or too abstract. I just want to learn how to make a curve between two points.. That's it!
So simple question: How do I randomize a curved animation (or plot points along a curve) between two points using vanilla JavaScript (no JQuery please).
First of all, if you would like a quick look into the math of JavaScript animations , you might consider visiting this link
Actually, you only need very simple trigonometry (sine and cosine). If you are tossing something from a point (X0, Y0), the equations of motion are more like a parabolic trajectory.
From Wikipedia:
Displacement and coordinates of parabolic throwing
At any time t, the projectile's horizontal and vertical displacement
are:
x = X0 + v0 * t * cos(theta)
y = Y0 + v0 * t * sin(theta) − 0.5 * g * t * t
So there you go, your coordinates in pixels for every t time step.
You may define theta and v0 as constants or also as random values to make the animation more chaotic and lively.
Play with the value of g (in Earth it is 9.8 m/s²), because probably when scaling to pixels/s² it might overshoot.
Also you may want to give negative values to X0 and Y0 in order to intercept the descending part of the trajectories, leaving the ascending out of the div.

JavaScript math gives completely wrong results

I have an assignment to make a program that can calculate the area beneath a graph in a certain area.
My function is f(x)=3+(tan(x))^2
I have turned this into javascript so it looks like this:
var y = 3 + Math.pow(Math.tan((x)*(180/Math.PI)), 2)
This is giving the right result at certain x-values. But sometimes, eg. at x = 3.4, it gives a strange number like 16 where I expected something around 3 or 4.
I have read that it can be caused by the problem with floating point behavior, but it should not give that big a difference? I don't understand it. :(
I use a for loop to change the x value and and array to store the values.
x*180/π converts an angle x, given in radians, into degrees. But that's almost certainly wrong here: The JavaScript trigonometric functions expect their arguments in radians. So if your angle is in radians, you don't need any conversion at all, and if it is in degrees, you should convert the other way round, namely x*π/180.

radians sometimes flipped/reversed

I have a function which should be finding the middle of two radians
function mrad(rb,ra){return (rb+ra)/2;}
But sometimes when I plot the x and y with Math.sin and Math.cos the two a specified length the new coordinates are coming out at the polar opposites of what I intend.
for example; If I expect the new points to be down and to the right sometimes they are coming out as up and to the left. The coordinates are correct apart from this!
Here is how I plot the new x and y
xnew=xold-(100)*Math.cos(radian);
xnew=yold+(100)*Math.sin(radian);
I am guessing that it might matter if radian B (rb) is bigger than ra. I think what is happening is that I am going full circle in this case, whereas I sometimes should be instead doing something like
function mrad(rb,ra){return (rb-ra)/2;}
My questions are
Is my assumption correct?
What would be the condition, how to tell when to do rb-ra vs rb+ra, or to put it better, how do you tell if one radian is pointing above or bellow the other?
It should look something like this
function mrad(rb,ra){return ((/*condition*/)?(rb-ra):(rb-ra))/2;}
Edit
To find the range I have tried to express different values to find a range in radians but cannot find anything more than a diagonal line
http://jsfiddle.net/roLLqfs6/
Also the defined length is not always 100 as it is written in the example
It's really a maths question. You need to make sure that your angles are in the same range (either -pi ... pi or 0 ... 2.0 * pi), but even then, taking the mean of them will not necessarily find the angle you are looking for - you might expect that (in degrees, for simplicity) the answer you want for 10º & 20º would be 15º, but what would you expect for 175º and -175º? I suspect you would want 180º (as this is the minor arc between them), but you will get 0º.
So, you need to test the difference, to see that they are less than 180º (pi radians) apart, and modify the answer accordingly if they are not.

solving a trig equation numerically with in-browser JS [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Given values for the variables s, v, and h, and given a library such as numeric.js how can I numerically solve the following equation for a within a given degree of accuracy?
I'm wanting a JS algorithm for use in-browser.
Separating variables and parameters
You could start by substituting b = a/h. That would turn your equation into
2b*sinh(1/(2b)) = sqrt(s²-v²)/h
That way you have all the inputs on the right hand side, and the variable on the left hand side, but unfortunately still occuring in several places in a transcendental form. The benefit is that we can now treat the right-hand side as a single number in order to gain some understanding of this function.
First look at a plot
The function seems reasonably well-behaved:
So you can do standard numerical root-finding methods, e.g. Newton's method, to find the position where this function takes a given value (i.e. the one you computed from the right-hand side). If you interpret root-finding as finding locations where a function is zero, then the function for which you want to find zeros is the difference, i.e.
2a*sinh(h/(2a)) - sqrt(s²-v²)
Using optimization from numeric.js
If you want to make use of numeric.js, numeric.uncmin would likely be your best bet. At least it's the best I could find in the docs so far. (Perhaps there is some bare root-finding implementation in there, but if so, I couldn't find it yet.) You'd try to find the minimum of the function
(2a*sinh(h/(2a)) - sqrt(s²-v²))²
interpreted as a function of a, and hope that that minimum is actually (close to) zero. You might get better results (i.e. faster convergence and/or lower error) by also providing the gradient (derivative) of that function as a separate argument. You can use Wolfram Alpha to find that derivative.
Further rewriting of the function
Let's define f as f(b) = 2b*sinh(1/(2b)). You are trying to find out at what position f assumes a given value. In order to make convergence faster, you can try to turn this f into a different function which will be close to linear. Toying around with plots, I've come up with this:
g(b) = (f(b) - 1)^(-1/2)
You can apply the same conversion to the right hand side to see the desired value for this function. For b > 0.06 this looks fairly linear, so it should converge really fast. Provided your parameters are expected to be in that range where it is almost linear, but even for smaller b it should be no worse than the original formulation. You could use the linear form to compute the starting position of your Newton's method, but I wouldn't bother: as long as you start with a reasonably big value, the first step of Newton's method will do just that.
this is transcendent equation
I assume real domain in that case you can not separate the unknown from it (in general) instead you still can solve it numerically (as you intended)
I am too lazy to do proper analysis of 2a.sinh(h/2a)=sqrt(s.s-v.v)
but if I see it right then 2a.sinh(h/2a) is monotone so let c=sqrt(s.s-v.v) for simplicity and speed up. As I see it c >= 0 so if h >= 0 then a = <0,+inf)
find value crossing
double a0,a1,da=initial accuracy step;
for (a1=0.0;2a.sinh(h/2a)<=sqrt(s.s-v.v);a1+=da);
now a1 holds approximate top bound solution
for (a0=a1;2a.sinh(h/2a)>sqrt(s.s-v.v);a0-=da);
now a0 holds approximate low bound solution
find solution in desired accuracy
if a0==a1 then you have found exact solution so stop
if fabs(a1-a0)<=accuracy you are inside your accuracy so stop and lower the da for example da*=0.01; this will boost accuracy 100 times. Now search for solution again but only on interval <a0,a1> and repeat this until solution is found
[notes]
Another example of solution of transcendent equation is here: solving Kepler`s equation. When nothing else works you still can try this:
How approximation search works

2d parabolic projectile

I'm looking to create a basic Javascript implementation of a projectile that follows a parabolic arc (or something close to one) to arrive at a specific point. I'm not particularly well versed when it comes to complex mathematics and have spent days reading material on the problem. Unfortunately, seeing mathematical solutions is fairly useless to me. I'm ideally looking for pseudo code (or even existing example code) to try to get my head around it. Everything I find seems to only offer partial solutions to the problem.
In practical terms, I'm looking to simulate the flight of an arrow from one location (the location of the bow) to another. I have already simulated the effects of gravity on my projectile by updating its velocity at each logic interval. What I'm now looking to figure out is exactly how I figure out the correct trajectory/angle to fire my arrow at in order to reach my target in the shortest time possible.
Any help would be greatly appreciated.
Pointy's answer is a good summary of how to simulate the movement of an object given an initial trajectory (where a trajectory is considered to be a direction, and a speed, or in combination a vector).
However you've said in the question (if I've read you correctly) that you want to determine the initial trajectory knowing only the point of origin O and the intended point of target P.
The bad news is that in practise for any particular P there's an infinite number of parabolic trajectories that will get you there from O. The angle and speed are interdependent.
If we translate everything so that O is at the origin (i.e. [0, 0]) then:
T_x = P_x - O_x // the X distance to travel
T_y = P_y - O_y // the Y distance to travel
s_x = speed * cos(angle) // the X speed
s_y = speed * sin(angle) // the Y speed
Then the position (x, y) at any point in time (t) is:
x = s_x * t
y = s_y * t - 0.5 * g * (t ^ 2)
so at impact you've got
T_x = s_x * t
T_y = -0.5 * g * (t ^ 2) + s_y * t
but you have three unknowns (t, s_x and s_y) and two simultaneous equations. If you fix one of those, that should be sufficient to solve the equations.
FWIW, fixing s_x or s_y is equivalent to fixing either speed or angle, that bit is just simple trigonometry.
Some combinations are of course impossible - if the speed is too low or the angle too high the projectile will hit the ground before reaching the target.
NB: this assumes that position is evaluated continuously. It doesn't quite match what happens when time passes in discrete increments, per Pointy's answer and your own description of how you're simulating motion. If you recalculate the position sufficiently frequently (i.e. 10s of times per second) it should be sufficiently accurate, though.
I'm not a physicist so all I can do is tell you an approach based on really simple process.
Your "arrow" has an "x" and "y" coordinate, and "vx" and "vy" velocities. The initial position of the arrow is the initial "x" and "y". The initial "vx" is the horizontal speed of the arrow, and the initial "vy" is the vertical speed (well velocity really but those are just words). The values of those two, conceptually, depend on the angle your bowman will use when shooting the arrow off.
You're going to be simulating the progression of time with discrete computations at discrete time intervals. You don't have to worry about the equations for "smooth" trajectory arcs. Thus, you'll run a timer and compute updated positions every 100 milliseconds (or whatever interval you want).
At each time interval, you're going to add "vx" to "x" and "vy" to "y". (Thus, note that the initial choice of "vx" and "vy" is bound up with your choice of time interval.) You'll also update "vx" and "vy" to reflect the effect of gravity and (if you feel like it) wind. If "vx" doesn't change, you're basically simulating shooting an arrow on the moon :-) But "vy" will change because of gravity. That change should be a constant amount subtracted on each time interval. Call that "delta vy", and you'll have to tinker with things to get the values right based on the effect you want. (Math-wise, "vy" is like the "y" component of the first derivative, and the "delta vy" value is the second derivative.)
Because you're adding a small amount to "vy" every time, the incremental change will add up, correctly simulating "gravity's rainbow" as your arrow moves across the screen.
Now a nuance you'll need to work out is the sign of "vy". The initial sign of "vy" should be the opposite of "delta vy". Which should be positive and which should be negative depends on how the coordinate grid relates to the screen.
edit — See #Alnitak's answer for something actually germane to your question.

Categories