matrix rotation in javascript via a html button - javascript
( i'm not english but i'll try my best to explain )
i have some issues to rotate a matrix after a click on a button
i tried this
How to rotate a matrix in an array in javascript
but i failed to adapt it to my code .
so here is my html button :
<script type="text/javascript" src="genmap.js"></script>
<button onclick="rotate()">Tourner -></button>
<div style="display:auto;">
<canvas id="main" height="2000" width="5000"></canvas>
</div>
and my matrix ( square ) is randomly generated and look like this :
var map = [];
for(var i=0; i < size; i++) {
map[i] = new Array(size);
}
for(var j = 0; j < size; j++){
for ( var i = 0; i < size ; i++){
map[j][i] = Math.floor ( Math.random() * 2 );
}
}
i use a tuto for canvas , and my script begin with
(function main(isometric) {
and end with
})(this);
i don't know if i should put my function rotate in or out ...
neither how to trigger it with a click on " tourner -> "
i think i need to duplicate ( and rename ) my script but with map2 instead of map and change the random generation with the rotation from map , but i don't even know if it's possible :/
i tried this
for(var j = 0; j < size; j++){
for ( var i = 0; i < size ; i++){
maproteun[i][j] = map[size-i][j];
}
}
after the map generation but for some reason , it stop the creation of the first matrix and don't even draw the map
can you please help me ?
EDIT : things are moving
i'm able to clear the canvas , but i'm unable to reload the function ( or it doesn't work ) to redraw one
i use clearRect to clear it , but if i write
main();
it don't redo the function
Without access to your source it's kind of hard to guess where it could be tripping up within the code. From your description it sounds like you have the clear working when you click rotate button however there is no further drawing.
Did you check for syntax errors in the console? Chrome Menu > More Tools > JavaScript Console.
I've written up a simple sample here using the original source of the tutorial (minus the enclosure) and added a Rotate button: http://jsfiddle.net/goet30ww/2/
Apart from the clearRect which you added, before the drawing loops, I also added a rotate function:
function allowRotate() {
// Display the rotate button once images have loaded and map is drawn
var rot = document.getElementById("rotate")
rot.style.visibility = "visible"
// On click rotate map and redraw
rot.addEventListener("click", function(e) {
var maproteun = [];
var size = map[0].length;
for (var j = 0; j < size; j++) {
maproteun[j] = [];
for ( var i = 0; i < size ; i++) {
maproteun[j][i] = map[size - i - 1][j];
}
}
map = maproteun;
drawMap();
});
}
Thanks.
const matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
];
const rotateMatrix = (arr, col) => arr.map( row => row[col]);
/* matrix[0] - is to check on the column length for any N * N rotation */
const clockWise = matrix[0].map((row,i) => {
return rotateMatrix(matrix, i).reverse();
});
console.log('CLOCK WISE');
console.log(clockWise);
console.log('**********************************');
const antiClockWise = matrix.map((row,i) => {
return rotateMatrix(matrix, matrix.length -1 -i).reverse();
});
console.log('ANTI CLOCK WISE');
console.log(antiClockWise);
Related
How do I create bounds of a 2darray tilemap in Javascript?
I am creating a 2D ASCII game. Currently I have the world (leveldata) stored in a 2D array. Example: "test2": [ ["╔","═","═","═","═","═","═","═","═","═","╗","´","´","´","´","`","´","´","´","´","´"], ["║","▓","▓","▓","▓","▓","▓","▓","▓","▓","║","´","`","`","´","`","´","´","`","´","´"], ["║","▓","▓","▓","▓","▓","▓","▓","▓","▓","║","´","´","´","´","`","´","´","´","´","´"], ["║","▓","▓","▓","▓","▓","▓","▓","▓","▓","║","´","`","´","´","´","´","´","`","´","´"], ["╚","═","═","▓","▓","▓","▓","═","═","═","╝","´","´","´","´","´","`","´","´","´","´"], ["´","´","´","´","´","`","´","´","´","´","`","´","´","`","´","´","`","´","´","´","´"], ["´","´","`","´","´","´","´","´","´","╔","╗","´","´","´","´","´","´","´","`","´","´"], ["´","´","´","´","´","´","´","´","`","║","║","´","`","´","´","`","´","´","`","`","´"], ["´","´","´","´","´","´","´","`","´","║","║","´","´","´","´","`","´","`","`","´","´"], ["´","´","`","´","´","´","´","´","´","║","║","´","´","`","´","´","`","`","´","´","´"], ["´","´","´","´","´","´","`","´","`","║","║","`","´","´","´","´","`","´","´","`","´"] ] I take this data, replace the tile where the player is and then paste it to the screen, like so: I want to take this array that I paste to the screen, and crop it around the player with variable bounds. Essentially remove any tiles that are a certain distance from a box around the player, so that the camera "follows" the player. The problem is, tiles aren't removing the way I want them to and I am stuck on what I am supposed to do. Here is all I have so far, it takes in map data, bounds, and player position, and dumps out a custom array. I am trying just the upper bounds so far... // Cropping the game screen using a camera. function crop(width=5, height=5, x=1, y=1, map=[]) { let topBound = y-height; let bottomBound = y + height; let rowsRemoved = []; // Loop through and remove rows that are above or below the max. for (let row = 0; row < map.length; row++) { if (row < topBound) { rowsRemoved.push(row); } } for (let i = 0; i < rowsRemoved.length; i++) { console.log(rowsRemoved[i]); map.splice(rowsRemoved[i], 1); } console.log(rowsRemoved) // Loop through and remove columns that are above or below the max. // for (let row = 0; row < map.length; row++) { // for (let column = 0; column < map[row].length; column++) { // if (column < x-width || column > x+width) { // map[row].splice(map[row].indexOf(map[row][column]), 1); // } // } // } console.log("----") return map; }
It turned out it was to slice the array instead of splice it, and take a totally different approach. // Cropping the game screen using a camera. function crop(width=5, height=5, x=1, y=1, map=[]) { // Get the bounds and make sure they stay within the map's bounds. let topBound = y - height; if (topBound < 0) { topBound = 0; } let bottomBound = y + height + 1; let leftBound = x - width; if (leftBound < 0) { leftBound = 0; } let rightBound = x + width + 1; let rowsRemoved = []; // Remove rows that are above or below the max. map = map.slice(topBound, bottomBound); console.log(map) // Remove columns that are above or below the max. for (let row = 0; row < map.length; row++) { map[row] = map[row].slice(leftBound, rightBound); } console.log("----"); return map; }
PaperJs Add 2 raster as 2 symbols in the same project
I have this project in paperjs: var url = "http://www.clker.com/cliparts/q/I/s/P/E/3/yellow-umbrella-md.png"; raster = new Raster(url); raster.rotate(10); raster.scale(0.4); var url2 = "https://images.vexels.com/media/users/3/145373/isolated/preview/98721f602aa3fadb040e0a161ab3f966-waterdrop-vislumbrante-vis-o-ilustra--o-by-vexels.png"; secondRaster = new Raster(url); secondRaster.scale(0.9); var count = 150; var symbol = new Symbol(raster); var secondSymbol = new Symbol(secondRaster); for (var i = 0; i < count; i++) { // The center position is a random point in the view: var center = Point.random() * view.size; var placedSymbol = symbol.place(center); placedSymbol.scale(i / count); } function onFrame(event) { // Run through the active layer's children list and change // the position of the placed symbols: for (var i = 0; i < count; i++) { var item = project.activeLayer.children[i]; // Move the item 1/20th of its width to the right. This way // larger circles move faster than smaller circles: item.position.y += item.bounds.width / 80; // If the item has left the view on the right, move it back // to the left: if (item.bounds.bottom > view.size.width) { item.position.y = -item.bounds.width; } } } The first raster has a symbol works good, but the second can't make it work... I read about to add more than one symbol to project.activeLayer.children but don't work. Even if I do a group of an array with both symbols also don't show up. I read in a post that symbols can't be added as a group. Being that be true, it should be ok to be added even though isolated... Anybody had done something similar? Thank you
There are some mistakes in your code: The most important one, that make you think that the second raster doesn't work, is that you are creating the second raster with the variable url instead of url2. So both rasters use the same image as source... You need to place the second symbol like you do with the first one otherwise it will never get rendered. When iterating through active layer children, make sure to iterate over all children by using project.activeLayer.children.length (as you are placing count * 2 symbols). When checking for bottom reaching items, use height instead of width. Here is a sketch demonstrating the solution. var COUNT = 10; var raster = new Raster('http://www.clker.com/cliparts/q/I/s/P/E/3/yellow-umbrella-md.png'); raster.rotate(10); raster.scale(0.4); var secondRaster = new Raster('https://images.vexels.com/media/users/3/145373/isolated/preview/98721f602aa3fadb040e0a161ab3f966-waterdrop-vislumbrante-vis-o-ilustra--o-by-vexels.png'); secondRaster.scale(0.15); var symbol = new Symbol(raster); var secondSymbol = new Symbol(secondRaster); for (var i = 1; i <= COUNT; i++) { // first symbol symbol.place(Point.random() * view.size).scale(i / COUNT); // second symbol secondSymbol.place(Point.random() * view.size).scale(i / COUNT); } function onFrame(event) { for (var i = 0; i < project.activeLayer.children.length; i++) { var item = project.activeLayer.children[i]; item.position.y += item.bounds.height / 80; if (item.bounds.bottom > view.size.height) { item.position.y = -item.bounds.height; } } }
Simulation of mouses moving, don't work
I'm trying to create a simulation of 150 mouses moving inside a 20x20 grid in p5.js (A processing like libary). First I'm spawning 150 mouses random places and everything goes fine. But after I have spawned the mouses I am trying to make them move to one of their neighbors. Instead of moving to one of the neighbors and make the current square empty it stays on the one that it already was one + it moves to the next one so instead of having 150 mouses i suddenly have 300... I have tried changing the code for hours but I can't find the proplem... Here is my code: var w = 40; var grid = []; var mouses = 10; var mouseAmount = []; var Mouse; var current; function setup() { createCanvas(800, 800); cols = floor(width/w) rows = floor(height/w) // frameRate(60); for (var j = 0; j < rows; j++) { for ( var i = 0; i < cols; i++) { var cell = new Cells(i,j); grid.push(cell); } } amount = new Amount; } function draw() { background(51); for ( var i = 0; i < grid.length; i++) { grid[i].show(); } amount.run(); } function index(i, j) { if (i < 0 || j < 0 || i > cols-1 || j > rows-1 ) { return -1; } return i + j * cols; } function Cells(i, j) { this.i = i; this.j = j; this.active = false; this.moveCell = function() { var neighbors = []; var top = grid[index(i, j -1)]; var right = grid[index(i+1, j)]; var bottom = grid[index(i, j+1)]; var left = grid[index(i-1, j)]; if (top) { neighbors.push(top) } if (right) { neighbors.push(right) } if (bottom) { neighbors.push(bottom) } if (left) { neighbors.push(left) } if(neighbors.length > 0) { var r = floor(random(0, neighbors.length)); return neighbors[r]; } else { return undefined; } } this.show = function() { var x = this.i*w; var y = this.j*w; stroke(255); noFill(); rect(x,y,w,w); if(this.active == true) { fill(155, 0, 255, 100) rect(x, y, w, w) } } } function Amount() { this.run = function() { var r = floor(random(grid.length)) for (var i = 0; i < mouses; i++) { var mouse = grid[r]; mouseAmount.push(mouse) } if (mouseAmount.length < 1499) { for (var i = 0; i < mouseAmount.length; i++) { mouseAmount[i].active = true; } } if (mouseAmount.length > 1499) { Next(); } } } function Next(i,j) { for (var i = 0; i < mouseAmount.length; i++) { current = mouseAmount[i]; var nextCell = current.moveCell(); if (nextCell) { nextCell.active = true; current.active = false; current = nextCell; } } } Thank you in advance :)
I don't really understand exactly what your code is supposed to do, but a few things stand out to me about your code: Problem One: I don't understand how you're iterating through your grid array. You seem to be iterating over mouseAmount, which seems to hold random cells from the grid for some reason? That doesn't make a lot of sense to me. Why don't you just iterate over the grid array directly? Problem Two: You then move the cells randomly to a neighbor, but you don't take into account whether the neighbor is already active or not. I'm not sure what you want to happen, but this seems a bit strange. Problem Three: Usually with simulations like this, you have to copy the next generation into a new data structure instead of modifying the data structure as you step through it. The biggest problem is that you haven't really explained what you want your code to do, or what this code does instead, or how those two things are different. But if I were you, I'd make the following changes: Step One: Iterate over your grid array in a more reasonable way. Just iterate over every index and take the appropriate action for every cell. If I were you I would just use a 2D array and use a nested for loop to iterate over it. Step Two: Make sure your logic for moving to a neighbor is correct. Do you want cells to move to already active cells? Step Three: Make a copy of the grid before you modify it. Think about it this way: as you iterate over the grid, let's say you move a cell down one row. Then you continue iterating, you'll reach the newly active cell again. In other words, you'll touch the same active cell twice in one generation, which is definitely going to mess you up. A word of advice: get this working for a single active cell first. It's really hard to tell what's going on since you have so many things going on at one time. Take a step back and make sure it works for one active cell before moving up to having a whole grid.
Can someone explain me this function for creating grid with JS/jQuery?
I am learning jquery/js and I want to create grid made of divs. This is script doing just that, but I cant fully understand it.. function displayGrid (n) { var size = 960; var boxSize = (960 - 4*n)/n; var wrap = $(".wrap").html(""); for (var j = 0; j < n; j++) { for (var i = 0; i < n; i++) { wrap.append( $("<div></div>").addClass("square").height(boxSize).width(boxSize) ); } wrap.append($("<div></div>").css("clear", "both")); } } In html I have empty wrap class. Also, there is this function which I understand :) function setGrid() { var col = prompt("Enter number of columns: "); displayGrid(col); clean(); } Thanks
Here is a basic line by line explanation.. function displayGrid (n) { var size = 960; //MAX SIZE TO BE COVERED BY ALL DIVS ,EVEN IF THERE ARE N NO OF DIV'S var boxSize = (960 - 4*n)/n; //FORMULA TO DECIDE WIDTH OF EACH DIV,CAN BE DIFFERENT TOO. var wrap = $(".wrap").html(""); //THIS IS A DIV PROBABLY WHERE YOU ARE ADDING THE NEW SMALLER DIVS for (var j = 0; j < n; j++) { for (var i = 0; i < n; i++) { //TWO FOR LOOPS ,1 IS FOR LOOP THROUGH ROWS , OTHER FOR COLUMNS. wrap.append( $("<div></div>").addClass("square").height(boxSize).width(boxSize) ); //THIS APPENDS A BLANK DIV TO DIV WITH CLASS .WRAP, AND ADDS A CLASS SQAURE, AND ALSO WITH WIDTH AND HEIGHT PROPERTY SETS EACH DIVS PROPERTY OF WIDTH AND HEIGHT. } wrap.append($("<div></div>").css("clear", "both")); //THIS SHOULD BE TO MOVE TO NEXT COLUMN. } }
Here is commented code: //n-> seems to be the number of times to divide the grid //1-> will get 1 square //2-> will get 4 square //3-> will get 9 square and so on... n^2 function displayGrid (n) { var size = 960; //This seems to calculate size of the squares to fit inside the give area // of 960: 960/4 //-4*n I guess is the border size to remove from each square in order to have an exact match var boxSize = (960 - 4*n)/n; //this get the grit container, empties it var wrap = $(".wrap").html(""); //now print each square on the document for (var j = 0; j < n; j++) { //columns for (var i = 0; i < n; i++) { //rows wrap.append( $("<div></div>").addClass("square").height(boxSize).width(boxSize) ); } //this is done to go in the next row, since we are using divs... wrap.append($("<div></div>").css("clear", "both")); } }
Resetting the iterator in a for...in loop
This is part of the code I am using to draw some random circles: if(circles.length != 0) { //1+ circles have already been drawn x = genX(radius); y = genY(radius); var i = 0; iCantThinkOfAGoodLabelName: for(i in circles) { var thisCircle = circles[i]; if(Math.abs(x-thisCircle["x"])+Math.abs(y-thisCircle["y"])>radius*2) { //overlaps } else { //overlaps x = genX(radius); y = genY(radius); continue iCantThinkOfAGoodLabelName; } if(i == circles.length - 1) { //Last iteration //Draw circle, add to array } } } The problem is that when there is an overlap, the circle with the newly generated coordinates is not checked for overlap with the circles that the overlapping circle had already been checked with. I have tried setting i to 0 before using the continue statement but that did not work. Please help, I am really confused.
You should not use for ... in on arrays. Use for(var i = 0; i < circles.length; ++i) instead. Then you can reset by setting i = 0.
Why not use a standard for loop for (var i=0,l = circles.length;i < l; i++) { .... if (i === l) { // draw } }
I'm not fully understanding the question, but I do not believe you can reset the iterations of a for..in. You'll need to go to a for(var i=0;...;i++).