How to convert a X and Y Velocity to one Velocity - javascript

How would I go about converting an X and Y Velocity to one Velocity? I don't mean the angle just the velocity.
var velocityX = some velocity;
var velocityY = some velocity;
// Convert the two X and Y velocities to one velocity

Just take Math.hypot with all velocities.
newVelocity = Math.hypot(velocityX, velocityY);

Pythagoras would say
var velocity = Math.sqrt(velocityX*velocityX+velocityY*velocityX);
and he would be right.
Some other dude might add:
var angleInDegrees = Math.atan2(velocityX,velocityY)*180/Math.PI;

Once you drop the direction, then it is just speed which is a scaler, whereas velocity is a vector.
You either are better off sticking with X and Y components, or having speed and angle.
Or
You are better off calling by what it becomes, which is speed.

Related

Math to account for winner in RouletteWheel

I'm going to be honest with you all. Since high school ended and I've had a year away from school a lot of the math has been faded out. I am creating this roulettewheel for the page I'm doing at the moment and now I have to calculate the winner from where the ball stops.
The ball has a position of
x = Math.cos(alpha) * radius;
y = Math.sin(alpha) * radius;
Where each slice of the wheel is drawn as following.
var slice = {startAngle: deg2rad(deg), stopAngle: deg2rad(deg+sliceDeg), deg: deg};
ctx.arc(centerX, centerY, width/2, slice.startAngle, slice.stopAngle);
Where the slices are drawn as following
function drawAll(){
ctx.clearRect(0, 0, width, width); //Clear the canvas
for(var i=0; i < locations.length; i++){
drawSlice(deg, color[i]);
deg += sliceDeg;
}
}
So what I am basically trying to understand is how I am to check whether in which of the slices bounds the ball is when it stops. My thesis is that I have to check it as following.
If the angle of the ball(alpha) is within the angle created by slices[i].startAngle and -||-.stopAngle. Get that slice and alert this item. Where I am lost is basically when I am to compare the radians that the slice is represented with the x and y position that the ball is represented with. All help is greatly appreciated.
You can use the function Math.atan2(y, x) to convert cartesian coordinates back into radians.
For instance, Math.atan2(1, 1) yields 0.7853981633974483, which is 45 degrees.
You may need to fiddle with the signs of y and x, if the results seem wrong.
The ball angle is given by
atan2(Y - Cx, X - Cy)
in radians. If the angle is negative, add 2π to be in range [0, 2π).
Then floor(Angle / sliceRad) tells you the slice index.

Moving object from A to B smoothly across canvas

