Creating random pixeled lines in Proccesing - random

I'm trying to make a game and I'm stuck on random level design. Basically, I'm trying to create a line from one edge/corner to another edge/corner while having some randomness to it.
See below image 1 [link broken] and 2 for examples. I'm doing this in processing and every attempt I've tried hasn't yielded proper results. I can get them to populate randomly but not in a line or from edge to edge. I'm trying to do this on a 16 x 16 grid by the way. Any ideas or help would be greatly appreciated thanks!
Image 2:

Based on your description, the challenge is in having a connected line from top to bottom with a bit of randomness driving left/right direction.
There are multiple options.
Here's a basic idea that comes to mind:
pick a starting x position: left's say right down the middle
for each row from 0 to 15 (for 16 px level)
pick a random between 3 numbers:
if it's the 1st go left (x decrements)
if it's the 2nd go right (x increments)
if it's the 3rd: ignore: it means the line will go straight down for this iteration
Here's a basic sketch that illustrates this using PImage to visualise the data:
void setup(){
size(160, 160);
noSmooth();
int levelSize = 16;
PImage level = createImage(levelSize, levelSize, RGB);
level.loadPixels();
java.util.Arrays.fill(level.pixels, color(255));
int x = levelSize / 2;
for(int y = 0 ; y < levelSize; y++){
int randomDirection = (int)random(3);
if(randomDirection == 1) x--;
if(randomDirection == 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level.pixels[x + y * levelSize] = color(0);
}
level.updatePixels();
// render result;
image(level, 0, 0, width, height);
fill(127);
text("click to reset", 10, 15);
}
// hacky reset
void draw(){}
void mousePressed(){
setup();
}
The logic is be pretty plain above, but free to replace random(3) with other options (perhaps throwing dice to determine direction or exploring other psuedo-random number generators (PRNGs) such as randomGaussian(), noise() (and related functions), etc.)
Here's a p5.js version of the above:
let levelSize = 16;
let numBlocks = levelSize * levelSize;
let level = new Array(numBlocks);
function setup() {
createCanvas(320, 320);
level.fill(0);
let x = floor(levelSize / 2);
for(let y = 0 ; y < levelSize; y++){
let randomDirection = floor(random(3));
if(randomDirection === 1) x--;
if(randomDirection === 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level[x + y * levelSize] = 1;
}
// optional: print to console
// prettyPrintLevel(level, levelSize, numBlocks);
}
function draw() {
background(255);
// visualise
for(let i = 0 ; i < numBlocks; i++){
let x = i % levelSize;
let y = floor(i / levelSize);
fill(level[i] == 1 ? color(0) : color(255));
rect(x * 20, y * 20, 20, 20);
}
}
function prettyPrintLevel(level, levelSize, numBlocks){
for(let i = 0; i < numBlocks; i+= levelSize){
print(level.slice(i, i + levelSize));
}
}
function mousePressed(){
setup();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
The data is a structured a 1D array in both examples, however, if it makes it easier it could easily be a 2D array. At this stage of development, whatever is the simplest, most readable option is the way to go.

Related

Processing(Java) to p5js - glitch effect

I'm new in p5js and i want to create a noise effect in an image with it. I create a functional sketch with Java in processing, but when i pass it to p5j something is wrong.
The image is download in the html field hwne i put , but the pixels loc staff doesn't.
Can anyone help me!!
This is my sketch:
function setup()
{
createCanvas(400,300);
img = loadImage("data/monja.jpg");
//surface.setResizable(true);
//surface.setSize(img.width, img.height);
background(0);
}
function draw()
{
loadPixels();
img.loadPixels();
for (let x = 0; x < img.width; x++)
{
for (let y = 0; y < img.height; y++)
{
let loc = x+y*width;
let c = brightness(img.pixels[loc]);
let r = red(img.pixels[loc]);
let g = green(img.pixels[loc]);
let b = blue(img.pixels[loc]);
if (c < 70){
img.pixels[loc]= color(random(255));
}
else {
img.pixels[loc] = color(r, g, b);
}
}
}
updatePixels();
//image(img, 0, 0);
}```
To modify the color of certain pixels in an image here are some things to keep in mind.
When we call loadPixels the pixels array is an array of numbers.
How many numbers each pixel gets is determined by the pixel density
If pixel density is 1 then each pixel will get 4 numbers in the array, each with a value from 0 to 255.
The first number determines the amount of red in the pixel, the second green, the third red and the fourth is the alpha value for transparency.
Here is an example that changes pixels with a high red value to a random gray scale to create a glitch effect.
var img;
var c;
function preload(){
img = loadImage("https://i.imgur.com/rpQdRoY.jpeg");
}
function setup()
{
createCanvas(img.width, img.height);
background(0);
let d = pixelDensity();
img.loadPixels();
for (let i = 0; i < 4 * (img.width*d * img.height*d); i += 4) {
if (img.pixels[i] > 150 && img.pixels[i+1] <100&&img.pixels[i+2] < 100){
let rColor = random(255);
img.pixels[i] = rColor;
img.pixels[i + 1] = rColor;
img.pixels[i + 2] = rColor;
img.pixels[i + 3] = rColor;
}
}
img.updatePixels();
}
function draw() {
image(img,0,0);
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.3.0/lib/p5.js"></script>

Processing - why does my Random Walker always tend toward the top left?

I am currently going through Daniel Shiffman's 'The Nature Of Code', and have been playing around with one of the first exercises - a simple 'RandomWalker()'. I have implemented similar things in Java & had no trouble, however for some reason my walker always seems to go in more or less the same direction:
RandomWalker
This happens 100% of the time. Here is my code:
class Walker
{
int x;
int y;
// Constructor
Walker()
{
x = width / 2;
y = height / 2;
}
void display()
{
stroke(0); // Colour
point(x, y); // Colours one pixel in
}
void step()
{
float stepX;
float stepY;
stepX = random(-1, 1);
stepY = random(-1, 1);
x += stepX;
y += stepY;
}
}
Walker w;
void setup()
{
size(640, 360);
w = new Walker();
background(255);
}
void draw()
{
w.step();
w.display();
}
Is this some artefact of the random function? My first thought is that it's something to do with the pseudorandom nature of the function but the textbook specifically states that this should not be noticeable, and yet this happens every single time. I was wondering if maybe there's something wrong with my code?
Thanks in advance.
Your x and y variables are both int types. That means that they don't have a decimal part, so any time you add or subtract from them, they are truncated. Here are some examples:
int x = 1;
x = x + .5;
//1.5 is truncated, and x stays 1
int x = 1;
x = x - .5;
//.5 is truncated, and x becomes 0
This is why you see your x and y variables only decreasing. To fix this, just change x and y to float types, so they keep track of the decimals.
If you really need x and y to be int values, then you need stepX and stepY to also be int values:
int stepX;
int stepY;
stepX = (int)random(-5, 5);
stepY = (int)random(-5, 5);
x += stepX;
y += stepY;
But you probably just want to store x and y as float values.
PS: I love random walkers!

Processing: Increment a counter when midpoint of ellipses are passed

I've got some code that displays 10 ellipses in random locations on the screen, and a square that descends from the top of the screen to the bottom, at which point it resets back at the top. What I'm trying to do is get a counter to increment when that square passes any of the ellipses (by comparing their y-positions). However, the counter increases rapidly instead of steadily and just doesn't behave desirably in general.
Here's my draw() function. barriers[i][0] stores the x-pos, barriers[i][1] the y-pos obviously.
void draw()
{
background(255);
fill(0);
for(int i = 0; i < barriers.length; i++) {
// Draw barriers
ellipse(barriers[i][0], barriers[i][1], 50, 50);
// Did we pass a barrier? (doesn't work!)
if(y >= barriers[i][0] - 1 && y <= barriers[i][1] + 1) {
counter++;
}
}
// Draw the square
rect(x, y, 25, 25);
// Draw counter alongside square
fill(255, 0, 0);
text(counter, x + 25, y - 5);
// Reset
if(y < height) {
y+=5;
} else {
y = -25;
counter = 0;
}
}
Apologies if the solution is blindingly obvious, but I'm just not seeing the problem here...
Looking forward to some assistance.
Look at this section of code:
if(y >= barriers[i][0] - 1 && y <= barriers[i][1] + 1) {
counter++;
}
The draw() function fires 60 times a second, so this code will be fired 60 times per second. That means that while you're passing a barrier, the counter variable will increment 60 times per second!
Presumably you only want the counter to increase once for each barrier. There are a number of ways to do this. You could have another data structure that keeps track of whether each barrier has already been passed, and then only check barriers that haven't been passed yet. Or you could keep track of the previous positions of the square, and then use that to determine when the square starts passing a barrier.
Think about how you would do this in your head, without a computer. How do you know when the square is passing a circle? How do you, in your head, only count one for each barrier?
Following Kevin's advice, I was able to get it working using an array of booleans which I used to ensure I wasn't incrementing counter more than once:
Full code:
float barriers[][] = new float[10][2];
float x = 400;
float y = -25;
int counter = 0;
boolean barriersChecked[] = {false, false, false, false, false, false, false, false, false, false};
void setup()
{
size(800, 600);
genBarriers();
}
void genBarriers()
{
for (int i = 0; i < barriers.length; i++) {
barriers[i][0] = random(width);
barriers[i][1] = random(height);
}
}
void draw()
{
background(255);
fill(0);
for (int i = 0; i < barriers.length; i++) {
// Draw barriers
ellipse(barriers[i][0], barriers[i][1], 50, 50);
// Did we pass a barrier?
if (barriers[i][1] < y && !barriersChecked[i]) {
counter++;
barriersChecked[i] = true;
}
}
// Draw the square
rect(x, y, 25, 25);
// Draw counter alongside square
fill(255, 0, 0);
text(counter, x + 25, y - 5);
// Reset
if (y < height) {
y+=2;
} else {
y = -25;
genBarriers();
// Reset barriersChecked
for(int i = 0; i < barriersChecked.length; i++) {
barriersChecked[i] = false;
}
}
}
Out of curiosity, is there a more elegant (loopless) way of resetting every element in barriersChecked back to false?
Suggestions of additional improvements would also be greatly appreciated.

Finding the furthest point in a grid when compared to other points

I have a rectangular grid of variable size but averaging 500x500 with a small number of x,y points in it (less than 5). I need to find an algorithm that returns an x,y pair that is the farthest away possible from any of the other points.
Context: App's screen (grid) and a set of x,y points (enemies). The player dies and I need an algorithm that respawns them as far away from the enemies so that they don't die immediately after respawning.
What I have so far: The algorithm I wrote works but doesn't perform that great in slower phones. I'm basically dividing up the grid into squares (much like a tic tac toe) and I assign each square a number. I then check every single square against all enemies and store what the closest enemy was at each square. The square with the highest number is the square that has the closest enemy furthest away. I also tried averaging the existing points and doing something similar to this and while the performance was acceptable, the reliability of the method was not.
This is the simplest algorithm I could think of that still gives good results. It only checks 9 possible positions: the corners, the middle of the sides, and the center point. Most of the time the player ends up in a corner, but you obviously need more positions than enemies.
The algorithm runs in 0.013ms on my i5 desktop. If you replace the Math.pow() by Math.abs(), that comes down to 0.0088ms, though obviously with less reliable results. (Oddly enough, that's slower than my other answer which uses trigonometry functions.)
Running the code snippet (repeatedly) will show the result with randomly positioned enemies in a canvas element.
function furthestFrom(enemy) {
var point = [{x:0,y:0},{x:250,y:0},{x:500,y:0},{x:0,y:250},{x:250,y:250},{x:500,y:250},{x:0,y:500},{x:250,y:500},{x:500,y:500}];
var dist2 = [500000,500000,500000,500000,500000,500000,500000,500000,500000];
var max = 0, furthest;
for (var i in point) {
for (var j in enemy) {
var d = Math.pow(point[i].x - enemy[j].x, 2) + Math.pow(point[i].y - enemy[j].y, 2);
if (d < dist2[i]) dist2[i] = d;
}
if (dist2[i] > max) {
max = dist2[i];
furthest = i;
}
}
return(point[furthest]);
}
// CREATE TEST DATA
var enemy = [];
for (var i = 0; i < 5; i++) enemy[i] = {x: Math.round(Math.random() * 500), y: Math.round(Math.random() * 500)};
// RUN FUNCTION
var result = furthestFrom(enemy);
// SHOW RESULT ON CANVAS
var canvas = document.getElementById("canvas");
canvas.width = 500; canvas.height = 500;
canvas = canvas.getContext("2d");
for (var i = 0; i < 5; i++) {
paintDot(canvas, enemy[i].x, enemy[i].y, 10, "red");
}
paintDot(canvas, result.x, result.y, 20, "blue");
function paintDot(canvas, x, y, size, color) {
canvas.beginPath();
canvas.arc(x, y, size, 0, 6.2831853);
canvas.closePath();
canvas.fillStyle = color;
canvas.fill();
}
<BODY STYLE="margin: 0; border: 0; padding: 0;">
<CANVAS ID="canvas" STYLE="width: 200px; height: 200px; background-color: #EEE;"></CANVAS>
</BODY>
This is similar to what you are already doing, but with two passes where the first pass can be fairly crude. First decrease resolution. Divide the 500x500 grid into 10x10 grids each of which is 50x50. For each of the resulting 100 subgrids -- determine which have at least one enemy and locate the subgrid that is furthest away from a subgrid which contains an enemy. At this stage there is only 100 subgrids to worry about. Once you find the subgrid which is furthest away from an enemy -- increase resolution. That subgrid has 50x50 = 2500 squares. Do your original approach with those squares. The result is 50x50 + 100 = 2600 squares to process rather than 500x500 = 250,000. (Adjust the numbers as appropriate for the case in which there isn't 500x500 but with the same basic strategy).
Here is a Python3 implementation. It uses two functions:
1) fullResSearch(a,b,n,enemies) This function takes a set of enemies, a corner location (a,b) and an int, n, and finds the point in the nxn square of positions whose upper-left hand corner is (a,b) and finds the point in that square whose which has the maximum min-distance to an enemy. The enemies are not assumed to be in this nxn grid (although they certainly can be)
2) findSafePoint(n, enemies, mesh = 20) This function takes a set of enemies who are assumed to be in the nxn grid starting at (0,0). mesh determines the size of the subgrids, defaulting to 20. The overall grid is split into mesh x mesh subgrids (or slightly smaller along the boundaries if mesh doesn't divide n) which I think of as territories. I call a territory an enemy territory if it has an enemy in it. I create the set of enemy territories and pass it to fullResSearch with parameter n divided by mesh rather than n. The return value gives me the territory which is farthest from any enemy territory. Such a territory can be regarded as fairly safe. I feed that territory back into fullResSearch to find the safest point in that territory as the overall return function. The resulting point is either optimal or near-optimal and is computed very quickly. Here is the code (together with a test function):
import random
def fullResSearch(a,b,n,enemies):
minDists = [[0]*n for i in range(n)]
for i in range(n):
for j in range(n):
minDists[i][j] = min((a+i - x)**2 + (b+j - y)**2 for (x,y) in enemies)
maximin = 0
for i in range(n):
for j in range(n):
if minDists[i][j] > maximin:
maximin = minDists[i][j]
farthest = (a+i,b+j)
return farthest
def findSafePoint(n, enemies, mesh = 20):
m = n // mesh
territories = set() #enemy territories
for (x,y) in enemies:
i = x//mesh
j = y//mesh
territories.add((i,j))
(i,j) = fullResSearch(0,0,m,territories)
a = i*mesh
b = j*mesh
k = min(mesh,n - a,n - b) #in case mesh doesn't divide n
return fullResSearch(a,b,k,enemies)
def test(n, numEnemies, mesh = 20):
enemies = set()
count = 0
while count < numEnemies:
i = random.randint(0,n-1)
j = random.randint(0,n-1)
if not (i,j) in enemies:
enemies.add ((i,j))
count += 1
for e in enemies: print("Enemy at", e)
print("Safe point at", findSafePoint(n,enemies, mesh))
A typical run:
>>> test(500,5)
Enemy at (216, 67)
Enemy at (145, 251)
Enemy at (407, 256)
Enemy at (111, 258)
Enemy at (26, 298)
Safe point at (271, 499)
(I verified by using fullResSearch on the overall grid that (271,499) is in fact optimal for these enemies)
This method looks at all the enemies from the center point, checks the direction they're in, finds the emptiest sector, and then returns a point on a line through the middle of that sector, 250 away from the center.
The result isn't always perfect, and the safe spot is never in the center (though that could be added), but maybe it's good enough.
The algorithm runs more than a million times per second on my i5 desktop, but a phone may not be that good with trigonometry. The algorithm uses 3 trigonometry functions per enemy: atan2(), cos() and sin(). Those will probably have the most impact on the speed of execution. Maybe you could replace the cos() and sin() with a lookup table.
Run the code snippet to see an example with randomly positioned enemies.
function furthestFrom(e) {
var dir = [], widest = 0, bisect;
for (var i = 0; i < 5; i++) {
dir[i] = Math.atan2(e[i].y - 250, e[i].x - 250);
}
dir.sort(function(a, b){return a - b});
dir.push(dir[0] + 6.2831853);
for (var i = 0; i < 5; i++) {
var angle = dir[i + 1] - dir[i];
if (angle > widest) {
widest = angle;
bisect = dir[i] + angle / 2;
}
}
return({x: 250 * (1 + Math.cos(bisect)), y: 250 * (1 + Math.sin(bisect))});
}
// CREATE TEST DATA
var enemy = [];
for (var i = 0; i < 5; i++) enemy[i] = {x: Math.round(Math.random() * 500), y: Math.round(Math.random() * 500)};
// RUN FUNCTION AND SHOW RESULT ON CANVAS
var result = furthestFrom(enemy);
var canvas = document.getElementById("canvas");
canvas.width = 500; canvas.height = 500;
canvas = canvas.getContext("2d");
for (var i = 0; i < 5; i++) {
paintDot(canvas, enemy[i].x, enemy[i].y, "red");
}
paintDot(canvas, result.x, result.y, "blue");
// PAINT DOT ON CANVAS
function paintDot(canvas, x, y, color) {
canvas.beginPath();
canvas.arc(x, y, 10, 0, 6.2831853);
canvas.closePath();
canvas.fillStyle = color;
canvas.fill();
}
<BODY STYLE="margin: 0; border: 0; padding: 0">
<CANVAS ID="canvas" STYLE="width: 200px; height: 200px; background-color: #EEE;"CANVAS>
</BODY>
Here's an interesting solution, however I cannot test it's efficiency. For each enemy, make a line of numbers from each number, starting with one and increasing by one for each increase in distance. Four initial lines will come from the four edges and each time you go one further out, you create another line coming out at a 90 degree angle, also increasing the number each change in distance. If the number line encounters an already created number that is smaller than it, it will not overwrite it and will stop reaching further. Essentially, this makes it so that if the lines find a number smaller than it, it won't check any further grid marks, eliminating the need to check the entire grid for all of the enemies.
<<<<<<^^^^^^^
<<<<<<^^^^^^^
<<<<<<X>>>>>>
vvvvvvv>>>>>>
vvvvvvv>>>>>>
public void map(int posX, int posY)
{
//left up right down
makeLine(posX, posY, -1, 0, 0, -1);
makeLine(posX, posY, 0, 1, -1, 0);
makeLine(posX, posY, 1, 0, 0, 1);
makeLine(posX, posY, 0, -1, 1, 0);
grid[posX][posY] = 1000;
}
public void makeLine(int posX, int posY, int dirX, int dirY, int dir2X, int dir2Y)
{
int currentVal = 1;
posX += dirX;
posY += dirY;
while (0 <= posX && posX < maxX && posY < maxY && posY >= 0 && currentVal < grid[posX][posY])
{
int secondaryPosX = posX + dir2X;
int secondaryPosY = posY + dir2Y;
int secondaryVal = currentVal + 1;
makeSecondaryLine( secondaryPosX, secondaryPosY, dir2X, dir2Y, secondaryVal);
makeSecondaryLine( secondaryPosX, secondaryPosY, -dir2X, -dir2Y, secondaryVal);
grid[posX][posY] = currentVal;
posX += dirX;
posY += dirY;
currentVal++;
}
}
public void makeSecondaryLine(int secondaryPosX, int secondaryPosY, int dir2X, int dir2Y, int secondaryVal)
{
while (0 <= secondaryPosX && secondaryPosX < maxX && secondaryPosY < maxY &&
secondaryPosY >= 0 && secondaryVal < grid[secondaryPosX][secondaryPosY])
{
grid[secondaryPosX][secondaryPosY] = secondaryVal;
secondaryPosX += dir2X;
secondaryPosY += dir2Y;
secondaryVal++;
}
}
}
Here is the code I used to map out the entire grid. The nice thing about this, is that the number of times the number is checked/written is not that much dependent on the number of enemies on the screen. Using a counter and randomly generated enemies, I was able to get this: 124 enemies and 1528537 checks, 68 enemies and 1246769 checks, 15 enemies and 795695 500 enemies and 1747452 checks. This is a huge difference compared to your earlier code which would do number of enemies * number of spaces.
for 124 enemies you'd have done 31000000 checks, while instead this did 1528537, which is less than 5% of the number of checks normally done.
You can choose some random point at the grid and then move it iteratively from the enemies, here is my implementation in python:
from numpy import array
from numpy.linalg import norm
from random import random as rnd
def get_pos(enem):
# chose random start position
pos = array([rnd() * 500., rnd() * 500.])
# make several steps from enemies
for i in xrange(25): # 25 steps
s = array([0., 0.]) # step direction
for e in enem:
vec = pos - array(e) # direction from enemy
dist = norm(vec) # distance from enemy
vec /= dist # normalize vector
# calculate size of step
step = (1000. / dist) ** 2
vec *= step
s += vec
# update position
pos += s
# ensure that pos is in bounds
pos[0] = min(max(0, pos[0]), 500.)
pos[1] = min(max(0, pos[1]), 500.)
return pos
def get_dist(enem, pos):
dists = [norm(pos - array(e)) for e in enem]
print 'Min dist: %f' % min(dists)
print 'Avg dist: %f' % (sum(dists) / len(dists))
enem = [(0., 0.), (250., 250.), (500., 0.), (0., 500.), (500., 500.)]
pos = get_pos(enem)
print 'Position: %s' % pos
get_dist(enem, pos)
Output:
Position: [ 0. 250.35338215]
Min dist: 249.646618
Avg dist: 373.606883
Triangulate the enemies (there's less than 5?); and triangulate each corner of the grid with the closest pair of enemies to it. The circumcenter of one of these triangles should be a decent place to re-spawn.
Below is an example in JavaScript. I used the canvas method from m69's answer for demonstration. The green dots are the candidates tested to arrive at the blue-colored suggestion. Since we are triangulating the corners, they are not offered as solutions here (perhaps the randomly-closer solutions can be exciting for a player? Alternatively, just test for the corners as well..).
// http://stackoverflow.com/questions/4103405/what-is-the-algorithm-for-finding-the-center-of-a-circle-from-three-points
function circumcenter(x1,y1,x2,y2,x3,y3)
{
var offset = x2 * x2 + y2 * y2;
var bc = ( x1 * x1 + y1 * y1 - offset ) / 2;
var cd = (offset - x3 * x3 - y3 * y3) / 2;
var det = (x1 - x2) * (y2 - y3) - (x2 - x3)* (y1 - y2);
var idet = 1/det;
var centerx = (bc * (y2 - y3) - cd * (y1 - y2)) * idet;
var centery = (cd * (x1 - x2) - bc * (x2 - x3)) * idet;
return [centerx,centery];
}
var best = 0,
candidates = [];
function better(pt,pts){
var temp = Infinity;
for (var i=0; i<pts.length; i+=2){
var d = (pts[i] - pt[0])*(pts[i] - pt[0]) + (pts[i+1] - pt[1])*(pts[i+1] - pt[1]);
if (d <= best)
return false;
else if (d < temp)
temp = d;
}
best = temp;
return true;
}
function f(es){
if (es.length < 2)
return "farthest corner";
var corners = [0,0,500,0,500,500,0,500],
bestcandidate;
// test enemies only
if (es.length > 2){
for (var i=0; i<es.length-4; i+=2){
for (var j=i+2; j<es.length-2; j+=2){
for (var k=j+2; k<es.length; k+=2){
var candidate = circumcenter(es[i],es[i+1],es[j],es[j+1],es[k],es[k+1]);
if (candidate[0] < 0 || candidate[1] < 0 || candidate[0] > 500 || candidate[1] > 500)
continue;
candidates.push(candidate[0]);
candidates.push(candidate[1]);
if (better(candidate,es))
bestcandidate = candidate.slice();
}
}
}
}
//test corners
for (var i=0; i<8; i+=2){
for (var j=0; j<es.length-2; j+=2){
for (var k=j+2; k<es.length; k+=2){
var candidate = circumcenter(corners[i],corners[i+1],es[j],es[j+1],es[k],es[k+1]);
if (candidate[0] < 0 || candidate[1] < 0 || candidate[0] > 500 || candidate[1] > 500)
continue;
candidates.push(candidate[0]);
candidates.push(candidate[1]);
if (better(candidate,es))
bestcandidate = candidate.slice();
}
}
}
best = 0;
return bestcandidate;
}
// SHOW RESULT ON CANVAS
var canvas = document.getElementById("canvas");
canvas.width = 500; canvas.height = 500;
context = canvas.getContext("2d");
//setInterval(function() {
// CREATE TEST DATA
context.clearRect(0, 0, canvas.width, canvas.height);
candidates = [];
var enemy = [];
for (var i = 0; i < 8; i++) enemy.push(Math.round(Math.random() * 500));
// RUN FUNCTION
var result = f(enemy);
for (var i = 0; i < 8; i+=2) {
paintDot(context, enemy[i], enemy[i+1], 10, "red");
}
for (var i = 0; i < candidates.length; i+=2) {
paintDot(context, candidates[i], candidates[i+1], 7, "green");
}
paintDot(context, result[0], result[1], 18, "blue");
function paintDot(context, x, y, size, color) {
context.beginPath();
context.arc(x, y, size, 0, 6.2831853);
context.closePath();
context.fillStyle = color;
context.fill();
}
//},1500);
<BODY STYLE="margin: 0; border: 0; padding: 0;">
<CANVAS ID="canvas" STYLE="width: 200px; height: 200px; background:
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.15) 30%, rgba(255,255,255,.3) 32%, rgba(255,255,255,0) 33%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.3) 13%, rgba(255,255,255,0) 14%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 17%, rgba(255,255,255,.43) 19%, rgba(255,255,255,0) 20%) 0 110px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13%, rgba(255,255,255,0) 14%) -130px -170px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13%, rgba(255,255,255,0) 14%) 130px 370px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.2) 13%, rgba(255,255,255,0) 14%) 0 0,
linear-gradient(45deg, #343702 0%, #184500 20%, #187546 30%, #006782 40%, #0b1284 50%, #760ea1 60%, #83096e 70%, #840b2a 80%, #b13e12 90%, #e27412 100%);
background-size: 470px 470px, 970px 970px, 410px 410px, 610px 610px, 530px 530px, 730px 730px, 100% 100%;
background-color: #840b2a;"></CANVAS>
<!-- http://lea.verou.me/css3patterns/#rainbow-bokeh -->
</BODY>

Kinect Depth Histogram in Processing

I'm trying to create a histogram displaying the distances scanned by a Kinect vs. their occurrences. I've adapted the Histogram example code to create a depth histogram, but it's currently displaying the depth at each pixel (from left to right) multiple times across the depth image width.
What I'm looking to do is reorder the depth information so that it ranges from the lowest value (that isn't 0) to the highest on the x axis, and shows their occurrences on the y. I'm using Processing, so I'm unsure if this is the right site to be posting on, but I've tried on the posting forum and not gotten any help. If anyone can show me where I'm going wrong, that'd be awesome. My current code is below, and a screenshot of my current output can be found here
import SimpleOpenNI.*;
SimpleOpenNI kinect;
void setup() {
size(1200, 580);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
}
void draw () {
kinect.update();
PImage depthImage = kinect.depthImage();
image (depthImage, 11, 0);
int[] depthValues = kinect.depthMap();
int[] hist = new int[716800];
for (int x = 11; x < depthImage.width; x++) {
for (int y = 0; y < depthImage.height; y++) {
int i = x + y * 640;
hist[i] = depthValues[i];
}
}
int histMax = max(hist);
stroke(20);
for (int i = 0; i < depthImage.width; i += 2) {
int which = int(map(i, 0, depthImage.width, 0, histMax));
int y = int(map(hist[which], 0, histMax, depthImage.height, 0));
line(i, depthImage.height, i, y);
}
}
I think you're asking two questions here.
How to get the histogram to go from 0-N:
Use Processing's sort() function to sort the array.
hist = sort(hist); // sorts your array numerically
How to get the histogram to fill the screen:
I'm not entirely sure why it's drawing twice, but I think you can clean up your code quite a bit.
// how far apart are the bars - set based on screen dimensions
int barSpacing = width / hist.length;
for (int i=0; i<hist.length; i++) {
// get value and map into usable range (note 10 not 0 for min)
int h = int(map(hist[i], 0,histMax, 10,height));
// set x position onscreen
int x = i * barSpacing;
// draw the bar
line(x,height, x,height-h);
}

Resources