Looping through coordinates, adding new coordinates - javascript

Ok I am using Flotr2 to make a graph, and apparently the only way to get the curved line between two coordinates is to add a new coordinate every say 0.1, between two different coordinates.
So. I have data = [[1, 2], [2, 3]];
Where it is [[x, y], [x, y]].
How would i loop through the coordinates, and do like.. [1, 2], [1.1. 2.1], [1.2, 2.2] etc..?
I need to do this in jquery or javascript, doesnt matter which one.

Use a for-loop to iterate from x_min to x_max, adding 0.1 with each iteration. You can then generate coordinates by pushing a new array composed of the current values for x and y to your current array.
var data = [[1, 2], [2, 3]];
var x_min = data[0][0];
var x_max = data[1][0];
var initial = data[0];
var iteration = 0.1;
data.length = 0;
for (var i = 0; i < (x_max-x_min); i+=iteration) {
data.push([initial[0]+i, initial[1]+i]);
}
​console.log(data)​

Related

extract 2D array from another 2D array represented as a 1D array

So if I have a 2D array such as
const array = [
[1, 2, 3, 4, 5],
[9, 8, 7, 6, 5],
[1, 8, 3, 6, 5],
[9, 8, 7, 6, 5],
[1, 8, 3, 6, 5],
[1, 2, 3, 4, 5]
];
which could for the point of the question be any size, square or not square.
and I want to extract 3x3 arrays out of it, for instance at 1,1 that would be const sub = [[8, 7, 6], [8, 3, 6], [8, 7, 6]]. So far so good - I can do this. However I am flattening the 2D array so that its represented as a 1D array (long story as to why), i.e
const array = [1, 2, 3, 4, 5, 9, 8, 7, 6, 5, 1, 8, 3, 6, 5, 9, 8, 7, 6, 5, 1, 8, 3, 6, 5, 1, 2, 3, 4, 5];
What I'm trying to do is extract the same (or any) 3x3 array out of this but while its represented as a 1D array, so I would then get back [8, 7, 6, 8, 3, 6, 8, 7, 6].
I almost got there, however I made an error of only working with arrays that were 9x9 and always extracting 3x3 subsets which mean that my solution only works for that specific case, and the more I stare at my solution, the more I cannot work out what the generic solution would look like.
My solution:
const extractSubsetFrom1D = (array, subHeight, subWidth, startRow, startCol) => {
const kWH = subWidth * subHeight
const subset = array.slice(((((kWH - 2) * startRow) + startCol) * kWH), ((((kWH - 2) * startRow) + startCol) * kWH) + kWH)
return subset
}
In my case subHeight and subWidth were always equalling 3 respectively, and as the array itself was always 9x9 I believe I accidentally stumbled on a solution for that specific case as they divide nicely into each other.
To be clear my solution will fail for the startRow = 1 startCol = 0 for the provided array (it works for the startRow = 0 scenario
It's not entirely clear to me how you came to your current implementation, but I can at least tell:
✅ You correctly determined the size of the sub grid array to return (kWH)
❌ You incorrectly assume you can slice out a sub grid as one continuous part of the original 1d array
🟠 The calculation of the first element seems kind-of-right but is actually wrong (probably because of the previous mistake)
From (y,x) to i
Let's start from scratch and work our way up to a nice one liner.
In a 2d-array, you can get a cell's value by doing:
cellValue = grid2d[y][x]
Once you flatten it, you'll need to do:
cellValue = grid1d[y * GRID_WIDTH + x]
y * GRID_WIDTH takes you to the start of the right row, and + x gets you to the right column.
As you can see, you need to know the original grid's size before you can even query a specific cell. That means your extract function would need an argument to pass the original width (or, if the grids are guaranteed to be square, you can do Math.sqrt(array.length).
A slice per row
Let's use this math to find the indices of a 2x2 sub grid at (1,1) extracted from a 3x3 source grid:
0 1 2
3 [4][5]
6 [7][8]
As you can see, the resulting indices are [4,5,7,8]. There is no way to slice these indices out of the source array directly because we don't want to include the 6.
Instead, we can use a nested loop to skip the gaps between our rows:
const to1d = (x, y, w) => y * w + x;
const extractSubGrid1D = (grid, gridWidth, x, y, w, h) => {
const yTop = y;
const yBottom = y + h
const xLeft = x;
const xRight = x + w;
const subgrid = [];
for (let y = yTop; y < yBottom; y += 1) {
for (let x = xLeft; x < xRight; x += 1) {
const index = to1d(x, y, gridWidth);
subgrid.push(grid[index]);
}
}
return subgrid;
}
const originalGrid = [
0, 1, 2,
3, 4, 5,
6, 7, 8
];
console.log(
extractSubGrid1D(originalGrid, 3, 1, 1, 2, 2)
)
Once you get a feel for the logic, feel free to refactor.
The other way around
To go from a 1d-index to a 2d coordinate, you can do:
x = i % w
y = Math.floor(i / w)
Applying this logic, you can also fill your sub grid like so:
Create a new array of the right size
For each of its indices, determine the original grid's (x, y) coordinate
Transform that coordinate back to an index to query the original grid with
const to1d = (x, y, w) => y * w + x;
const extractSubGrid1D = (grid, gridWidth, x, y, w, h) => Array.from(
{ length: w * h },
(_, i) => grid[to1d(x + i % w, y + Math.floor(i / w), gridWidth)]
)
const originalGrid = [
0, 1, 2,
3, 4, 5,
6, 7, 8
];
console.log(
extractSubGrid1D(originalGrid, 3, 1, 1, 2, 2)
)

Calculate polygon area javascript

I'm trying to calculate the area of a polygon giving some coordinates that can be negative.
When I pass only negative coordinates it gives me a negative area, when I pass only positives it gives me a positive but when I give it a mix ([-1, 0],[-1, 1],[1, 1],[1, 0]) it always give me a negative.
My code is:
function calculateArea(coords) {
area = 0;
points = coords.length;
j = points - 1;
for (i = 0; i < points; i++) {
area += (coords[i][0] + coords[j][0]) * (coords[i][1] - coords[j][1])
j = i;
}
return area / 2;
}
coords is an array of [x,y] coordinates.
The thing is, I'm not completely sure but I think that if I return the absolute value of the area calculated this should be correct.
Am I missing something or returning the absolute should be ok?
Area sign depends on how you order vertices not on if some coordinates are negative.
Clockwise ordering gives negative areas
Counterclockwise - positive
Assuming you have correct formula itself you could simple use Math.abs to always get positive values.
function calculateArea(coords) {
let area = 0;
for (let i = 0; i < coords.length; i++) {
const [x1, y1] = coords[i];
const [x2, y2] = coords[(i + 1) % coords.length];
area += x1 * y2 - x2 * y1
}
return area / 2;
// replace with
// return Math.abs(area) / 2;
}
console.log('Clockwise:', calculateArea([
[-1, 0],
[-1, 1],
[1, 1],
[1, 0]
]))
console.log('Counterclockwise:', calculateArea([
[-1, 0],
[-1, 1],
[1, 1],
[1, 0]
].reverse()))

reshape 1d array to 3d for tensorflow.js lstm

I'm trying to predict future stock prices using time series data. I have an xs array of 251 timesteps, and a ys array of the corresponding stock price for that time step. I have reshaped the xs array to be 3d, but get an error
'Input Tensors should have the same number of samples as target Tensors. Found 1 input sample(s) and 251 target sample(s).'
the code for the model is below.
var xs = [];
var ys = [];
for(i in result){
xs.push(i);
ys.push(result[i].close);
}
var xt = tf.tensor3d(xs, [1,xs.length,1]);
var yt = tf.tensor2d(ys, [xs.length, 1]);
//xt.reshape([1, xs.length, 1]).print();
//yt.reshape([1, ys.length, 1]).print();
var lstm1 = tf.layers.lstm({units: 32, returnSequences: true, inputShape:[xs.length,1]});
var model = tf.sequential();
model.add(lstm1);
model.add(tf.layers.dropout({rate:0.2}));
model.add(tf.layers.lstm({units:5}));
model.add(tf.layers.dropout({rate:0.2}));
model.add(tf.layers.dense({units:1, inputShape:[32], activation:'softmax'}));
model.compile({optimizer:'adam', loss:'categoricalCrossentropy'});
model.fit(xt, yt, {epochs:1000}).then(() => {
bestfit = model.predict(tf.tensor(xs, [xs.length,1])).dataSync();
The error seems to come from model.fit(x, y) because there seems to be a mismatch in the shape of x and y.
x has the shape [1, 251, 1] and y the shape [251, 1]. This does not work because there is more features in x than there is label in y. You have to reshape whether x or y.
reshape x: x.reshape([251, 1, 1]) or x.reshape([251, 1])
or
reshape y: y.reshape([1, 251]) or y.reshape([1, 251, 1])
Note: There is almost an infinite way of reshaping that will work as long as the first two dimension sizes are equal and that the product of all dimension sizes is equal to 251. What matter in the reshaping is not to loose the correlation between the features and the labels

Issues with displaying a map in p5.js

I am currently attempting to display a map in processing using a 2d array.
Currently I have this down:
var start_map = [
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1]
];
function drawMap(map) {
for (var x = 0; x < 5; x++) {
for (var y = 0; y < 5; y++) {
if (map[x][y] == 0) {
fill(51, 153, 51);
rect((10 + 50*x), (10 + 50*y), 50, 50);
}
else if (map[x][y] == 1) {
fill(0, 102, 0);
rect((10 + 50*x), (10 + 50*y), 50, 50);
}
}
}
}
But, while I do get a map displayed, it appears to be rotated 90 degrees clockwise. What is causing this and how can I fix this?
Think about how the indexes of a 2D array work. Let's look at a simpler example:
var map = [
[1, 2],
[3, 4]
];
Where is map[0][1]? Where is map[1][0]?
A 2D array is an array of arrays. The first index selects the subarray at that index, and the second index selects the element in that subarray.
So in the simple example above, map[0] selects the subarray at index 0, which is [1, 2]. Then map[0][1] selects the element in that subarray at index 1, which is 2.
This might seem a bit surprising if you were treating the indexes as an x, y pair. In that case, you'd expect 0, 1 to give you 3, right? But it's not an x, y pair. It's an index into the outer array, then an index into the subarray.
In other words, it's actually a y, x pair. So to fix your problem, you can actually just swap the order of your indexes:
`map[y][x]`
Now you use the y value to select which subarray you want (which row you want), and the x value to select which element in that subarray you want (which column you want).

How to write jqPlot values into variables?

I use jqPlot to plot a line chart out of a .csv-file.
I need to get the xmax and ymax values of the plot and use them for further processings.
How do I get this or any other values and write them inside my own variables?
EDIT
Let's say this is my plot:
What I need is not the maximum x-value from the array (here 1380). I need to get the maximum value from the plot (here 2000). For further processing I would like to add rectangles inside the plot, see second picture: and calculate their height as a x-value and not as their pixel-value.
Therefore I need to access the jqplot variables, not the array variables I give over to jqplot.
So, at some point you have an array of values that you passed to jqPlot to draw the graph, for example:
var myData = [[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]];
If you want to find the maximum x and y values, you just need to loop through the array keeping track of the largest value you've found so far.
var maxX, maxY;
for (var i=0; i < myData.length; i++) {
if (myData[i][0] > maxX || !maxX) {
maxX = myData[i][0];
}
if (myData[i][1] > maxY || !maxY) {
maxY = myData[i][1];
}
}
Here's a simple demo: http://jsfiddle.net/LAbvj/
EDIT: Ok, so I think what you are now asking for is the maximum for each axis. In that case, this is simple:
var plot1 = $.jqplot('chart1', [
[3, 7, 19, 1, 4, 6, 8, 2, 5]
]);
console.log(plot1.axes.xaxis.max);
console.log(plot1.axes.yaxis.max);
See demo: http://jsfiddle.net/KJTRF/

Categories

Resources