can someone tell why this does not work?
the code does print "generating fish" but than not printing enything...
function fish(x, y, degree, genes, Snumber) {
this.x = x;
this.y = y;
this.dgree = degree;
this.energy = 50;
this.genes = genes;
this.Snumber = Snumber;
}
fishs = new Array(10);
Snumber = 0;
document.writeln("generating fish");
for (i = 0; i < 10; i++) {
x = Math.round(Math.random * 600);
y = Math.round(Math.random * 600);
degree = Math.round(Math.random * 360);
genes + new Array(12);
for (j = 0; j < 12; j++) {
genes[j] = Math.random * 2 - 1;
}
fishs[i] = new fish(x, y, degree, genes, Snumber);
Snumber++;
document.writeln("genarating fish num" + i);
}
You have couple of errors and warnings in your code:
1.) You don't user the var keyword, so you automatically put the variables on the global scope.
2.) You use a + operator instead of an = in the line:
genes + new Array(12);
3.) You use Math.random (wich returns the random function, not a random number) instead of the function in 3 places.
4.) You use document.write(ln), which is deprecated. Use console.log instead (which prints to the console, hit F12 to see it)
Related
I wrote a javascript version of Lagrange algorithm, but it kept going wrong when I run it, I don't know what went wrong.
I use this to calculate time.
When I pass a cSeconds as a variable, sometimes it returns a minus value which is obviously wrong...
function LagrangeForCat(cSeconds){
var y = [2592000,7776000,15552000,31104000,93312000,155520000,279936000,404352000,528768000,622080000,715392000,870912000,995328000,1119744000,1244160000,1368576000,1492992000,1617408000,1741824000,1866240000,1990656000,2115072000,2239488000,2363904000,2488320000,2612736000,2737152000,2861568000,2985984000,3110400000,3234816000,3359232000,3483648000,3608064000];
var x = [604800,1209600,1814400,2592000,5184000,7776000,15552000,23328000,31104000,46656000,62208000,93312000,124416000,155520000,186624000,217728000,248832000,279936000,311040000,342144000,373248000,404352000,435456000,466560000,497664000,528768000,559872000,590976000,622080000,653184000,684288000,715392000,746496000,777600000];
var l = 0.0;
for (var j = 0; j < 34; j++) {
var s = 1.0;
for (var i = 0; i < 34; i++) {
if (i != j)
s = s * ((cSeconds - x[i]) / (x[j] - x[i]));
}
l = l + s * y[j];
}
var result = l / (24 * 60 * 60);
var Days = Math.floor(result);
//get float seconds data
var littleData = String(result).split(".")[1];
var floatData = parseFloat("0."+littleData);
var second = floatData *60*60*24;
var hours = Math.floor(second/(60*60));
var minutes = Math.floor(second % 3600/60);
var seconds = Math.floor(second % 3600) % 60;
var returnData = {days:Days,hours: hours + ':' + minutes + ':' + seconds}
return returnData;
}
I don't believe the issue is with your code but with the data set.
I tried a few things, for instance if you have cSeconds = one of the x values, then you get the correct result (I could check that it was equal to the matching y value).
I put all the data in open office and drew the graph it was like the square root function but more extreme (the 'straight' part look very straight) then I remembered that when you interpolate you usually get a polynomial that crosses the points you want but can be very wild outside between the point.
To test my theory I modified the algorithm to control at which x/y index to start and tried for all the values:
for (let i = 0; i < 35; ++i) {
LagrangeForCat(63119321, i, 34)
}
Together with a console.log inside LagrangeForCat it gives me the interpolated y value if I use all the x/y arrays (i=0), if I ignore the first x/y point (i=1), the first two (i=2), ...
00-34 -6850462776.278063
01-34 549996977.0003194
02-34 718950902.7592317
03-34 723883771.1443908
04-34 723161627.795225
05-34 721857113.1756063
06-34 721134873.0889213
07-34 720845478.4754647
08-34 720897871.7910147
09-34 721241470.2886044
10-34 722280314.1033486
11-34 750141284.0070543
12-34 750141262.289736
13-34 750141431.2562406
14-34 750141089.6980047
15-34 750141668.8768387
16-34 750142353.3267975
17-34 750141039.138794
18-34 750141836.251831
19-34 750138039.6240234
20-34 750141696.7529297
21-34 750141120.300293
22-34 750141960.4248047
23-34 750140874.0966797
24-34 750141337.5
25-34 750141237.4694824
26-34 750141289.2150879
27-34 750141282.5408936
28-34 750141284.2094421
29-34 750141283.987999
30-34 750141284.0002298
31-34 750141284.0000689
32-34 750141283.9999985
33-34 3608064000
34-34 0
Exclude 33-34 and 34-34 (there's just not enough data to interpolate).
For the example x=63119321 you'd expect y to be between 715392000 and 870912000 you can see that if you ignore the first 2-3 values the interpolation is "believable", if you ignore more values you interpolate based off the very straight part of the curve (see how consistent the interpolation is from 11-34 onward).
I use to work on a project where interpolation was needed, to avoid those pathological cases we opted for linear interpolation trading accuracy for security (and we could generate all the x/y points we wanted). In your case I'd try to use a smaller set, for instance only two values smaller than cSeconds and two greater like this:
function LagrangeForCat(cSeconds) {
var x = [...];
var y = [...];
let begin = 0,
end = 34
for (let i = 0; i < 34; ++i) {
if (cSeconds < x[i]) {
begin = (i < 3) ? 0 : i - 2
end = (i > (x.length - 1)) ? x.length : i + 1
break
}
}
let result = 0.0;
for (let i = begin; i < end; ++i) {
let term = y[i] / (24 * 60 * 60)
for (let j = begin; j < end; ++j) {
if (i != j)
term *= (cSeconds - x[j]) / (x[i] - x[j]);
}
result += term
}
var Days = Math.floor(result);
// I didn't change the rest of the function didn't even looked at it
}
If you find this answer useful please consider marking it as answered it'd be much appreciated.
I'm writing a mini-game in EaselJS that requires mouse clicks on a grid of tiles.
However, it appears that it's only partially working - or perhaps not assigning a unique Event to each bitmap. During creation, I assign a simple ID - a number counting up per iteration, and expect to get that back.... but no matter where I click, out of 49 objects on stage (hexagon tiles), it only reports back 48....every time. I have enabled stage.enableMouseOver(20), which I initially forgot, but it did not help.
function BuildGround()
{
var i = 0;
for (var x = 0; x < 7; x++)
{
for (var y = 0; y < 7; y++)
{
var h = 102;
var s = h/Math.cos(30*Math.PI/180)/2;
var tempTile = new createjs.Sprite(Tiles, 0);
WorldContainer.addChild(tempTile);
tempTile.regX = 64;
tempTile.regY = 64;
tempTile.id = i;
tempTile.x = x * s * 1.5;
tempTile.y = y * h + (x % 2) * h / 2;
tempTile.addEventListener("click", function(event) { alert(tempTile.id); })
TileArray.push(tempTile);
i++;
console.log(i);
}
}
WorldContainer.x = 155;
WorldContainer.y = 150;
}
My guess, you are experiencing context problem of JavaScript, try this:
tempTile.addEventListener("click", function(event) { alert(event.target.id); })
All events objects have a target element, usually the one which triggered it.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I'm trying to make a hover for every tile, but when I use tileArray[i].x it uses the last tiles position. And I'm trying to get the position of the tile I'm hovering.
Here is the code I've made.
for (x = 0; x < mapxtiles; x++) {
for (y = 0; y < mapytiles; y++) {
if(map[x][y].height != 'x') {
i++;
var topPos = (x * 16) + (y * 16) - 24;
var leftPos = (y * 32) - (x * 32) + (mapxtiles * 32) - 32;
var normalTileTexture = PIXI.Texture.fromImage("./assets/map/normal.png");
var tileHoverTexture = PIXI.Texture.fromImage("./assets/map/hoverTexture.png");
tileArray[i] = new PIXI.Sprite(normalTileTexture);
tileArray[i].setInteractive(true);
var tileHover = new PIXI.Sprite(tileHoverTexture);
tileArray[i].mouseover = function(mouseData) {
tileHover.position = new PIXI.Point(tileArray[i].x - 2, tileArray[i].y + 22);
floorMap.addChild(tileHover);
};
tileArray[i].position = new PIXI.Point(leftPos, topPos);
floorMap.addChild(tileArray[i]);
}
}
}
i is a counter which has reached a certain value at the end of your loop. if you hover your tile, it will always have the last value. a workaround for that, is to wrap your code in a closure:
(function (a) {
tileArray[a].mouseover = function(mouseData) {
tileHover.position = new PIXI.Point(tileArray[a].x - 2, tileArray[a].y + 22);
floorMap.addChild(tileHover);
};
})(i);
what i do here:
i wrap your event-handler in an iife with i as parameter and recieve it as a inside the closure. this is for illustration purposes, you could of course leave the inner var by the name of i
it is also a little bit more readable, to just move it into a function which is declared outside of your loop:
function helperfunction (tileArrayElement, tileHover, floorMap) {
tileArrayElement.mouseover = function(mouseData) {
tileHover.position = new PIXI.Point(tileArrayElement.x - 2, tileArrayElement.y + 22);
floorMap.addChild(tileHover);
};
}
and call it in your loop:
for (x = 0; x < mapxtiles; x++) {
for (y = 0; y < mapytiles; y++) {
if(map[x][y].height != 'x') {
// your other code...
helperfunction(tileArray[i], tileHover, floorMap);
// your other code...
}
}
}
I am attempting to do some data processing on the client side but it has proven to be more difficult than I originally thought.
I use a double for loop so it will call the following function 31^2 times and store a table of promises.
var getPearsonsCorrelation = function(x, y){
// var deferred = $q.defer();
//I commented the promise statements out
//so you can copy paste into your own browser to try a small array
var shortestArrayLength = 0;
if(x.length === y.length){shortestArrayLength = x.length;}
else if(x.length > y.length || y.length < x.length){
deferred.reject('array lenghts are not the same size');
}
var xy = [];
var x2 = [];
var y2 = [];
var sumX = 0;
var sumY = 0;
var sumXy = 0;
var sumX2 = 0;
var sumY2 = 0;
var partOneCounter = 0;
var partTwoCounter = 0;
function partThree(sumX, sumY, sumXy, sumX2, sumY2){
var step1 = (shortestArrayLength * sumXy) - (sumX * sumY);
var step2 = (shortestArrayLength * sumX2) - (sumX * sumX);
var step3 = (shortestArrayLength * sumY2) - (sumY * sumY);
var step4 = Math.sqrt(step2 * step3);
var answer = step1 / step4;
console.log(answer);
//deferred.resolve(answer);
}
function partTwo(xy, x2, y2){
if(partTwoCounter>= shortestArrayLength){
partThree(sumX, sumY, sumXy, sumX2, sumY2);
}else{
sumX += x[partTwoCounter];
sumY += y[partTwoCounter];
sumXy += xy[partTwoCounter];
sumX2 += x2[partTwoCounter];
sumY2 += y2[partTwoCounter];
setTimeout(partTwo(xy, x2, y2), 0);
partTwoCounter++;
}
}
function partOne(partTwo){
if(partOneCounter>=shortestArrayLength){
partTwo(xy, x2, y2);
}else{
xy.push(x[partOneCounter] * y[partOneCounter]);
x2.push(x[partOneCounter] * x[partOneCounter]);
y2.push(y[partOneCounter] * y[partOneCounter]);
setTimeout(partOne(partTwo), 0);
partOneCounter++;
}
}
partOne(partTwo);
//return deferred.promise;
};
I got this script from stevegardner, however as it currently is it is blocking javascript.
http://stevegardner.net/2012/06/11/javascript-code-to-calculate-the-pearson-correlation-coefficient/
In my attempt to make it async javascript, I now get callstack overflow errors instead. Is there some work around for this?
Appreciate it!
When you want to use setTimeout do not invoke the function. You should pass a noninvoked function.
calculate function(){
/* --- */
}
setTimeout(calculate(),0) //wrong
setTimeout(calculate,0) //right
//And if you want to pass in params into the setTimeout
setTimeout(function(){
calculate(params)
},0)
#Benjamin Gruenbaum thanks!
I've written the following Javascript:
(function () {
var computationModule = (function foo1(stdlib, foreign, heap) {
"use asm";
var sqrt = stdlib.Math.sqrt,
heapArray = new stdlib.Int32Array(heap),
outR = 0.0,
outI = 0.0;
function computeRow(canvasWidth, canvasHeight, limit, max, rowNumber, minR, maxR, minI, maxI) {
canvasWidth = +canvasWidth;
canvasHeight = +canvasHeight;
limit = +limit;
max = max | 0;
rowNumber = +rowNumber;
minR = +minR;
maxR = +maxR;
minI = +minI;
maxI = +maxI;
var columnNumber = 0.0,
zReal = 0.0,
zImaginary = 0.0,
numberToEscape = 0;
var columnNumberInt = 0;
// Compute the imaginary part of the numbers that correspond to pixels in this row.
zImaginary = +(((maxI - minI) * +rowNumber) / +canvasHeight + minI);
// Iterate over the pixels in this row.
// Compute the number of iterations to escape for each pixel that will determine its color.
for (columnNumber = +0; + columnNumber < +canvasWidth; columnNumber = +(+columnNumber + 1.0)) {
// Compute the real part of the number for this pixel.
zReal = +(((maxR - minR) * +columnNumber) / +canvasWidth + minR);
numberToEscape = howManyToEscape(zReal, zImaginary, max, limit) | 0;
columnNumberInt = columnNumberInt + 1 | 0;
heapArray[(columnNumberInt * 4) >> 2] = numberToEscape | 0;
}
}
// Function to determine how many iterations for a point to escape.
function howManyToEscape(r, i, max, limit) {
r = +r;
i = +i;
max = max | 0;
limit = +limit;
var j = 0,
ar = 0.0,
ai = 0.0;
ar = +r;
ai = +i;
for (j = 0;
(j | 0) < (max | 0); j = (j + 1) | 0) {
iteratingFunction(ar, ai, r, i)
ar = outR;
ai = outI;
if (+(ar * ar + ai * ai) >= +(limit * limit))
return j | 0;
}
return j | 0;
}
// The iterating function defining the fractal to draw
// r and i are the real and imaginary parts of the value from the previous iteration
// r0 and i0 are the starting points
function iteratingFunction(r, i, r0, i0) {
r = +r;
i = +i;
r0 = +r0;
i0 = +i0;
computePower(r, i, 2);
// Set the output from this function to t
outR = +(r0 + outR);
outI = +(i0 + outI);
}
// Compute the result of [r,i] raised to the power n.
// Place the resulting real part in outR and the imaginary part in outI.
function computePower(r, i, n) {
// Tell asm.js that r, i are floating point and n is an integer.
r = +r;
i = +i;
n = n | 0;
// Declare and initialize variables to be numbers.
var rResult = 0.0;
var iResult = 0.0;
var j = 0;
var tr = 0.0;
var ti = 0.0;
// Declare and initialize variables that will be used only in the
// event we need to compute the reciprocal.
var abs = 0.0;
var recr = 0.0;
var reci = 0.0;
if ((n | 0) < (0 | 0)) {
// For n less than 0, compute the reciprocal and then raise it to the opposite power.
abs = +sqrt(r * r + i * i);
recr = r / abs;
reci = -i / abs;
r = recr;
i = reci;
n = -n | 0;
}
rResult = r;
iResult = i;
for (j = 1;
(j | 0) < (n | 0); j = (j + 1) | 0) {
tr = rResult * r - iResult * i;
ti = rResult * i + iResult * r;
rResult = tr;
iResult = ti;
}
outR = rResult;
outI = iResult;
} // end computePower
return {
computeRow: computeRow
};
})(self, foreign, heap);
// Return computationModule that we just defined.
return computationModule;
})();
There's nothing particularly unusual about this Javascript, except that I want to make my web application display the Javascript in an ACE text editor (http://ace.c9.io/) so that the user can modify the code at runtime.
I load the Javascript using jQuery AJAX and then set the contents of the ACE Editor to the Javascript code. After the user modifies the code, he can click a button to run the code. (This uses eval)
The problem I'm having is that ACE is displaying strange characters instead of spaces.
Oddly enough, if I try to copy text from the ACE editor, the strange characters disappear and the spaces are normal. Furthermore, the code runs fine even with these strange characters being displayed.
I also noticed that the problem does not appear when using Firefox, but it appears for Chrome and IE 11.
Finally, the problem only occurs when I put the code on a real web server. It doesn't reproduce in my development environment.
Looking at this some more, I can see that it's not just the text I'm loading via AJAX. Even when I type new spaces, more text characters appear!
What could be going wrong so that the text doesn't display properly?
Here's a link to the application: http://danielsadventure.info/html5fractal/
Use charset="utf-8" in the script tag where you include ace.
<script src="path/to/ace.js" charset="utf-8">
This may have something to do with this:
When no explicit charset parameter is provided by the sender, media
subtypes of the "text" type are defined to have a default charset
value of "ISO-8859-1" when received via HTTP. Data in character sets
other than "ISO-8859-1" or its subsets MUST be labeled with an
appropriate charset value. See section 3.4.1 for compatibility
problems.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
So the string passed to the script are in an encoding different than what ACE (or JS in general) expects, which is UTF-8.