Javascript Bradley adaptive thresholding implementation - javascript

I have been trying to implement Bradley Adaptive thresholding. I know there is a python code in one of the stack overflow questions. But i am struggling to implement the same in JS by following that. Can anyone please help me? So far my code is:
function computeAdaptiveThreshold (imagetest,imageWidth,imageHeight,callback)
{
var size = imageWidth*imageHeight*4;
var s = imageWidth/8;
var s2=s>>1;
var t=0.15;
var it=1.0-t;
var i,j,diff,x1,y1,x2,y2,ind1,ind2,ind3;
var sum=0;
var ind=0;
var integralImg = [];
var canvas = document.createElement('canvas');
var bin = canvas.getContext('2d').createImageData(imageWidth, imageHeight);
for(i=0;i<imageWidth;i++)
{
sum = 0;
for(j=0;j<imageHeight;j++)
{
index = i *imageHeight + j;
sum += imagetest.data[index];
if(i== 0)
{
integralImg[index] = sum;
}
else
{
//index = (i-1) * height + j;
integralImg[index] = integralImg[(i-1) * imageHeight + j] + sum;
}
}
}
x1=0;
for(i=1;i<imageWidth;++i)
{
sum=0;
ind=i;
ind3=ind-s2;
if(i>s)
{
x1=i-s;
}
diff=i-x1;
for(j=0;j<imageHeight;++j)
{
sum+=imagetest.data[ind];// & 0xFF;
integralImg[ind] = integralImg[(ind-1)]+sum;
ind+=imageWidth;
if(i<s2)continue;
if(j<s2)continue;
y1=(j<s ? 0 : j-s);
ind1=y1*imageWidth;
ind2=j*imageWidth;
if (((imagetest.data[ind3])*(diff * (j - y1))) < ((integralImg[(ind2 + i)] - integralImg[(ind1 + i)] - integralImg[(ind2 + x1)] + integralImg[(ind1 + x1)])*it)) {
bin.data[ind3] = 0;
} else {
bin.data[ind3] = 255;
}
ind3 += imageWidth;
}
}
y1 = 0;
for( j = 0; j < imageHeight; ++j )
{
i = 0;
y2 =imageHeight- 1;
if( j <imageHeight- s2 )
{
i = imageWidth - s2;
y2 = j + s2;
}
ind = j * imageWidth + i;
if( j > s2 ) y1 = j - s2;
ind1 = y1 * imageWidth;
ind2 = y2 * imageWidth;
diff = y2 - y1;
for( ; i < imageWidth; ++i, ++ind )
{
x1 = ( i < s2 ? 0 : i - s2);
x2 = i + s2;
// check the border
if (x2 >= imageWidth) x2 = imageWidth - 1;
if (((imagetest.data[ind])*((x2 - x1) * diff)) < ((integralImg[(ind2 + x2)] - integralImg[(ind1 + x2)] - integralImg[(ind2 + x1)] + integralImg[(ind1 + x1)])*it)) {
bin.data[ind] = 0;
} else {
bin.data[ind] = 255;
}
}
}
callback(bin);`
I am getting very bad images. I should say i cannot call it as a image.

I think your first effort should be to refactor your code : it will be much easier to handle the index.
Then you'll see that you have issues with your indexes : an image -even a gray one- is an RGBA Array, meaning 4 bytes = 32 bits per pixel.
You could handle this by doing a conversion RGBA-> b&W image, then thresholding, then doing b&w -> RGBA back.
...Or handle the RGBA components as you go. Notice that here you only want to output black or white, so you can create an Int32 view on the array, and write at once R,G,B,A for each pixels.
So some code (working here : http://jsfiddle.net/gamealchemist/3zuopz19/8/ ) :
function computeAdaptiveThreshold(sourceImageData, ratio, callback) {
var integral = buildIntegral_Gray(sourceImageData);
var width = sourceImageData.width;
var height = sourceImageData.height;
var s = width >> 4; // in fact it's s/2, but since we never use s...
var sourceData = sourceImageData.data;
var result = createImageData(width, height);
var resultData = result.data;
var resultData32 = new Uint32Array(resultData.buffer);
var x = 0,
y = 0,
lineIndex = 0;
for (y = 0; y < height; y++, lineIndex += width) {
for (x = 0; x < width; x++) {
var value = sourceData[(lineIndex + x) << 2];
var x1 = Math.max(x - s, 0);
var y1 = Math.max(y - s, 0);
var x2 = Math.min(x + s, width - 1);
var y2 = Math.min(y + s, height - 1);
var area = (x2 - x1 + 1) * (y2 - y1 + 1);
var localIntegral = getIntegralAt(integral, width, x1, y1, x2, y2);
if (value * area > localIntegral * ratio) {
resultData32[lineIndex + x] = 0xFFFFFFFF;
} else {
resultData32[lineIndex + x] = 0xFF000000;
}
}
}
return result;
}
function createImageData(width, height) {
var canvas = document.createElement('canvas');
return canvas.getContext('2d').createImageData(width, height);
}
function buildIntegral_Gray(sourceImageData) {
var sourceData = sourceImageData.data;
var width = sourceImageData.width;
var height = sourceImageData.height;
// should it be Int64 Array ??
// Sure for big images
var integral = new Int32Array(width * height)
// ... for loop
var x = 0,
y = 0,
lineIndex = 0,
sum = 0;
for (x = 0; x < width; x++) {
sum += sourceData[x << 2];
integral[x] = sum;
}
for (y = 1, lineIndex = width; y < height; y++, lineIndex += width) {
sum = 0;
for (x = 0; x < width; x++) {
sum += sourceData[(lineIndex + x) << 2];
integral[lineIndex + x] = integral[lineIndex - width + x] + sum;
}
}
return integral;
}
function getIntegralAt(integral, width, x1, y1, x2, y2) {
var result = integral[x2 + y2 * width];
if (y1 > 0) {
result -= integral[x2 + (y1 - 1) * width];
if (x1 > 0) {
result += integral[(x1 - 1) + (y1 - 1) * width];
}
}
if (x1 > 0) {
result -= integral[(x1 - 1) + (y2) * width];
}
return result;
}

Related

createPattern on canvas issue

As on the attached fiddle, the background image on the canvas is just coming and getting disappearing
I tried both createPattern and drawImage both are having same issue.
I am not an expert in Canvas. Any help would be appreciated
(function(){
var canvas = document.getElementById('c'),
/** #type {CanvasRenderingContext2D} */
ctx = canvas.getContext('2d'),
width = 400,
height = 400,
half_width = width >> 1,
half_height = height >> 1,
size = width * (height + 2) * 2,
delay = 30,
oldind = width,
newind = width * (height + 3),
riprad = 3,
ripplemap = [],
last_map = [],
ripple,
texture,
line_width = 20,
step = line_width * 2,
count = height / line_width;
canvas.width = width;
canvas.height = height;
/*
* Water ripple demo can work with any bitmap image
*/
var imageObj = new Image();
imageObj.onload = function() {
var pattern = ctx.createPattern(imageObj, 'repeat');
ctx.rect(0, 0, width, height);
ctx.fillStyle = pattern;
ctx.fill();
ctx.save();
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';
with (ctx) {
fillStyle = '#ccc';
fillRect(0, 0, width, height);
fillStyle = '#999999';
save();
rotate(-0.785);
for (var i = 0; i < count; i++) {
fillRect(-width, i * step, width * 3, line_width);
}
}
texture = ctx.getImageData(0, 0, width, height);
ripple = ctx.getImageData(0, 0, width, height);
for (var i = 0; i < size; i++) {
last_map[i] = ripplemap[i] = 0;
}
/**
* Main loop
*/
function run() {
newframe();
ctx.putImageData(ripple, 0, 0);
}
/**
* Disturb water at specified point
*/
function disturb(dx, dy) {
dx <<= 0;
dy <<= 0;
for (var j = dy - riprad; j < dy + riprad; j++) {
for (var k = dx - riprad; k < dx + riprad; k++) {
ripplemap[oldind + (j * width) + k] += 128;
}
}
}
/**
* Generates new ripples
*/
function newframe() {
var a, b, data, cur_pixel, new_pixel, old_data;
var t = oldind; oldind = newind; newind = t;
var i = 0;
// create local copies of variables to decrease
// scope lookup time in Firefox
var _width = width,
_height = height,
_ripplemap = ripplemap,
_last_map = last_map,
_rd = ripple.data,
_td = texture.data,
_half_width = half_width,
_half_height = half_height;
for (var y = 0; y < _height; y++) {
for (var x = 0; x < _width; x++) {
var _newind = newind + i, _mapind = oldind + i;
data = (
_ripplemap[_mapind - _width] +
_ripplemap[_mapind + _width] +
_ripplemap[_mapind - 1] +
_ripplemap[_mapind + 1]) >> 1;
data -= _ripplemap[_newind];
data -= data >> 5;
_ripplemap[_newind] = data;
//where data=0 then still, where data>0 then wave
data = 1024 - data;
old_data = _last_map[i];
_last_map[i] = data;
if (old_data != data) {
//offsets
a = (((x - _half_width) * data / 1024) << 0) + _half_width;
b = (((y - _half_height) * data / 1024) << 0) + _half_height;
//bounds check
if (a >= _width) a = _width - 1;
if (a < 0) a = 0;
if (b >= _height) b = _height - 1;
if (b < 0) b = 0;
new_pixel = (a + (b * _width)) * 4;
cur_pixel = i * 4;
_rd[cur_pixel] = _td[new_pixel];
_rd[cur_pixel + 1] = _td[new_pixel + 1];
_rd[cur_pixel + 2] = _td[new_pixel + 2];
}
++i;
}
}
}
canvas.onmousemove = function(/* Event */ evt) {
disturb(evt.offsetX || evt.layerX, evt.offsetY || evt.layerY);
};
setInterval(run, delay);
// generate random ripples
var rnd = Math.random;
var timeOut;
var intrvl = setInterval(function() {
clearTimeout(timeOut);
disturb(0, (height/40));
disturb((width/2.67), (height/40));
disturb((width/1.33), (height/40));
disturb(0, (height/2.67));
disturb((width/2.67), (height/2.67));
disturb((width/1.33), (height/2.67));
disturb(0, (height/1.33));
disturb((width/2.67), (height/1.33));
disturb((width/1.33), (height/1.33));
timeOut= setTimeout(function(){
disturb((width/1.8), (height/8));
disturb((width/-1.2), (height/8));
disturb((width/1.14), (height/8));
disturb((width/1.8), (height/2.13));
disturb((width/-1.2), (height/2.13));
disturb((width/1.14), (height/2.13));
disturb((width/1.8), (height/1.03));
disturb((width/-1.2), (height/1.03));
disturb((width/1.14), (height/1.03));;
},300);
}, 700);
setTimeout(function(){
clearInterval(intrvl);
},3000);
})();
this is the link to the fiddle

Fill a 2d Array with circular area

I want an array looking like this:
[
[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0],
]
My first approach was to get the circumference
var steps = 100;
var coord = [];
var x,y;
for (var i = 0; i < steps; i++) {
var phase = 2 * Math.PI * i / steps;
x = Math.round(cenx + range * Math.cos(phase));
y = Math.round(ceny + range * Math.sin(phase))
if(x>=0 && y >=0){
coord.push([x,y]);
}
}
and with the resulting coords i could have juggled around to get the circular area. but i doubt that would be performant.
So my second approach would be to check every entry of the array whether it has a certain distance (i.e. radius) to the center of my circle. but for huge maps that wouldnt be performant either. perhaps checking only in a reasonable frame would be wiser.
but im certain there is a better approach for this problem.
im needing this for a fog of war implementation.
Your second suggested approach of testing each point in the array will be simple to implement, and can be optimized to just one subtract, one multiply and one test per element in the inner loop.
The basic test is ((x - centerX) * (x - centerX)) + ((y - centerY) * (y - centerY)) > radiusSq, but since ((y - centerY) * (y - centerY)) will be constant for a given row you can move that outside the loop.
Given that you have to visit each element in the array and set it anyway (meaning your algorithm will always be O(n2) on the circle radius), the test is a negligible cost:
// circle generation code:
function makeCircle(centerX, centerY, radius, a, arrayWidth, arrayHeight)
{
var x, y, d, yDiff, threshold, radiusSq;
radius = (radius * 2) + 1;
radiusSq = (radius * radius) / 4;
for(y = 0; y < arrayHeight; y++)
{
yDiff = y - centerY;
threshold = radiusSq - (yDiff * yDiff);
for(x = 0; x < arrayWidth; x++)
{
d = x - centerX;
a[y][x] = ((d * d) > threshold) ? 0 : 1;
}
}
}
// test code:
var width = 7;
var dim = (width * 2) + 1;
var array = new Array(dim);
for(row = 0; row < dim; row++)
array[row] = new Array(dim);
makeCircle(width, width, width, array, dim, dim);
for(var y = 0, s = ""; y < dim; y++)
{
for(var x = 0; x < dim; x++)
{
s += array[y][x];
}
s += "<br>";
}
document.body.innerHTML += s + "<br>";
I would use the mid-point circle algorithm and see the array as a bitmap.
I did this JavaScript implementation a while back, modified here to use an array as target source for the "pixel". Just note that a circle will produce odd widths and heights as the distance is always from a single center point and we can only use integer values in this case.
Tip: For speed improvements you could use typed array instead of a regular one (shown below).
Example
Make sure to use integer values as input, the code will clip values outside the "bitmap"/array -
var width = 7, height = 7,
array = new Uint8Array(width * height);
// "draw" circle into array
circle(3, 3, 3);
renderDOM();
// circle example 2
width = height = 17;
array = new Uint8Array(width * height);
circle(8, 8, 8);
renderDOM();
function circle(xc, yc, r) {
if (r < 1) return;
var x = r, y = 0, // for Bresenham / mid-point circle
cd = 0,
xoff = 0,
yoff = r,
b = -r,
p0, p1, w0, w1;
while (xoff <= yoff) {
p0 = xc - xoff;
p1 = xc - yoff;
w0 = xoff + xoff;
w1 = yoff + yoff;
hl(p0, yc - yoff, yc + yoff, w0); // fill a "line"
hl(p1, yc - xoff, yc + xoff, w1);
if ((b += xoff+++xoff) >= 0) {
b -= --yoff + yoff;
}
}
// for fill
function hl(x, y1, y2, w) {
w++;
var xw = 0;
while (w--) {
xw = x + w;
setPixel(xw, y1);
setPixel(xw, y2);
}
}
function setPixel(x, y) {
if (x < width && y < height && x >= 0 && y >= 0)
array[y * width + x] = 1;
}
}
function renderDOM() {
for(var i = 0, str = ""; i < array.length; i++) {
if (i > 0 && !(i % width)) str += "<br>";
str += array[i];
}
document.body.innerHTML += str + "<br><br>";
}
body {font:18px monospace}
For an odd-sized array (2r+1 x 2r+1),
for (row= 0; row < 2 * r + 1; row++)
{
f= (row + 1) * (row - 2 * r - 1) + r * r + r;
for (col= 0; col < 2 * r + 1; f+= 2 * (col - r) + 1; col++)
{
array[row][col]= f >= 0;
}
}

Filtering specific range of numbers from an array

I'm creating an algorithm that will blur the border of a canvas(image). Before applying the blur effect, I am creating an array filtered that includes all pixel values that needs to be blurred.
I've created an example with a 10×10px image.
function compute(w, h, bW) {
w *= 4;
var ignored = [];
for (y = bW; y < (h - bW); y++) {
for (x = 0; x < (w - (bW * 4 * 2)); x++) {
ignored.push(w * y + x + bW * 4);
}
}
console.log(ignored);
function range(limit) {
return Array.apply(null, Array(limit)).map(function(_, i) {
return i;
})
}
Array.prototype.diff = function(array) {
return this.filter(function(elem) {
return array.indexOf(elem) === -1;
})
}
var filtered = range(w * h).diff(ignored);
console.log(filtered);
return filtered;
}
compute(10, 10, 2);
//////////////////////////////////////////////////////////////////
// Below is just to display the numbers that are being filtered //
// Here, the size is 100 x 100 px with 10px border width //
//////////////////////////////////////////////////////////////////
var pixels = compute(100, 100, 10);
var c = document.getElementsByTagName('canvas')[0];
var ctx = c.getContext('2d');
var imgD = ctx.createImageData(100, 100);
for (var i = 0; i < imgD.data.length; i += 4) {
if (pixels.indexOf(i) > 0) {
imgD.data[i + 0] = 0;
imgD.data[i + 1] = 0;
imgD.data[i + 2] = 0;
imgD.data[i + 3] = 255;
} else {
imgD.data[i + 0] = 255;
imgD.data[i + 1] = 0;
imgD.data[i + 2] = 0;
imgD.data[i + 3] = 255;
}
}
ctx.putImageData(imgD, 10, 10);
<canvas></canvas>
The array filtered contains all the numbers that has the background color and ignored contains all the numbers that has the background color and in the image.
My question is:
How do I change my code so that the array filtered will have the numbers with background color and and not ?
An Example on a bit high resolution(65×65px):
FIDDLEJS : http://jsfiddle.net/t14gr6pL/2/
Explanation:
It depends on the width of your triangles (the second color). In the 64*64 example, this width is 7.
Let's assume that this width (tw) is calculate like this (you can change) :
var tw = (2 * bW) - 1;
So your code would be:
function compute(w, h, bW) {
var filtered = [];
var WIDTH_MULTIPLICATOR = 4;
var bH = bW;
w *= WIDTH_MULTIPLICATOR;
bW *= WIDTH_MULTIPLICATOR;
var triangleWidth = (2 * bW) - 1;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
if (
// Borders
(Math.min(x, w - x) < bW) ||
(Math.min(y, h - y) < bH) ||
// Adding "Triangles"
(Math.min(x, w - x) < bW + triangleWidth - Math.max(0, Math.min(y, h - y) - bH) * WIDTH_MULTIPLICATOR)
) {
filtered.push(w * y + x);
}
}
}
return filtered;
}

For-Loop doesn't finish without error message

I have this for-loop:
y1 = 0; y2 = 3264; x1 = 0; x2 = 4928; uc = 1; vc = 1; scale = 1;
for (var y = y1; y < y2; y++) {
for (var x = x1; x < x2; x++) {
sumR = 0;
sumG = 0;
sumB = 0;
i = 0;
for (var v = -vc; v <= vc; v++) {
for (var u = -uc; u <= uc; u++) {
if (kernel[i] != 0) {
var tempX = x + u < 0 ? 0 : x + u;
var tempY = y + v < 0 ? 0 : y + v;
tempX = tempX >= width ? width - 1 : tempX;
tempY = tempY >= height ? height - 1 : tempY;
sumR += pixels.data[((tempY * (pixels.width*4)) + (tempX * 4)) + 0] * kernel[i];
sumG += pixels.data[((tempY * (pixels.width*4)) + (tempX * 4)) + 1] * kernel[i];
sumB += pixels.data[((tempY * (pixels.width*4)) + (tempX * 4)) + 2] * kernel[i];
}
i++;
}
}
tempArray.push(sumR * scale, sumG * scale, sumB * scale, 255);
}
console.log(y + "|" + y2);
}
So basically it's about image processing, the loop stops at y = 3115 without any error, everything after the loop isn't computed it just "crashes" there. Do you guys have any ideas how this could happen? Can there be a problem with memory?
UPDATE: I think I made this abit unclear: if I use this algorithm for a image with size y2 = 1000 and x2 = 1000 everything is working fine. But if the images get bigger it just stopps working, there is no errormessage in the console!
uc + vc = 1; is a invalid statement,
uc and vc don't seem to be defined anywhere,
scale isn't defined anywhere.
The second x1 here should probably be x2:
x1 = 0; x1 = 4928;
//Should probably be:
x1 = 0; x2 = 4928;
This pretty much comes down to: "debug your code".
Okay finally I found the problem,
I initialized the array this way: var tempArray = []; above the for-loops, next step was that I tried to initialize it this way : var tempArray = new Array(width * height * 4)
The browser just stopped at that position now and didn't even enter the for-loops. So I guess the Array is just to big to create.
Solution: I am using a Typed Array now and everything is working:
var tempArray = new Uint8ClampedArray(width * height * 4);

I cannot generate smooth Simplex noise in Javascript

I've tried everything and read every single link I can see on the internet regarding Perlin Noise or Simplex Noise and even dissected a few Javascript examples that I see work fine.
But I still get very random looking images... essentially just TV static.
My code is below. I'm using a random number generator so that I can seed a value, but I've tried with Math.random as well.
As near as I can tell, the different images generated at the different octaves aren't interpolating properly, or maybe the way I'm converting from the Noise function to RGB values is wrong (I've tried to fix both of these issues...).
if (!this.Prng) {
var Prng = function() {
var iMersenne = 2147483647;
var rnd = function(seed) {
if (arguments.length) {
that.seed = arguments[0];
}
that.seed = that.seed*16807%iMersenne;
return that.seed;
};
var that = {
seed: 123,
rnd: rnd,
random: function(seed) {
if (arguments.length) {
that.seed = arguments[0];
}
return rnd()/iMersenne;
}
};
return that;
}();
}
var CSimplexNoise = function(r)
{
this.grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],
[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]];
var p = [];
for(i = 0; i < 256; i++)
p[i] = Math.floor(r.random()*256);
this.perm = new Array();
for(i = 0; i < 512; i++)
{
this.perm[i] = p[i & 255];
}
}
CSimplexNoise.prototype.dot = function(g,x,y)
{
return g[0]*x + g[1]*y;
}
CSimplexNoise.prototype.GenerateSimplexNoise = function(x,y,octaves,persistence)
{
var total = 0;
for(i=0; i < octaves-1; i++)
{
var freq = Math.pow(2,i);
var amp = Math.pow(persistence,i);
total += this.InterpolatedNoise(x*freq,y*freq) * amp;
}
return total;
}
CSimplexNoise.prototype.InterpolatedNoise = function(x,y)
{
var xInt = Math.floor(x);
var xFrac = x - xInt;
var yInt = Math.floor(y);
var yFrac = y - yInt;
var v1 = this.SmoothNoise(xInt,yInt);
var v2 = this.SmoothNoise(xInt + 1,yInt)
var v3 = this.SmoothNoise(xInt,yInt+1)
var v4 = this.SmoothNoise(xInt + 1, yInt + 1);
var i1 = this.LinearInterpolate(v1,v2,xFrac);
var i2 = this.LinearInterpolate(v3,v4,xFrac);
return this.CosineInterpolate(i1,i2,yFrac);
}
CSimplexNoise.prototype.LinearInterpolate = function(a,b,x)
{
return a*(1-x) + b*x;
}
CSimplexNoise.prototype.CosineInterpolate = function(a,b,x)
{
var f = (1 - Math.cos(x*Math.PI)) * 0.5;
return a*(1-f) + b*f;
}
CSimplexNoise.prototype.SmoothNoise = function(x,y)
{
var corners = (this.Noise(x-1,y-1) + this.Noise(x+1,y-1) + this.Noise(x-1,y+1) + this.Noise(x+1,y+1)) / 16;
var sides = (this.Noise(x-1,y) + this.Noise(x+1,y) + this.Noise(x,y-1) + this.Noise(x+1,y+1)) / 8;
var center = this.Noise(x,y) / 4;
return corners + sides + center;
}
CSimplexNoise.prototype.Noise = function(xin, yin)
{
var n0, n1, n2;
var F2 = 0.5*(Math.sqrt(3)-1);
var s = (xin+yin)*F2;
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var G2 = (3-Math.sqrt(3))/6;
var t = (i+j)*G2;
var X0 = i-t;
var Y0 = j-t;
var x0 = xin-X0;
var y0 = yin-Y0;
var i1,j1;
if(x0 > y0)
{
i1 = 1;
j1 = 0;
}
else
{
i1 = 0;
j1 = 1;
}
var x1 = x0 - i1 + G2;
var y1 = y0 - j1 + G2;
var x2 = x0 - 1 + 2 * G2;
var y2 = y0 - 1 + 2 * G2;
var ii = i & 255;
var jj = j & 255;
var gi0 = this.perm[ii + this.perm[jj]] % 12;
var gi1 = this.perm[ii + i1 + this.perm[jj + j1]] % 12;
var gi2 = this.perm[ii + 1 + this.perm[jj + 1]] % 12;
var t0 = 0.5 - x0 * x0 - y0 * y0;
if(t0 < 0)
n0 = 0;
else
{
t0 *= t0;
n0 = t0 * t0 * this.dot(this.grad3[gi0],x0,y0)
}
var t1 = 0.5 - x1 * x1 - y1 * y1;
if(t1 < 0)
n1 = 0;
else
{
t1 *= t1;
n1 = t1 * t1 * this.dot(this.grad3[gi1],x1,y1);
}
var t2 = 0.5 - x2 * x2 - y2 * y2;
if(t2 <0 )
n2 = 0;
else
{
t2 *= t2;
n2 = t2 * t2 * this.dot(this.grad3[gi2],x2,y2);
}
return 70 * (n0 + n1 + n2);
}
$(document).ready(function(){
var context = $('#screen')[0].getContext("2d");
var w = 100;
var h = 100;
var data = context.createImageData(w,h);
var simplexNoise = new CSimplexNoise(Prng);
for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
// var newVal = ((simplexNoise.GenerateSimplexNoise(x,y,5,0.25) - -1) / (1 - -1)) * (255 - 0);
var newVal2 = simplexNoise.GenerateSimplexNoise(x,y,5,0.5)
var newVal = Math.floor(newVal2*256);
newVal = Math.abs(newVal * 2)-0.5;
data.data[((h * y) + x) * 4] = newVal;
data.data[((h * y) + x) * 4+1] = newVal;
data.data[((h * y) + x) * 4+2] = newVal;
data.data[((h * y) + x) * 4+3] = 255;
}
}
context.putImageData(data,0,0);
})
Try sampling simplexNoise.GenerateSimplexNoise(x * 0.05, y * 0.05, 5, 0.5)
The problem may be that your samples are too far apart. (this would result in apparently random behavior, since the simplex noise might go through more than half a wavelength before you sample it)
REVISION: Updated numbers above...
You may actually need to reduce the samples so that there are 20 in a given wavelength of the simplex noise. The average wavelength of most simplex noise is 1, so 0.05 should do the trick. Also, you may want to test with just one octave at first.

Categories

Resources