How can I refer to the previous element in an array?
I want to calculate the angular distance of 2 coordinates so that I can move a steering wheel.
My data comes from a robot.
let arrX = [];
let arrY = [];
tag5617.subscribe(function(message) {
let X = document.getElementById('posX');
X.innerHTML = message.x.toFixed(2);
let Y = document.getElementById('posY');
Y.innerHTML = message.y.toFixed(2);
myChart.data.datasets[0].data.push({x:message.x.toFixed(2), y:message.y.toFixed(2)});
arrX.push(message.x);
arrY.push(message.y);
let deg = Math.atan2(message.x - arrX[-1], message.y - arrY[-1]) * 180 / Math.PI;
myChart.update();
});
After you push a new element onto an array, the element before it is the 2nd to last element.
Unlike some other languages (e.g. Python) there's no shorthand syntax to index from the end of an array. So you have to calculate the index by subtracting from array.length.
let deg = Math.atan2(message.x - arrX[arrX.length-2], message.y - arrY[arrY.length-2]) * 180 / Math.PI;
Related
I am automating mouse movement using Jmgr's Actiona and need to create a method that moves the mouse from one point (x, y) to another in a very uniform way.
Actiona supports the creation of custom JavaScript functions, which is what I am using to achieve this. My idea is to set the mouse position by iterating through an array of points, with a short delay between each new position set. I have this portion worked out already.
This is my code for positioning the mouse (Mouse and Execution are part of Actiona):
var mouse = new Mouse();
for (var i = 0; i < pointList.length; i++) {
Execution.pause(30); //pause for 30ms
mouse.move(pointList[i]); //move() sets the mouse to a new x, y position
}
I want a JavaScript function which will return an array of points between a starting and ending point, where the distance between each point is always the same. I.e., always move N distance each step taken regardless of the distance between startPos and endPos.
It could look like this: getPoints(startPos, endPos, stepDistance)
I realize that with these constraints there is a good chance of the last step overshooting my end point. To deal with this I was planning on just making the last point in my array = to endPos if the last step would have overshot it. I am open to any other ideas you may have for dealing with this.
Here is my current function:
function getPoints(p1, p2, quantity) {
var points = new Array();
var ydiff = p2.y - p1.y, xdiff = p2.x - p1.x;
var slope = (p2.y - p1.y) / (p2.x - p1.x);
var x, y;
for (var i = 0; i <= quantity; i++) {
if (slope == 0)
{
y = 0;
x = xdiff * (i / quantity);
}
if (slope != 0)
{
y = ydiff * (i / quantity);
x = y / slope;
}
points.push(new Point(Math.round(x) + p1.x, Math.round(y) + p1.y));
}
return points;
}
This works, but I need to provide a quantity (how big my steps are). I don't like this approach because it makes mouse movement harder to normalize. What I want is to always move, for example, 4 units for each step taken. Those units would be resolved to new coordinates in my array.
I have an array with x elements given lat - lng value. My aim is to find the distance difference between the previous position and the next position in the loop as long as the number of elements (length) of the array with the haversine formula.
Example my array value;
var array = [
[51.06745252933975, -114.11267548799515],
[51.067506465746014, -114.09559518098831],
[51.0827140244322,-114.0949085354805],
[51.088267312195484,-114.10709649324417]];
I don't have a problem with math, my goal is to get the cursor in the loop as the previous element vs. the next actually pointer order.
Sketchy code recipe;
1st index of the loop; array[0] lat-lng and array[1] lat-lng calc distance
2nd index of the loop; array[1] lat-lng and array[2] lat-lng calc distance
I'm using Javascript and how do I do it most ideally?
Seems a bit easy, but I might be not understand the question at all, if the question is how to loop an array by comparing to the previous entry, there are several ways to do it, one way could be shown below
// https://stackoverflow.com/a/27943/28004
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
// end of pasted code
// your entry
const points = [
[51.06745252933975, -114.11267548799515],
[51.067506465746014, -114.09559518098831],
[51.0827140244322,-114.0949085354805],
[51.088267312195484,-114.10709649324417]
]
// looping through all points starting from the second element
for (let i = 1; i < points.length; i += 1) {
const lastPosition = points[i-1];
const newPosition = points[i];
console.log(
`from position ${i-1} to ${i} it's %s Km`,
getDistanceFromLatLonInKm(lastPosition[0], lastPosition[1], newPosition[0], newPosition[1]))
}
Keep in mind that there's no validation (1 entry only will through an error) and that the Haversine formula only calculates a straight line between 2 points and does to take into account that the planet is not a sphere.
Doing a mini-game like this:
https://bijanmoudi.github.io/teeter-totter/
Image
My goal is to calculate the offset to the line from my object
I tried to learn how to calculate the collision right but - unsuccessful
Appreciate for your feedback
you should calculate the distance between object and line like that:
const line = document.getElementsById('line')
const obj = document.getElementsById('obj')
const distance = Math.hypot(obj.position.x - line.position.x, obj.position.y - line.position.y);
When you calculate the distance between a line segment and point, you first need to calculate the nearest point on the infinite line that runs through the segment. Second, you clamp that nearest point to be within the bounds of the line segment. Third, you calculate the distance from the clamped point to your original point.
const line = [{x:0,y:0}, {x:10, y:0}]
const point1 = {x:2, y:2}
const point2 = {x:-10, y:2}
const point3 = {x:11, y:-1}
function nearestPointDistance(line, point){
//Get the Ax+By+c = 0 representtion of the line
let vector = {x:line[1].x-line[0].x, y:line[1].y-line[0].y}
lineLength = Math.sqrt(vector.x**2 + vector.y**2)
let normalizedVector = {x:vector.x/lineLength, y:vector.y/lineLength}
let pointVector = {x:point.x - line[0].x,y:point.y - line[0].y}
let dotProduct = vector.x*pointVector.x+vector.y*pointVector.y;
dotProduct /= lineLength
let nearestPoint
if(dotProduct < 0)
nearestPoint = line[0];
else if(dotProduct > lineLength)
nearestPoint = line[1];
else nearestPoint = {x:(line[0].x + normalizedVector.x*dotProduct), y:(line[0].y + normalizedVector.y/dotProduct)}
let distance = Math.sqrt((nearestPoint.x - point.x)**2 + (nearestPoint.y - point.y)**2)
return distance;
}
console.log(nearestPoint(line, point1))
console.log(nearestPoint(line, point2))
console.log(nearestPoint(line, point3))
I have one circle, which grows and shrinks by manipulating the radius in a loop.
While growing and shrinking, I draw a point on that circle. And within the same loop, increasing the angle for a next point.
The setup is like this:
let radius = 0;
let circleAngle = 0;
let radiusAngle = 0;
let speed = 0.02;
let radiusSpeed = 4;
let circleSpeed = 2;
And in the loop:
radius = Math.cos(radiusAngle) * 100;
// creating new point for line
let pointOnCircle = {
x: midX + Math.cos(circleAngle) * radius,
y: midY + Math.sin(circleAngle) * radius
};
circleAngle += speed * circleSpeed;
radiusAngle += speed * radiusSpeed;
This produces some kind of flower / pattern to be drawn.
After unknown rotations, the drawing line connects to the point from where it started, closing the path perfectly.
Now I would like to know how many rotations must occure, before the line is back to it's beginning.
A working example can be found here:
http://codepen.io/anon/pen/RGKOjP
The console logs the current rotations of both the circle and the line.
Full cycle is over, when both radius and point returns to the starting point. So
speed * circleSpeed * K = 360 * N
speed * radiusSpeed * K = 360 * M
Here K is unknown number of turns, N and M are integer numbers.
Divide the first equation by the second
circleSpeed / radiusSpeed = N / M
If speed values are integers, divide them by LCM to get minimal valid N and M values, if they are rational, multiply them to get integer proportion.
For your example minimal integers N=1,M=2, so we can get
K = 360 * 1 / (0.02 * 2) = 9000 loop turns
I am trying to write a function that will randomly return an (x,y) co-ordinates around a given circumference
so if I have a point that's at (0,0) (being the center of the div) how can I write a function that randomly places other entities that appear among the outer edge of a circle.
All I need is the equation i know it has something to do with getting the distance from the center to the circumference edge just no idea how to calculate it and randomize it so it looks good.
Just get a random angle:
var angle = Math.random()*Math.PI*2;
Then
x = Math.cos(angle)*radius;
y = Math.sin(angle)*radius;
Done.
You can also avoid computing sin and cos via this formula:
// Generate 2 random numbers in the [-1, 1] interval
const u = Math.random()*2 - 1;
const v = Math.random()*2 - 1;
const u2 = u*u;
const v2 = v*v;
const r = u2 + v2;
if (r <= 1) {
x = (u2 - v2)/r;
y = (2*u*v)/r;
}
if r > 1 you need to re-try, but the expected number of tries until you get a valid point is ~1.27. So this algorithm is very efficient and avoids the complex trigonometric functions.
Visualization: https://observablehq.com/#kunigami/circles-and-randomness