Array length is showing incorrect - javascript

I'm confused about why this is not working: when I print the array lengths for two exact arrays, holding graphics objects, they are different. I'm using Javascript. Can someone pls help? Thanks.
Here's the code:
for (var i = 0; i < 4; i++){
for (var j = 0; j < 4; j++){
var tile = new Circle(30);
tile.setPosition(i * 3 * tile.getRadius() + tile.getRadius() * 2, j * 3 * tile.getRadius() + tile.getRadius() * 2);
tile.setColor(colors[Randomizer.nextInt(0, colors.length - 1)]);
add(tile);
} tiles.push(tile);
}
println(tiles.length);
for (var r = 0; r < rows; r++){
for (var c = 0; c < cols; c++){
var black = new Circle(30);
black.setPosition(r * 3 * black.getRadius() + black.getRadius() * 2, c * 3 * black.getRadius() + black.getRadius() * 2);
black.setColor(Color.black);
black.isFilled = false;
after.push(black);
}
}
println(after.length);

Related

How to distort an image by noise in p5.js

I'm trying to produce a function that starts with source image, generates noise, and then uses the noise to distort the image.
I start with creating the noise, and turning it into a vector field, Then I remap the coordinates, and pull the pixels out of the image at the correct coordinates.
Finally I re-combine the extracted pixels into an image.
So far my code is as follows:
function distort(sourceImage){
let vectorField = [];
var amount = 100;
var scale = 0.01;
for (x = 0; x < sourceImage.width; x++){
let row = [];
for (y = 0; y < sourceImage.height; y++){
let vector = createVector(amount*(noise(scale*x,scale*y)-0.5), 4*amount*(noise(100+scale*x,scale*y)-0.5))
row.push(vector);
}
vectorField.push(row);
}
var result = [];
sourceImage.loadPixels();
for (i = 0; i < sourceImage.width; i++){ //sourceImage.width
for (j = 0; j < sourceImage.height; j += 4){ //sourceImage.height
var res = vectorField[i][j];
//console.log(res);
var ii = constrain(floor(i + res.x), 0, sourceImage.width - 1);
var jj = constrain(floor(j + res.y), 0, sourceImage.height - 1);
//console.log(ii, jj);
result[i * sourceImage.width + j] = color(sourceImage.pixels[ii * sourceImage.width + jj], sourceImage.pixels[ii * sourceImage.width + jj + 1], sourceImage.pixels[ii * sourceImage.width + jj + 2], sourceImage.pixels[ii * sourceImage.width + jj + 3]);
}
}
//console.log(result)
//console.log(sourceImage.pixels[0 + sourceImage.width * 0])
for (n=0; n<sourceImage.width; n++) {
for(m=0; m<sourceImage.height; m++){
index = (n * sourceImage.width + m) * 4;
if (index >= 4194300){
index = 4194300;
}
sourceImage.pixels[index] = red(result[index]);
sourceImage.pixels[index + 1] = green(result[index]);
sourceImage.pixels[index + 2] = blue(result[index]);
sourceImage.pixels[index + 3] = alpha(result[index]);
}
}
sourceImage.updatePixels();
image(sourceImage, 0, 0, size, size);
}
Except that as a result, I'm getting 4 panels of noise across the top 4th of the canvas. The noise notably includes a lot of pixels that I know weren't in the source image, too (namely blue pixels; the image I'm trying to distort is red and white). The noise is sort of identifiable as having started as the source image, but distorted and with the aforementioned artefacts.
For comparison:
You do not process the vector field completely, you have to read each vector from the field. Actually you read just each 4th element of the vector
for (j = 0; j < sourceImage.height; j += 4)
for (j = 0; j < sourceImage.height; j++)
Further the computation of the source index is wrong. Note the control variable for the row (jj) has to be multiplied by the height. The index of the pixel in the array has to be multiplied by 4, because each pixel consists of 4 color channels:
ii * sourceImage.width + jj
(jj * sourceImage.width + ii) * 4
The computation of the target index is wrong, too:
index = (n * sourceImage.width + m) * 4;
index = (m * sourceImage.width + n) * 4;
Note, result contains 1 element for each pixel, byut sourceImage.pixels contains 4 elements for each pixel. Thus the index which reads from result and the index which access the target are different:
let result_i = m * sourceImage.width + n;
let target_i = result_i * 4;
For instance:
let result = [];
for (let j = 0; j < sourceImage.height; j++) {
for (let i = 0; i < sourceImage.width; i++) {
let res = vectorField[i][j];
let ii = constrain(floor(i + res.x), 0, sourceImage.width - 1);
let jj = constrain(floor(j + res.y), 0, sourceImage.height - 1);
let source_i = (jj * sourceImage.width + ii) * 4;
let col = color(
sourceImage.pixels[source_i],
sourceImage.pixels[source_i + 1],
sourceImage.pixels[source_i + 2],
sourceImage.pixels[source_i + 3]);
result.push(col);
}
}
for(let m = 0; m < sourceImage.height; m++) {
for (let n = 0; n < sourceImage.width; n++) {
let result_i = m * sourceImage.width + n;
let target_i = result_i * 4;
let col = result[result_i];
sourceImage.pixels[target_i] = red(col);
sourceImage.pixels[target_i + 1] = green(col);
sourceImage.pixels[target_i + 2] = blue(col);
sourceImage.pixels[target_i + 3] = alpha(col);
}
}

display pyramid in javascript in the below format

I am trying to display the pyramid in the console part using only javascript except document.write("")
*
* *
* * *
* * * *
* * * * *
I don't want in the above format.
I want in the below format
*
* *
* * *
* * * *
* * * * *
My code is
function getPyramid(param) {
for (var i = 1; i <= param; i++) {
var output = "";
for (var j = 1; j <= i; j++) {
output += j + " ";
}
console.log(output);
output = "";
}
}
<button onclick="getPyramid('10')">
function renderPyramid(n) {
for (var i = 0; i < n; i++) {
var str = '';
for (var j = 1; j < n-i; j++) {
str = str + ' ';
}
for (var k = 1; k <= (2*i+1); k++) {
str = str + '*';
}
console.log(str);
}
}
renderPyramid(5)
my solution
function pyramid(n) {
// generate base of pyramid, aka longest possible string
let limit = n+n-1;
let hashesToPrint = 1; // number of hashes to print
for (let i=0; i<n; i++) {
// get length of spaces we need on each side
let difference = (limit - hashesToPrint) / 2;
// generate spaces string
let spaces = ' '.repeat(difference);
// create pounds string
let pounds = '#'.repeat(hashesToPrint);
// append spaces on either side of our pound string
let newString = spaces + pounds + spaces
console.log(newString)
// increment our counter by two
hashesToPrint += 2
}
}
pyramid(3)
Resolved :I got logic for this question
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<button onclick="getPyramid('10')">
Get Pyramid</button>
<script>
function getPyramid(param)
{
for(var i=0;i<param;i++) {
var output="";
for(var j=0;j<param-i;j++) {
output+=" ";
// console.log(" ");
}
for(var k=0;k<=i;k++) {
// console.log("* ");
output += "* ";
}
// output += "";
console.log(output);
}
}
</script>
</body>
</html>
<script type="text/javascript">
var i, j;
for (i = 1; i <= 5; i++)
{
for (j = 1; j <= i; j++)
{
document.write("\t*");
}
document.write("<br>");
}
for (i = 5; i >= 1; i--)
{
for (j = 1; j <= i; j++)
{
document.write("\t*");
}
//document.write("\t");
document.write("<br>");
}
for (i = 5; i >= 0; i--)
{
for (j = 0; j < i; j++)
{
document.write("*");
}
for (k = i; k <= 5; k++)
{
document.write("*");
}
document.write("*");
}
</script>

Javascript object losing attribute

I'm having a bit of a problem with this function:
function create_enemies(rows, columns) {
var i, j;
var x_position = 0;
var y_position = 0;
var id = 0;
enemies_array = new Array(rows);
for (i = rows - 1; i >= 0; i--) {
enemies_array[i] = new Array(columns);
for (j = columns - 1; j >= 0; j--) {
x_position = j * (enemy_squadron_width / 4) + (ship_width / 2);
y_position = i * (enemy_squadron_height / 4);
enemies_array[i, j] = {
x : x_position,
y : y_position,
width : ship_width,
height : ship_height,
speed : 2,
id : id
};
id++;
console.log("this one's fine: " + enemies_array[i, j].y);
}
}
for (i = rows - 1; i >= 0; i--) {
for (j = columns - 1; j >= 0; j--) {
console.log("This one's not fine: " + enemies_array[i, j].y);
}
}
}
What's happening is that on the first console.log, the Y attribute is being correctly printed, but on the second console.log, every Y in every element of the array is set at 0. Somehow the Y attribute is lost between the first outer for-loop and the second.
I'm surely missing something very obvious, and starting to feel a little insane.
Any ideas?
Thank you very much.
edit - I should mention that every other attribute is fine. Only the Y is being reset
Here you go:
function create_enemies(rows, columns) {
var x_position = 0;
var y_position = 0;
var enemy_squadron_width = 100;
var enemy_squadron_height = 100;
var ship_width = 100;
var ship_height = 100;
var id = 0;
var enemies_array = new Array(rows);
for (var i = rows - 1; i >= 0; i--) {
enemies_array[i] = new Array(columns);
for (var j = columns - 1; j >= 0; j--) {
var x_position = j * (enemy_squadron_width / 4) + (ship_width / 2);
var y_position = i * (enemy_squadron_height / 4);
enemies_array[i][j] = {
x : x_position,
y : y_position,
width : ship_width,
height : ship_height,
speed : 2,
id : id
};
id++;
console.log("this one's fine: " + enemies_array[i][j].y);
}
}
for (var i = rows - 1; i >= 0; i--) {
for (var j = columns - 1; j >= 0; j--) {
console.log("This one's not fine: " + enemies_array[i][j].y);
}
}
}
create_enemies(10,10);
You need to acces the elements of the array by a[i][j].
Fiddle: http://jsfiddle.net/bL4mwgez/1/

Got 90% of the JavaScript code - can't figure out the rest

So I am trying to model Gram-Schmidt for any size N×N matrix, and I have officially hit a roadblock I can't get past. I know it's a matter of looping this correctly, but I can't figure out what the problem is. Remember I do not want to just pass in a 3×3 matrix, but any size N×N.
The course notes QR Decomposition with Gram-Schmidt explains exactly what I want to do. Very simple calculation by the way. In the course notes ||u|| means that it is the sum of the square of the elements, so sqrt(x12 + x22 + x32 + .... + xn2).
The multiplication symbol is actually the dot product.
The code I wrote so far is listed below. What is wrong with it?
function qrProjection(arr) {
var qProjected = [];
var tempArray = [];
var aTemp = arr;
var uTemp = new Array(arr.length);
var uSquareSqrt = new Array(arr.length);
var eTemp = [];
var sum = 0;
var sumOfSquares = 0;
var breakCondition = 0;
var secondBreakCondition = 0;
var iterationCounter = 0;
//Build uTemp Array
for (i = 0; i < arr.length; i++) {
uTemp[i] = new Array(arr[i].length);
}
for (i = 0; i < arr.length; i++) {
eTemp[i] = new Array(arr[i].length);
}
uTemp[0] = aTemp[0];
for (j = 0; j <= arr.length; j++) {
for (l = 0; l < arr[j].length; l++) {
if (breakCondition == 1) break;
sumOfSquares = Math.pow(uTemp[j][l], 2) + sumOfSquares;
}
if (breakCondition == 0) {
uSquareSqrt[j] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
}
for (i = 0; i < arr[j].length; i++) {
if (breakCondition == 1) break;
eTemp[j][i] = (1 / (uSquareSqrt[j])) * (uTemp[j][i]);
}
breakCondition = 1;
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
matrixDotProduct = aTemp[j + 1][m] * eTemp[j][m] + matrixDotProduct;
}
}
else {
for (m = 0; m < arr[j].length; m++) {
for (s = 0; s <= iterationCounter; s++) {
matrixDotProduct = aTemp[j + 1][s] * eTemp[m][s] + matrixDotProduct;
}
for (t = 0; t < arr[j].length; t++) {
uTemp[j + 1][t] = aTemp[j + 1][t] - eTemp[j][t] * matrixDotProduct;
}
}
}
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
uTemp[j + 1][m] = aTemp[j + 1][m] - eTemp[j][m] * matrixDotProduct;
}
}
matrixDotProduct = 0;
for (l = 0; l < arr[j].length; l++) {
sumOfSquares = Math.pow(uTemp[j + 1][l], 2) + sumOfSquares;
}
uSquareSqrt[j + 1] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
for (i = 0; i < arr[j].length; i++) {
eTemp[j + 1][i] = (1 / (uSquareSqrt[j + 1])) * (uTemp[j + 1][i]);
}
iterationCounter++;
}
qProjected = eTemp;
return qProjected;
}
I must apologize that instead of tweaking your code, I wrote my own from scratch:
/* Main function of interest */
// Each entry of a matrix object represents a column
function gramSchmidt(matrixA, n) {
var totalVectors = matrixA.length;
for (var i = 0; i < totalVectors; i++) {
var tempVector = matrixA[i];
for (var j = 0; j < i; j++) {
var dotProd = dot(matrixA[i], matrixA[j], n);
var toSubtract = multiply(dotProd, matrixA[j], n);
tempVector = subtract(tempVector, toSubtract, n);
}
var nrm = norm(tempVector, n);
matrixA[i] = multiply(1 / nrm, tempVector, n);
}
}
/*
* Example usage:
* var myMatrix = [[1,0,0],[2,3,0],[5,4,7]];
* gramSchmidt(myMatrix, 3);
* ==> myMatrix now equals [[1,0,0],[0,1,0],[0,0,1]]
* 3 here equals the number of dimensions per vector
*/
/* Simple vector arithmetic */
function subtract(vectorX, vectorY, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = vectorX[i] - vectorY[i];
return result;
}
function multiply(scalarC, vectorX, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = scalarC * vectorX[i];
return result;
}
function dot(vectorX, vectorY, n) {
var sum = 0;
for (var i = 0; i < n; i++)
sum += vectorX[i] * vectorY[i];
return sum;
}
function norm(vectorX, n) {
return Math.sqrt(dot(vectorX, vectorX, n));
}
Note that the algorithm above computes the Gram-Schmidt orthogonalization, which is the matrix [e1 | e2 | ... | en], not the QR factorization!

Problem with JavaScript Array

TilesArray.tiles has a wrong output, alert(TilesArray.array); gives me the correct output with randomized numbers, but at the end TilesArray.tiles has the same array in each index.
for (i = 0; i < 200; i++) {
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}
Any solution to fix the issue?
You need to copy the array. Could be done with slice()
for (i = 0; i < 200; i++) {
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array.slice(0);
}
You're continuously adding a reference to the same array to tiles. To get around this, create a new array in each iteration of the outer loop:
for (i = 0; i < 200; i++) {
TilesArray.array = []; // This is the line
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}
Or even better? Add everything directly to your tiles array (it's one less variable to worry about):
for (i = 0; i < 200; i++) {
TilesArray.tiles[i] = [];
for (j = 0; j < 200; j++) {
TilesArray.tiles[i][j] = (Math.round(Math.random() * 499 + 1));
}
}
At each iteration, you fill your TilesArray.array with new random values, and store a reference to this unique array in TilesArray.tiles[i]. But the array of random values is always the same. You just have many pointers to the same array.
You need to allocate a new array at each iteration :
for (i = 0; i < 200; i++) {
TilesArray.array = [];
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}

Categories