random number of subparts in a rectangle - p5.js

I have found this extremely nice example of rectangles being divided in to smaller rectangles from
the very great resource Generative Design book. The book itself does not go into details on the division of the rectangles.
the code is online here on the p5.js web editor: online code here
all code examples from the book can be found here: insanely great resource
Could someone try to explain how to make a simpler version of this code so i can understand the logic behind it? Or explain what is going on while the rectangles are getting drawn?
// add all subparts
var sumPartsTotal = 0;
for (var ii = 0; ii < partCount; ii++) {
sumPartsTotal += parts[ii];
}
// draw rects
var sumPartsNow = 0;
for (var ii = 0; ii < parts.length; ii++) {
sumPartsNow += parts[ii];
var x = map(sumPartsNow, 0, sumPartsTotal, 0, width);
var y = rowHeight * i;
var w = -map(parts[ii], 0, sumPartsTotal, 0, width);
var h = rowHeight;
var index = counter % colorCount;
var col = color(hueValues[index], saturationValues[index], brightnessValues[index]);
fill(col);
rect(x, y, w, h);
counter++;
}

Related

Creating random pixeled lines in Proccesing

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.

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>

Creating Grid in as3

I am trying to make to grid to squares using as3.
I am using nested for loops to create the grid.
import flash.display.Shape;
import flash.display.MovieClip;
var n=10;
var myClip = new MovieClip;
stage.addChild(myClip);
for (var i = 0; i < n * 10; i += 10) {
for (var j = 0; j < n * 10; j += 10) {
var _shape = new Shape;
myClip.addChild(_shape);
_shape.graphics.lineStyle(1);
_shape.graphics.beginFill(0xcccccc);
_shape.graphics.drawRect(i, j, 10, 10);
_shape.graphics.endFill();
}
}
I am applying Zooming and Panning Gestures on myClip. For this Grid size everything works fine. As soon as I increase the value of n, it starts lagging
My game requires a bigger grid. Please help
I'll show some ideas as code, my AS3 is a bit rusty but perhaps it helps.
You can reduce the number of Shape instances or draw the vector based grid graphic to a Bitmap. Since you are zooming and panning it you'll want to smooth it. Depending on performance and how much you zoom you also may want to draw the bitmap at a higher resolution than initially used. See comments in the below.
import flash.display.Shape;
import flash.display.MovieClip;
var n=10;
// do you actually need dynamic binding or a timeline in this?
// if not (also if you don't know what it means) do use the Sprite class instead
var myClip = new MovieClip;
stage.addChild(myClip);
// if you don't need individual shapes move this out of the for loop
// your logic with all of the shapes having the same origin suggests this might be so
var _shape = new Shape;
myClip.addChild(_shape);
for (var i = 0; i < n * 10; i += 10) {
for (var j = 0; j < n * 10; j += 10) {
_shape.graphics.lineStyle(1);
_shape.graphics.beginFill(0xcccccc);
_shape.graphics.drawRect(i, j, 10, 10);
_shape.graphics.endFill();
}
}
// then we can draw the grid to a bitmap
// since you are scaling it I'm drawing it a 300% resolution
var _bmd:BitmapData = new BitmapData(_shape.width*3, _shape.height*3, true, 0);
var _bit:Bitmap = new Bitmap(_bmd);
myClip.addChild(_bit);
_shape.width*=3;
_shape.height*=3;
_bmd.draw(stage);
_bit.smoothing = true;
_bit.width/=3;
_bit.height/=3;
// and remove the vector shape so it won't be rendered
myClip.removeChild(_shape);
// if need be it can be redrawn later

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