i'm trying to do some modifications (in ES6) in this pen http://codepen.io/IMarty/pen/RaajQx, and it's almost perfectly working, except for these function
function drawLines(p) {
if(!p.active) return;
for(var i in p.closest) {
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.closest[i].x, p.closest[i].y);
ctx.strokeStyle = 'rgba(255,255,255,'+ p.active+')';
ctx.stroke();
}
}
In my pen http://codepen.io/wendelnascimento/pen/PzRzGE, i've written everything in ES6 and it's working, but just the strokes aren't showing. The method looks like this
drawLines(p) {
if(!p.active)
return;
for(var i = 0; i < p.closest.length; i++) {
this._context.beginPath();
this._context.moveTo(p.x, p.y);
this._context.lineTo(p.closest[i].x, p.closest[i].y);
this._context.strokeStyle = `rgba(255,255,255,${p.active})`;
this._context.stroke();
}
}
Can anyone help me with this?
This is because your list of closest points has only one element, so the iteration draws no lines. Reason for it: you have
if(p1 == p2) {
let placed = false;
for(let k = 0; k < 5; k++) {
if(!placed) {
if(!closest[k]) {
closest[k] = p2;
placed = true;
}
}
}
}
While it should be:
if(!(p1 == p2)) {
let placed = false;
for(let k = 0; k < 5; k++) {
if(!placed) {
if(!closest[k]) {
closest[k] = p2;
placed = true;
}
}
}
}
You want to enter the above if when points are different.
This draws lines between points, however the effect is very different to the example you were inspired by. If that's what you wanted - well done; if not, there's probably another problem, like picking mouse position and finding points closest to that, not the origin.
Related
I'm trying to get N ways of solves a N rook problem. The issue I am having is currently, I seem to get n*n solutions while it needs to be N! . Below is my code, I have written it in simple loops and functions, so it's quite long. Any help would be greatly appreciated
Note: Please ignore case for n = 2. I get some duplicates which I thought I would handle via JSON.stringify
var createMatrix = function (n) {
var newMatrix = new Array(n);
// build matrix
for (var i = 0; i < n; i++) {
newMatrix[i] = new Array(n);
}
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
newMatrix[i][j] = 0;
}
}
return newMatrix;
};
var newMatrix = createMatrix(n);
// based on rook position, greying out function
var collision = function (i, j) {
var col = i;
var row = j;
while (col < n) {
// set the row (i) to all 'a'
col++;
if (col < n) {
if (newMatrix[col][j] !== 1) {
newMatrix[col][j] = 'x';
}
}
}
while (row < n) {
// set columns (j) to all 'a'
row++;
if (row < n) {
if (newMatrix[i][row] !== 1) {
newMatrix[i][row] = 'x';
}
}
}
if (i > 0) {
col = i;
while (col !== 0) {
col--;
if (newMatrix[col][j] !== 1) {
newMatrix[col][j] = 'x';
}
}
}
if (j > 0) {
row = j;
while (row !== 0) {
row--;
if (newMatrix[i][row] !== 1) {
newMatrix[i][row] = 'x';
}
}
}
};
// checks position with 0 and sets it with Rook
var emptyPositionChecker = function (matrix) {
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j < matrix.length; j++) {
if (matrix[i][j] === 0) {
matrix[i][j] = 1;
collision(i, j);
return true;
}
}
}
return false;
};
// loop for every position on the board
loop1:
for (var i = 0; i < newMatrix.length; i++) {
var row = newMatrix[i];
for (var j = 0; j < newMatrix.length; j++) {
// pick a position for rook
newMatrix[i][j] = 1;
// grey out collison zones due to the above position
collision(i, j);
var hasEmpty = true;
while (hasEmpty) {
//call empty position checker
if (emptyPositionChecker(newMatrix)) {
continue;
} else {
//else we found a complete matrix, break
hasEmpty = false;
solutionCount++;
// reinitiaze new array to start all over
newMatrix = createMatrix(n);
break;
}
}
}
}
There seem to be two underlying problems.
The first is that several copies of the same position are being found.
If we consider the case of N=3 and we visualise the positions by making the first rook placed red, the second placed green and the third to be placed blue, we get these three boards:
They are identical positions but will count as 3 separate ones in the given Javascript.
For a 3x3 board there are also 2 other positions which have duplicates. The gets the count of unique positions to 9 - 2 - 1 -1 = 5. But we are expecting N! = 6 positions.
This brings us to the second problem which is that some positions are missed. In the case of N=3 this occurs once when i===j==1 - ie the mid point of the board.
This position is reached:
This position is not reached:
So now we have the number of positions that should be found as 9 - 2 - 1 - 1 +1;
There appears to be nothing wrong with the actual Javascript in as much as it is implementing the given algorithm. What is wrong is the algorithm which is both finding and counting duplicates and is missing some positions.
A common way of solving the N Rooks problem is to use a recursive method rather than an iterative one, and indeed iteration might very soon get totally out of hand if it's trying to evaluate every single position on a board of any size.
This question is probably best taken up on one of the other stackexchange sites where algorithms are discussed.
I'm creating an animation to show how a pattern matching algorithm works. Right now I have the full animation running from start to end when the sort button is pressed.
I am trying to implement a 'forward step' button (and also a 'back step' button) which when pressed will compare the pattern at the first position and then will compare it at the second position when it is pressed again etc. I'm unsure how I could implement this if it is even possible.
function kmp(p,t){
var k=0, j=0, result;
var fail=[];
var next=[];
var shifts = 0, comparisons = 0;
var boxWidth = $('#text_array .panel').outerWidth(true);
var places;
var previousMove = 0;
var totalMoves = 0;
kmpSetup(p, fail, next);
xx = setInterval(function () {
if(t[j] == p[k]) {
turnGreen('#p', k);
for(n=0; n<k; n++) {
turnGreen('#p', n);
}
turnGreenWhite('#t', j);
k = k+1;
j = j+1;
} else if(k==0) {
j++;
} else {
turnRed('#p', k);
turnRed('#t', j);
for (var m = 0; m < p.length; m++) {
turnWhite('#p', m);
}
turnWhite('#t', j);
var position = k;
k = next[k];
//calculating how many places to shift the pattern
// depending on the value in the table
if (k == -1) {
places = position + 1;
totalMoves+=places;
animatePattern(boxWidth, totalMoves, result);
k = k+1;
} else {
places = position - k;
totalMoves+=places;
animatePattern(boxWidth, totalMoves, result);
}
if(j>=t.length && k>=p.length) {
clearInterval(xx);
}
}
}, 1000);
if(k>=p.length){
result='match found';//match found
} else {
result='match not found';//no match found
}
return result;
}
jsfiddle
Hello fellow programmers,
I'm trying to build a tower defense-like game in canvas, HTML. I'm currently working on the process of detecting coordinates within a range of a defense. Here's what I have worked out so far:
this.defensesInRangeArcher = 0;
for (var i = 0; i < buildArcherX.length; i++) {
for (var i = 0; i < buildArcherY.length; i++) {
if (Math.sqrt(Math.pow(buildArcherX[i] - this.x, 2) + Math.pow(buildArcherY[i] - this.y, 2)) <= arch.radius + 7) {
this.defensesInRangeArcher += 1;
this.attackByArcher = true;
} else {
this.attackByArcher = false;
}
}
}
So far in the following code, I have made it so that the "Defenses" could detect multiple coordinates within a range. "this" is able to detect the number of "defenses" in range but then arose a problem. Archers shoot one at a time but it affects all of "this" in range of the "defense". However, I don't want that so I was wondering how I could make it shoot one at a time.
I decided to use a global variable shown in the following code but had a bug in it.
this.defensesInRangeArcher = 0;
for (var i = 0; i < buildArcherX.length; i++) {
for (var i = 0; i < buildArcherY.length; i++) {
if (Math.sqrt(Math.pow(buildArcherX[i] - this.x, 2) + Math.pow(buildArcherY[i] - this.y, 2)) <= arch.radius + 7) {
this.defensesInRangeArcher += 1;
if (!v.singleAimArcher && !this.dead) {
this.attackByArcher = true;
v.singleAimArcher = true;
}
} else {
this.attackByArcher = false;
v.singleAimArcher = false;
}
}
}
It worked for the first defense it passed by, however not for the second one it passed by, so on.
I was wondering what kind of solution I could get to solve this.
Thanks!
I have reference the question Finding all cycles in undirected graphs . and write a javascript version, but I got the performance problem, I run on chrome, it took about 8 seconds, too a long time, for only 16 vertices and 33 edges on my undirected graphs. this is codes:
<script>
var graph = [[37,36], [37,168], [37,85], [37,2264], [37,3203], [36,85], [36,536], [36,5097], [85,168], [85,654], [85,755], [85,3607], [85,4021], [85,5097], [168,755], [536,4021], [536,5097], [536,5464], [536,6533], [654,3607], [654,4021], [654,5564], [654,6533], [755,2357], [755,3203], [755,3607], [2264,2357], [2264,3203], [2357,3203], [4021,5097], [5464,5564], [5464,6533], [5564,6533]];
var cycles = [];
function findAllCycles() {
var i, j, len;
var st1 = new Date().getTime();
for (i = 0; i < graph.length; i++) {
var edge = graph[i];
for (j = 0; j < 2; j++) {
findNewCycles( [edge[j]] );
}
}
var st2 = new Date().getTime();
console.log("time: " + (st2-st1));
};
function findNewCycles(path) {
var startNode = path[0],
nextNode;
// visit each edge and each node of each edge
for (var i = 0; i < graph.length; i++) {
var edge = graph[i];
for (var j = 0; j < 2; j++) {
var node = edge[j];
if (node === startNode) // edge refers to our current node
{
nextNode = edge[(j + 1) % 2];
if ( !visited(nextNode, path) ) { // neighbor node not on path yet
// explore extended path
findNewCycles( [nextNode].concat(path), graph, cycles );
}
else if ( (path.length > 2) && (nextNode === path[path.length - 1]) ) { // cycle found
//var p = normalize(path);
//var inv = invert(p);
if ( isNew(path, cycles) ) {
cycles.push(path);
}
}
}
}
}
}
// check if vertex n is contained in path
function visited(node, path) {
return (path.indexOf(node) !== -1);
}
function isNew(path, cycles) {
for (var i = 0; i < cycles.length; i++) {
if ( equal(path, cycles[i]) ) {
return false;
}
}
return true;
}
function equal(path1, path2) {
if (path1.length !== path2.length) {
return false;
}
for (var i = 0; i < path1.length; i++) {
var node1 = path1[i];
for (var j = 0; j < path2.length; j++) {
var node2 = path2[j];
if (node1 === node2) {
break;
}
}
if (j === path2.length) {
return false;
}
}
return true;
}
findAllCycles();
console.log(cycles);
</script>
how can I improve the performance.
I think you could try things differently.
You could calculate for each node it's depths. If you ever come to a node that already has a depth, then you have a cycles.
This algorithm would be in O(n) where n is the number of node. It should be much faster.
If you don't care about depth you could just "tag" the node.
I believe the problem is not the implementation of your algorithm. This graph is deceptively complicated, apparently containing a total of 3930 cycles! Including 39 chordless cycles plus 3891 cycles with chords (which include smaller cycles inside).
This is similar to the "how many squares" problem, it can be surprising how quickly it adds up.
You may be able to optimize significantly if you are only interested in chordless cycles.
(Side note: the equals function seems overly complicated, but this is presumably doesn't significantly affect performance)
function pathIsEqual(path1, path2) {
if (path1.length !== path2.length) {
return false
}
for(var i = path1.length; i--;) {
if(path1[i] !== path2[i]){
return false
}
}
return true;
}
I'm trying to animate a solution to the latin-square-problem in javascript.
To do so, I wrote the recursive backtracking algorithm below.
Solving the problem is initiated by calling search(0,0) and it works just fine, displaying a solution after calculating. But I want it to show an animation on it's progress, in terms of redrawing the whole canvas, after changing the colour of one square.
I tried to incoorporate many of the solutions to similar problems, found on stackoverflow or in tutorials about canvas gameloops. Neither of them worked for me, so I'm presenting the javascript code as close as possible to my pseudo-code algorithm (without any setTimeout's or requestAnimationFrame's)
Here's a working jsfiddle containing all the code.
function search(i, j){
if (latinSquare[i][j] != -1){
//this square is predefined, skip it
searchNext(i, j);
} else {
var colour = latinSquare[i][j];
while(colour < n-1){
colour = colour + 1;
latinSquare[i][j] = colour;
//redraw the whole canvas
drawLatinSquare();
//check if curent constellation is legal
var legal = true;
for (var k = 0; k < n; k++){
if (k != i){
if (latinSquare[k][j] == colour){
legal = false;
break;
}
}
if (k != j){
if (latinSquare[i][k] == colour){
legal = false;
break;
}
}
}
if (legal){
searchNext(i, j);
if (window.found) return;
}
}
latinSquare[i][j] = -1;
}
}
function searchNext(i, j){
if (i < n-1){
//proceed horizontally
search(i+1, j);
} else {
if (j < n-1){
//proceed in the next row
search(0, j+1);
} else {
//we're done
window.found = true;
}
}
}
In this solution, an array is created to hold each iteration of the latinSquare arrays. The timeout interval is a function of the length of the array.
An advantage of this method is that the animation doesn't start until all the calculations are completed, so it runs quite quickly (assuming a solution is found):
var lsa= [];
function drawLatinSquare() {
var l= [];
for(var i = 0 ; i < latinSquare.length ; i++) {
l.push(latinSquare[i].slice());
}
lsa.push(l);
setTimeout(function() {
var ls= lsa.shift();
ctx.clearRect ( 0 , 0 , canvas.width, canvas.height );
ctx.lineWidth= 1;
//draw the grid
for (var i = 0; i < n + 1; i++){
ctx.beginPath();
ctx.moveTo(0,i*21 + 0.5);
ctx.lineTo((n*(21)+1),i*21 + 0.5);
ctx.stroke();
}
for (var j = 0; j < n + 1; j++){
ctx.beginPath();
ctx.moveTo(j*21 + 0.5,0);
ctx.lineTo(j*21 + 0.5,(n*(21)+1));
ctx.stroke();
}
//draw the squares
for (var i = 0; i < n; i++){
for (var j = 0; j < n; j++){
colour = ls[i][j];
if (colour == -1){
colour = "#FFFFFF";
} else {
colour = colours[colour];
}
ctx.fillStyle = colour;
ctx.fillRect((i*21)+1.5,(j*21)+1.5,20,20);
}
}
},10*lsa.length);
} //drawLatinSquare
Fiddle
You can just wrap the call to the main compute function to have it display then delay the call to the actual compute function :
function search(i,j) {
drawLatinSquare();
setTimeout(function() { _search(i,j)} , 15);
}
function _search(i, j){
//... your real search function
issue being that there are too many combinations to see them all for a 'big' n : you should make a choice about what you want to show i fear.
Also if i was you i'd do a first pass to see the number of iterations, so that you can display a progress bar or like.
https://jsfiddle.net/ezstfj9f/4/