i created a program in javascript that computes vector coordinates, everything was smooth since i have the correct formula, but when i try to conpute for the cosine of 143.1301 using Math.cos in javascript it returns 0.1864 instead of 0.7999 from the scientific calculator why is that? can anyone explain to me why? and also please give me the solution for this problem... thanks in advance... :) here;s a sample of my code
function cyltoxec(a)
{
ans = Math.cos(a);
return ans.toFixed(4);
}
var = x;
return cyltoxec(x);
Trigonometric functions in JavaScript (and indeed, in most mathematical parlance and programming) use radians as the angular unit, not degrees.
There are 2 * Pi radians in 360 Degrees. Thus, the cosine of a degrees is
Math.cos(a * Math.PI/180)
Math.cos expects its argument to be in radians, not degrees. Try Math.cos(a * Math.PI/180) instead.
Related
I originally wanted to use four points (as a bezier Curve is defined with 4 points), but that forces me to brute force the position, so I tried a different approach i now need help with:
I have a start point P0, an end point P1 and slopes m0 and m1 which are supposed to give me the start/end slope to calculate a Bezier Curve inbetween them.
The Curve is supposed to be in the form of a function (3rd degree), since I need to get the height y of a given point x.
Using the HTML5Canvas i can draw a bezier curve no problem and using this function
that allows me to calculate any given point given a percentage of the way i can get the center point of the curve. But I don't need it depending on t but rather the y depending on x, so not halfway of the curve but halfway of the x distance between P0 and P1.
Image to visualize:
Left is what i can calculate, right is what i need.
I've been trying to calculate the cubic function given the two points P0, P1 as well as the slopes m0, m1, which results into four equations which i can't seem to be able to solve with only variable inputs. I've also tried to use the above function to calculate the t using the x value (which is known), but no dice there either.
I need to avoid using approximations or costly loops for these calculations as they are performed many times a second for many objects, thus this answer is not feasible for me.
Any help is appreciated.
I've encountered the same problem in a project I'm working on. I don't know of a formula to get the y coordinate from the x, and I suspect you'll have trouble with that route because a bezier curve can have up to 3 points that all have the same x value.
I would recommend using the library BezierEasing, which was designed for this use case and uses various performance enhancing techniques to make lookups as fast as possible: https://github.com/gre/bezier-easing
To solve this problem, you need to rewrite Bezier equation in power polynomial form
X(t) = t^3 * (P3.X-3*P2.X+3*P1.X-P0.X) +
t^2 * (3*P0.X + 6*P1.X+3*P2.X) +
t * (3*P1.X - 3P2.X) +
P0.X
if X(t) = P0.X*(1-ratio) + P3.X*ratio
then
let d = ratio * (P0.X - P3.X)
and solve cubic equation for unknown t
a*t^3 + b*t^2 + c*t + d = 0
JS code here
Then apply calculated t parameter (there might be upto three solutions) to Y-component and get point coordinates. Note that formulas are close (no loops) and should work fast enough
Thank you to everyone that answered before, those are generally great solutions.
In my case I can be 100% sure that I can convert the curve into a cubic function, which serves as the approximation of the bezier curve using the result of this calculation.
Since i have control over my points in my case, I can force the P0 to be on x=0, which simplifies the linear system calculations and thus allows me to calculate the cubic function much easier like this:
let startPoint: Utils.Vector2 = new Utils.Vector2(0, 100);
let endPoint: Utils.Vector2 = new Utils.Vector2(100, 100);
let a: number, b: number, c: number, d: number;
function calculateFunction() {
let m0: number = 0;
let m1: number = 0;
a = (-endPoint.x * (m0 + m1) - 2 * startPoint.y + 2 * endPoint.y) / -Math.pow(endPoint.x, 3);
b = (m1 - m0 - 3 * a * Math.pow(endPoint.x, 2)) / (2 * endPoint.x);
c = m0;
d = startPoint.y;
}
I'm trying to get this calculation done in javascript using Big.js
r = (a * b)/ sqrt( ( a*sin(θ) )^2 + ( b*cos(θ) )^2 )
I've also tried math.js and have the same result.
You can see the discrepancies in Wolfram and Google calculations, as google is using javascript.
Wolfram [=40] vs Google [=43.4008369271]
I've done this jsfiddle where you can see it working:
http://jsfiddle.net/herkulano/k1h5d4zk/
How do you solve it?
The difference stems from the fact that javascript by default uses radians and in your example, Wolfram is defaulting to degrees. You can convert degrees to radians with a function like this.
function degToRad(deg){
return deg*(Math.PI/180)
}
I have been making a mod for a game called Minecraft PE and I'm using it to learn. Before I show my code I want you to know that Y is the vertical axis and X and Z is horizontal. Here is some code I used:
Math.asin(Math.sin((fPosXBeforeMoved - sPosX) /
Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) +
Math.pow(fPosZBeforeMoved - sPosZ, 2))));
I didn't use tan because sometimes it returns something like NaN at a certain angle. This code gives us the sine of the angle when I clearly used Math.asin. angle is a value between -1 and 1, and it works! I know it works, because when I go past the Z axis I was expecting and it did switch from negative to positive. However, I thought it's supposed to return radians? I read somewhere that the input is radians, but my input is not radians. I really want the answer to how my own code works and how I should have done it! I spent all day learning about trigonometry, but I'm really frustrated so now I ask the question from where I get all my answers from!
Can someone please explain how my own code works and how I should modify it to get the angle in radians? Is what I've done right? Am I actually giving it radians and just turned it into some sort of sine degrees type thing?
OK, let's give a quick refresher as to what sin and asin are. Take a look at this right-angle triangle in the diagram below:
Source: Wikipedia
By taking a look at point A of this right-angle triangle, we see that there is an angle formed between the line segment AC and AB. The relationship between this angle and sin is that sin is the ratio of the length of the opposite side over the hypotenuse. In other words:
sin A = opposite / hypotenuse = a / h
This means that if we took a / h, this is equal to the sin of the angle located at A. As such, to find the actual angle, we would need to apply the inverse sine operator on both sides of this equation. As such:
A = asin(a / h)
For example, if a = 1 and h = 2 in our triangle, the sine of the angle that this right triangle makes between AC and AB is:
sin A = 1 / 2
To find the actual angle that is here, we do:
A = asin(1 / 2)
Putting this in your calculator, we get 30 degrees. Radians are another way of representing angle, where the following relationship holds:
angle_in_radians = (angle_in_degrees) * (Math.PI / 180.0)
I'm actually a bit confused with your code, because you are doing asin and then sin after. A property between asin and sin is:
arcsin is the same as asin. The above equation states that as long as x >= -Math.PI / 2, x <= Math.PI / 2 or x >= -90, x <= 90 degrees, then this relationship holds. In your code, the argument inside the sin will definitely be between -1 to 1, and so this actually simplifies to:
(fPosXBeforeMoved - sPosX) / Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) +
Math.pow(fPosZBeforeMoved - sPosZ, 2));
If you want to find the angle between the points that are moved, then you're not using the right sides of the triangle. I'll cover this more later.
Alright, so how does this relate to your question? Take a look at the equation that you have in your code. We have four points we need to take a look at:
fPosXBeforeMoved - The X position of your point before we moved
sPosX - The X position of your point after we moved
fPosZBeforeMoved - The Z position of your point before we moved
sPosZ - The Z position of your point after we moved.
We can actually represent this in a right-angle triangle like so (excuse the bad diagram):
We can represent the point before you moved as (fPosXBeforeMoved,fPosZBeforeMoved) on the XZ plane, and the point (sPosX,sPosZ) is when you moved after. In this diagram X would be the horizontal component, while Z would be the vertical component. Imagine that you are holding a picture up in front of you. X would be the axis going from left to right, Z would be the axis going up and down and Y would be the axis coming out towards you and going inside the picture.
We can find the length of the adjacent (AC) segment by taking the difference between the X co-ordinates and the length of the opposite (AB) segment by taking the difference between the Z co-ordinates. All we need left is to find the length of the hypotenuse (h). If you recall from school, this is simply done by using the Pythagorean theorem:
h^2 = a^2 + b^2
h = sqrt(a^2 + b^2)
Therefore, if you refer to the diagram, our hypotenuse is thus (in JavaScript):
Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) + Math.pow(fPosZBeforeMoved - sPosZ, 2));
You'll recognize this as part of your code. We covered sin, but let's take a look at cos. cos is the ratio of the length of the adjacent side over the hypotenuse. In other words:
cos A = adjacent / hypotenuse = b / h
This explains this part:
(sPosX - fPosXBeforeMoved) / Math.sqrt(Math.pow(sPosX - fPosXBeforeMoved, 2) +
Math.pow(sPosZ - fPosZBeforeMoved, 2));
Take note that I swapped the subtraction of sPosX and fPosXBeforeMoved in comparison to what you had in your code from before. The reason why is because when you are examining the point before and the point after, the point after always comes first, then the point before comes second. In the bottom when you're calculating the hypotenuse, this doesn't matter because no matter which order the values are subtracted from, we take the square of the subtraction, so you will get the same number anyway regardless of the order. I decided to swap the orders here in the hypotenuse in order to be consistent. The order does matter at the top, as the value being positive or negative when you're subtracting will make a difference when you're finding the angle in the end.
Note that this division will always be between -1 to 1 so we can certainly use the inverse trigonometric functions here. Finally, if you want to find the angle, you would apply the inverse cosine. In other words:
Math.acos((sPosX - fPosXBeforeMoved) / Math.sqrt(Math.pow(sPosX - fPosXBeforeMoved, 2)
+ Math.pow(sPosZ - fPosZBeforeMoved, 2)));
This is what I believe you should be programming. Take note that this will return the angle in radians. If you'd like this in degrees, then use the equation that I showed you above, but re-arrange it so that you are solving for degrees instead of radians. As such:
angle_in_degrees = angle_in_radians * (180.0 / Math.PI)
As for what you have now, I suspect that you are simply measuring the ratio of the adjacent and the hypotenuse, which is totally fine if you want to detect where you are crossing over each axis. If you want to find the actual angle, I would use the above code instead.
Good luck and have fun!
Suppose I have a circle with a center point at origin (0,0) and a 90deg point from it at (0,10)... from this 2 obvious points the radius of the circle would definitely be 10, right?
I researched that the formula of finding the radius based on center point and another point is:
Math.sqrt( ((x1-x2)*2) + ((y1-y2)*2) )
but I'm getting a value of 4.47213595499958 instead of what I thought would be 10.
Can anyone teach me the correct formula I should use to make a perfect circle from a center point to another point?
Power in javascript is done by using Math.pow:
Math.sqrt( Math.pow((x1-x2), 2) + Math.pow((y1-y2), 2) )
In javascript, the * operator means multiply, not raise to the power. The correct formula should be:
Math.sqrt( ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) )
Using the equation of circle I have
x = rCos(theta)
y = rSin(theta)
Now I want to calculate theta. I have
x = -87.91
r = 14.63
what will be the value of theta? using
Math.acos(x/r)
its giving me NaN...
From MDN
The acos method returns a numeric value between 0 and pi radians for
x between -1 and 1. If the value of number is outside this range, it
returns NaN.
You need to get it within the range.
If you have x = -87.91, than r >= 87.91, so you have something wrong.
The best method in such situations is usually theta = Math.atan2(y, x) http://en.wikipedia.org/wiki/Atan2
sine and cosine don't have true inverses unless you restrict their range. So the acos and asin methods are only defined over these restricted ranges (which become the domains of asin and acos).
You have to ensure that theta is a value in radians, and that sentiment has been echoed thoroughly. If you don't want to convert values before you enter them, then you can use a conversion formula while calculating x and y.
x = rCos(theta * (3.14/180))
y = rSin(theta * (3.14/180))