I am trying to move an object smoothly from point A to point B using HTML canvas and regular javascript.
Point A is a set of coordinates
Point B is in the case the cursor location.
I made a jsfiddle of what I have so far: https://jsfiddle.net/as9fhmw8/
while(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
ctx.save();
ctx.beginPath();
ctx.translate(projectile.x, projectile.y);
ctx.arc(0,0,5,0,2*Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.stroke();
ctx.restore();
if(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
var stepsize = (projectile.mouseX - projectile.x) / (projectile.y - projectile.mouseY);
projectile.x += (stepsize + 1);
}
if(projectile.mouseY < projectile.y)
{
var stepsize = (projectile.y - projectile.mouseY) / (projectile.mouseX - projectile.x);
projectile.y -= (stepsize + 1);
}
}
Essentially what I can't figure out to do is to make the while loop slower (so that it appears animated in stead of just going through every iteration and showing the result).
I also can't figure out how to prevent the Arc from duplicating so that it creates a line that is permanent, instead of appearing to move from point a to point b.
Smooth animation here is really about determining how far to move your object for each iteration of the loop.
There is a little math involved here, but it's not too bad.
Velocity
Velocity in your case is just the speed at which your particles travel in any given direction over a period of time. If you want your particle to travel 200px over the course of 4 seconds, then the velocity would be 50px / second.
With this information, you can easily determine how many pixels to move (animate) a particle given some arbitrary length of time.
pixels = pixelsPerSecond * seconds
This is great to know how many pixels to move, but doesn't translate into individual X and Y coordinates. That's where vectors come in.
Vectors
A vector in mathematics is a measurement of both direction and magnitude. For our purposes, it's like combining our velocity with an angle (47°).
One of the great properties of vectors is it can be broken down into it's individual X and Y components (for 2-Dimensional space).
So if we wanted to move our particle at 50px / second at a 47° angle, we could calculate a vector for that like so:
function Vector(magnitude, angle){
var angleRadians = (angle * Math.PI) / 180;
this.magnitudeX = magnitude * Math.cos(angleRadians);
this.magnitudeY = magnitude * Math.sin(angleRadians);
}
var moveVector = new Vector(50, 47);
The wonderful thing about this is that these values can simply be added to any set of X and Y coordinates to move them based on your velocity calculation.
Mouse Move Vector
Modeling your objects in this way has the added benefit of making things nice and mathematically consistent. The distance between your particle and the mouse is just another vector.
We can back calculate both the distance and angle using a little bit more math. Remember that guy Pythagoras? Turns out he was pretty smart.
function distanceAndAngleBetweenTwoPoints(x1, y1, x2, y2){
var x = x2 - x1,
y = y2 - y1;
return {
// x^2 + y^2 = r^2
distance: Math.sqrt(x * x + y * y),
// convert from radians to degrees
angle: Math.atan2(y, x) * 180 / Math.PI
}
}
var mouseCoords = getMouseCoords();
var data = distanceAndAngleBetweenTwoPoints(particle.x, particle.y, mouse.x, mouse.y);
//Spread movement out over three seconds
var velocity = data.distance / 3;
var toMouseVector = new Vector(velocity, data.angle);
Smoothly Animating
Animating your stuff around the screen in a way that isn't jerky means doing the following:
Run your animation loop as fast as possible
Determine how much time has passed since last time
Move each item based on elapsed time.
Re-paint the screen
For the animation loop, I would use the requestAnimationFrame API instead of setInterval as it will have better overall performance.
Clearing The Screen
Also when you re-paint the screen, just draw a big rectangle over the entire thing in whatever background color you want before re-drawing your items.
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
Putting It All Together
Here is a Fiddle demonstrating all these techniques: https://jsfiddle.net/jwcarroll/2r69j1ok/3/

Finding a location on cosine curve with a specified distance to another location JS

I am working on a "rally" game where a car is drawing on hills made of cosine curves. I know the current xspeed of the car (without hills) but the problem is that I need to know the xspeed of the car on the hills to be able to draw the wheels on right places and keep the speed steady.
At the moment my solution looks like this.
function drawWheelOnBasicHill(hillStart, xLocWheel, wheelNro) {
var cw = 400 //the width of the hill
t_max = 2*Math.PI;
var scale = 80, step = cw, inc = t_max/step;
var t1 = (xLocWheel-hillStart)*inc
var y1 = -scale*0.5 * Math.cos(t1);
if(wheelNro == 1 ){ //backwheel
drawRotatedImage(wheel, car.wheel1x, car.wheel1y-y1-45,sx);
//drawing the wheel on canvas
} else { //frontwheel
drawRotatedImage(wheel, car.wheel2x, car.wheel2y-y1-45,sx);
}
for(var i=1; i<=car.speed; i++){ //finding the next xlocation of the wheel with the
//same distance (on the curve) to the previous location as the speed of the car(=the
//distance to the new point on the flat ground)
var t2 = (xLocWheel + i -hillStart)*inc
var y2 = -scale*0.5 * Math.cos(t2);
if(Math.round(Math.sqrt(i^2+(y2-y1)^2))==car.speed){
sx = sx+i; //the new xcoordinate break;
}
}
}
The for loop is the problem. It might bee too slow (animation with fps 24). I cant understand why the if statement isnt working at the moment. It works sometimes but most of the times the value of the condition newer reaches the actual xspeed.
Are there some more efficient and easier ways to do this? Or does this code contain some errors? I really appreciate your efforts to solve this! Ive been looking at this piece of code the whole day..
So i is the variable and
x2=x1+i
t2=t1+i*inc
y1=-scale*0.5 * Math.cos(t1)
y2=-scale*0.5 * Math.cos(t2)
which somehow is strange. The landscape should be time independent, that is, y should be a function of x only. The time step is external, determined by the speed of the animation loop. So a more logical model would have dx as variable and
dt = t2-t1
x2 = x1 + dx
y1 = f(x1) = -0.5*scale*cos(x1)
y2 = f(x2) = -0.5*scale*cos(x2)
and you would be looking for the intersection of
(x2-x1)^2+(y2-y1)^2 = (speed*dt)^2
which simplifies to
(speed*dt)^2=dx^2+0.25*scale^2*(cos(x1+dx)-cos(x1))^2
For small values of dx, which would be the case if dt or speed*dt is small,
cos(x1+dx)-cos(x1) is approx. -sin(x1)*dx
leading to
dx = (speed*dt) / sqrt( 1+0.25*scale^2*sin(x1)^2 )
To get closer to the intersection of curve and circle, you can then iterate the fixed point equation
dydx = 0.5*scale*(cos(x1+dx)-cos(x1))/dx
dx = (speed*dt) / ( 1+dydx^2 )
a small number of times.

Determine movement vector's direction from velocity

I'm kinda confused with this one.
I have an object and I know it's velocities on axis x and y. My problem is how to determine the angle at which it's moving.
function Object(){
this.velocity = {x: 5, y: 1};
}
Basically I Know that a vector's direction is x_projectioncos(deg) + y_projectionsin(deg), but I don't know how to get those projections since I only have the velocity, as I said I'm really confused.
#EDIT:
in addition to the accepted answer, here's what I did to get a full 360 degree spectrum
var addDeg = 0;
if(obj.velocity.x<0)
addDeg = obj.velocity.y>=0 ? 180 : 270;
else if(obj.velocity.y<=0) addDeg = 360;
deg = Math.abs(Math.abs(Math.atan(obj.velocity.y/obj.velocity.x)*180/Math.PI)-addDeg)
I don't know how to get those projections since I only have the
velocity
Actually, what you seem to be missing is that you already have the projections. That's what x and y are.
x is speed * cos(angle)
y is speed * sin(angle)
So y/x = sin(angle)/cos(angle) which is tan(angle) so angle=arctan(y/x).
That's the angle rotating anti-clockwise starting from the x axis (with x pointing right and y pointing up).
Find the angle between that vector and (1,0) (Right horizontal positive direction).
The math is:
A = (5,1)
B = (1,0)
A.B = |A||B|cos(angle) -> angle = arccos((|A||B|)/(A.B))
Dot product, check geometric definition
Edit:
Another option is to use the cross product formula:
|AxB| = |A||B|sin(angle) -> angle = arcsin((|A||B|)/(|AxB|))
It will give you the angle you need.
There is an easier way to get full 360 degrees. What you're looking for, is Math.atan2:
deg = Math.atan2(obj.velocity.y,obj.velocity.x)*180/Math.PI;

How to change an objects x and y coordinates by degrees?

I'm working on some coordinates function to my canvas in HTML5, and I want to make a function which can move an object by degrees.
My dream is to make a function which works like this:
box.x=10;
box.y=10;
// now the box has the coordinates (10,10)
moveTheBoxWithThisAmountOfDistance=10;
degreesToMoveTheBox=90;
box.moveByDegrees(moveTheBoxWithThisAmountOfDistance,degreesToMoveTheBox);
// now the box.x would be 20 and box.y wouldn't be changed because
// we only move it to the right (directional 90 degrees)
I hope this makes any sense!
So my question is:
How does the mathematical expression look like when I have to turn a degree into to coordinates?
You use sin and cos to convert an angle and a distance into coordinates:
function moveByDegrees(distance, angle) {
var rad = angle * Math.pi / 180;
this.x += Math.cos(rad) * distance;
this.y += Math.sin(rad) * distance;
}
That's it: http://en.wikipedia.org/wiki/Rotation_matrix , all the math is described :)
Also beware that if you need multiple sequential rotations (i.e. you do continuous animation), it's better to recompute x' and y' from initial ones and not just previous. Not doing so will result in rounding errors accumulation, and after some thousand rotations the result will become too rough.

Categories