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.
Related
I want to transform an image in 2 points perspective.
I guess I need to transfer to JS a formula from: http://web.iitd.ac.in/~hegde/cad/lecture/L9_persproj.pdf
But I'm humanities-minded person and I faint when I see matrices.
Here's what I need exactly:
I have a two vanishing points: X(X.x, X.y) and Z(Z.x, Z.y). And rectangle ABCD (A.x, A.y and so on)
(source: take.ms)
And I want to find new nA, nB, nC and nD points with which I can transform my rectangle like that (the points order doesn't really matter):
(source: take.ms)
Right now I'm doing weird approximate calculations: I'm looking for most distant point from X (1), then lay over an interval towards Z (2), than another interval towards X (3) and then again from Z (4):
(source: take.ms)
The result is a bit off but is alright for the precision I need, but this algorithm sometimes gives very weird results if I change vanishing points, so if there's a proper solution I'll gladly use it. Thanks!
I need to find the speed of an object in a game. The game is made in HTML5 with jquery and jquery.box2d.
For this I can use these methods:
GetLinearVelocity().x;
GetLinearVelocity().y;
I'm then trying to calculate the speed from this piece of code, but get some values that doesn't make sense when I console.log it. This is my code:
var heroVelX = game.currentHero.GetLinearVelocity().x;
var heroVelY = game.currentHero.GetLinearVelocity().y;
var speed = Math.sqrt(heroVelX^2 + heroVelY^2);
console.log(speed);
Some of the values in console.log are numbers, but most of them are NaN (Not-A-Number), which confuses me? Can someone help me solve this?
The goal I want to achieve, is to see when the speed(of object .currenHero) drop below a certain value, so I can excute a new state in the game.
Your problem is that you're using the wrong operator (Bitwise XOR) for doing square - see here.
What you need to do is:
var speed = Math.sqrt(Math.pow(heroVelX, 2) + Math.pow(heroVelY, 2));
The only time the square root function should return NaN is when the value being square rooted is negative. A way to go about testing if this is the issue would be to try squaring the values in a different line of code before square rooting them.
heroVelX = (heroVelX) * (heroVelX)
Another way to potentially shine some light on the problem would be to add log statements printing out the values of the velocities and the velocities squared before square rooting.
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.
I'm translating some c++ code in relation to PMP for attitude controls and part of the code uses FLT_EPSILON.
The code does the following:
while (angle > ((float)M_PI+FLT_EPSILON))
M_PI is simple but I'm not sure what to with FLT_EPSILON. A google has told me:
This is the difference between 1 and the smallest floating point
number of type float that is greater than 1. It's supposed to be no
greater than 1E-5.
However other sources state values like 1.192092896e-07F.
I'm not 100% clear on why it's being used. I suspect it's to do with the granuality of float. So if someone could clarify what it is attempting to do in c++ and if this is a concern for javascript then that would be very helpful.
I'm not sure how javascript goes about handling internally stuff like these values so help would be appreciated.
As an FYI, the code I'm translating is as follows (sourced from QGroundControl, it's open source):
float limitAngleToPMPIf(float angle) {
if (angle > -20*M_PI && angle < 20 * M_PI) {
while (angle > ((float)M_PI + FLT_EPSILON)) {
angle -= 2.0f * (float)M_PI;
}
while (angle <= -((float)M_PI + FLT_EPSILON)) {
angle += 2.0f * (float)M_PI;
}
} else {
// Approximate
angle = fmodf(angle, (float)M_PI);
}
return angle;
}
--- edit ---
Just realised that fmodf isn't defined. Apparently it's a lib function and does the following:
The fmod() function computes the floating-point remainder of dividing
x by y. The return value is x - n * y, where n is the quotient of x /
y, rounded toward zero to an integer.
This code is attempting to keep angle within an interval around zero.
However, managing angles in this way is troublesome and requires considerable care. If it is not accompanied by documentation explaining what is being done, why, and the various errors and specifications that are involved, then it was done improperly.
It is impossible for this sort of angle reduction to keep accumulated changes accurately over a long sequence of changes, because M_PI is only an approximation to π. Therefore, this sort of reduction is generally only useful for aesthetic or interface effect. E.g., as some angle changes, reducing it can keep it from growing to a point where there may be large jumps in calculation results due to floating-point quantization or other calculation errors that would be annoying to a viewer. Thus, keeping the angle within an interval around zero makes the display look good, even though it diverges from what real physics would do over the long term.
The choice of FLT_EPSILON appears to be arbitrary. FLT_EPSILON is important for its representation of the fineness of the float format. However, at the magnitude of M_PI, the ULP (finest change) of a float is actually 2*FLT_EPSILON. Additionally, JavaScript performs the addition with double-precision arithmetic, and FLT_EPSILON is of no particular significance in this double format. I suspect the author simply chose FLT_EPSILON because it was a convenient “small” number. I expect the code would work just as well as if angle > M_PI had been written, without the embellishment, and (float) M_PI were changed to M_PI everywhere it appears. (The addition of FLT_EPSILON may have been intended to add some hysteresis to the system, so that it did not frequently toggle between values near π and values near –π. However, the criterion I suggest, angle > M_PI, also includes some of the same effect, albeit a smaller amount. That might not be apparent to somebody inexperienced with floating-point arithmetic.)
Also, it looks like angle = fmodf(angle, (float) M_PI); may be a bug, since this is reducing modulo M_PI rather than 2*M_PI, so it will add 180º to some angles, producing a completely incorrect result.
It is possible that replacing the entire function body with return fmod(angle, 2*M_PI); would work satisfactorily.
Basically, I'm trying to do 3D projection on a 2D canvas with simulation of depth. As a general rule, bodies that are further away are "shaded" more and smaller than bodies that are closer to the viewer. The only thing missing is having bodies that are further away always drawn behind bodies that are closer.
Sometimes, bodies that are further away are drawn behind closer bodies, but there are always small bodies that get drawn in front of larger ones, meaning that the ones that are further away sometimes appear in front of bodies that are supposed to be closer.
I try to solve it by sorting the bodies by the z-position. The bodies array is an array of objects with 0 containing an array of the body's position, 0 being x, 1 being y, 2 being z. I first have the position of the bodies updated according to rotations in the x, y, and z axes, stored into the np value of the body object, then do the sorting, and draw the bodies. I've tried changing how the array is sorted, changing the order of the loop, but still no cigar.
Just wondering if anyone can point me in the right direction to get this 3D "engine" behaving correctly. Any help is appreciated. Some quick notes: Rotations along the three axes are accomplished using the Q/A, W/S, and E/D keys, zooming in and out of the z-axis is accomplished using the R/F keys, and the default rotation about the z-axis can be accomplished using the P key. What I'm trying to do is located here:
http://jsbin.com/aholu/5/
You're sorting on the original xyz values instead of the transformed np values. I got it to look right by switching...
bodies.sort(function(a,b) {return a[0][2]-b[0][2]});
to
bodies.sort(function(a,b) {return a.np[1]-b.np[1]});
with change see http://home.comcast.net/~trochoid/mod5.html
I don't follow all of your code so this may not be a total solution. Specifically, I thought it'd be sorted on np[2] for the transformed z value, but np[1] gives correct looking results. I guess maybe you switch these coords. Also, it looks like you're transforming and projecting the z value and the code fix above sorts on this projected z value. It seems to work out ok but I've never projected the z value itself, just use the transformed z to project xy. Anyways, Looks good!
Trochoid. I had to access from a different computer and still haven't registered, so I have to add this as an answer instead of a comment.
If you notice, the axis of rotation for x and y are rotated when you rotate any other axis (eg. if you press W to rotate, then rotate a different axis, then press W again, you will notice that the helix in your code rotates the same way). T
his is not so with the z axis. No matter how you rotate the x and y axes, the z axis will always rotate "right-to-left" (eg. in default configuration, helix is spiraling along z-axis, or axis rotated using the E/D keys, but if you rotate the helix along any other axis, rotating using the E/D keys no longer spirals the helix).
I don't know why the behavior would be different in that axis, so I would like your assistance to get that rotation working properly. Thank you.
I am aware that this is not answering the original question, but depending on what you are trying to acchieve in general be aware that there is also 'parallax scrolling' (example) (esp. in CSS3 (example).