Processing - Initialize function with CP5 button - function

I have this code that draws hexagons randomly in a grid and coloring them randomly from an array.
What I want to do is press a CP5 button to initialize the drawing function. If I press this button again, it will fill all drawn hexagons with black and re-initialize the drawing function.
Currently this initialize the drawing:
void mousePressed() {
if (active_counter == 0) {
hexagons[int(wide/2)][int(tall/2)].active = true;
active_counter++;
}
}
So I tried this approach:
public void startDrawing(int theValue) {
println("a button event from startDrawing: "+theValue);
c1 = c2;
c2 = color(0,0,0);
if (active_counter == 40) {
fill(color(0));
}
}
This is not working, because “fill” is not connected to “hexagons”, but I have difficulty appending it the right way.
This is the full code:
import controlP5.*;
ControlP5 cp5;
int myColor = color(255);
int c1,c2;
float n,n1;
// ------------- Hexagon grid -------------
Hexagon[] [] hexagons;
float rx = 51;
float ry = 56;
int wide;
int tall;
int hexagon;
int active_counter = 0;
boolean active;
int max_hexagons;
float Xoffset, Yoffset;
int randX;
int randY;
int randD;
int x;
int y;
int[] stepX = { -1, -1, 1, 0, 1, 1 };
int[][] stepY = {{ 0, 1, -1, 1, 0, 1 }, { 0, -1, -1, 1, 0, -1 } };
class Hexagon {
float x;
float y;
int rand;
color[] colors;
boolean active;
Hexagon (float ix, float iy) {
x = ix;
y = iy;
active = false;
// Array of colors
colors = new color[10];
colors[0] = color(#62563D); // Infantry green
colors[1] = color(#2C2B2D); // Parisian night blue
colors[2] = color(#3E2224); // Purple heart
colors[3] = color(#A49F9B); // Wild dove grey
colors[4] = color(#684F40); // Brown
colors[5] = color(#5C573D); // Moss green
colors[6] = color(#B9897F); // Pink
colors[7] = color(#24283B); // Dark blue
colors[8] = color(#1F1D20); // Black
colors[9] = color(#C5A9A2); // Brazilian clay
// Takes the colors array and output random colors
rand = (int)random(colors.length);
}
// ------------- Nested draw -------------
void draw() {
if (active) {
// Call the colors array in random order
fill(colors[rand]);
} else {
noFill();
}
stroke(80);
pushMatrix();
translate(x, y);
beginShape();
vertex(-17, -28);
vertex(17, -28);
vertex(34, 0);
vertex(17, 28);
vertex(-17, 28);
vertex(-34, 0);
endShape(CLOSE);
popMatrix();
}
}
// ------------- setup -------------
void setup() {
size(1000, 700);
// ------------- CP5 control buttons -------------
cp5 = new ControlP5(this);
cp5.addButton("start drawing")
.setValue(0)
.setPosition(20,80)
.setSize(200, 19)
;
// ------------- Create hexagon grid -------------
wide = int(width/rx) + 2;
tall = int (height/ry) + 2;
max_hexagons = 40;
hexagons = new Hexagon [wide] [tall];
for (int y = 0; y < tall; y++) {
for (int x = 0; x < wide; x++) {
if ( x % 2 == 0) {
hexagons[x] [y] = new Hexagon(x*rx, y*ry);
} else {
hexagons[x] [y] = new Hexagon(x*rx, (y-.5)*ry);
}
}
}
float targetX = width/2;
float targetY = height/2;
Xoffset = hexagons [int(wide/2)] [int(tall/2)] .x - targetX;
Yoffset = hexagons [int(wide/2)] [int(tall/2)] .y - targetY;
}
// ------------- draw -------------
void draw () {
background(0);
pushMatrix();
translate(-Xoffset, -Yoffset);
for (int y = 0; y < tall; y++) {
for (int x = 0; x < wide; x++) {
hexagons[x] [y] .draw();
}
}
if (active_counter > 0 && active_counter < max_hexagons) {
nextHex();
}
popMatrix();
myColor = lerpColor(c1,c2,n);
n += (1-n)* 0.1;
}
public void controlEvent(ControlEvent theEvent) {
println(theEvent.getController().getName());
n = 0;
}
public void startDrawing(int theValue) {
println("a button event from startDrawing: "+theValue);
c1 = c2;
c2 = color(0,0,0);
if (active_counter == 40) {
fill(color(0));
}
}
// ------------- Mouse interaction -------------
void mousePressed() {
if (active_counter == 0) {
hexagons[int(wide/2)][int(tall/2)].active = true;
active_counter++;
}
}
// ------------- Drawing next hexagon -------------
void nextHex() {
int randX = int(random(wide));
int randY = int(random(tall));
while (!hexagons[randX][randY] .active) {
randX = int(random(wide));
randY = int(random(tall));
}
int randD = int(random(6));
if (
randX + stepX[randD] >= 0 &&
randX + stepX[randD] < wide &&
randY + stepY[randX % 2][randD] >= 0 &&
randY + stepY[randX % 2][randD] < tall
) {
if (!hexagons[randX + stepX[randD]][randY + stepY[randX % 2][randD]] .active) {
active_counter++;
}
hexagons[randX + stepX[randD]][randY + stepY[randX % 2][randD]] .active = true;
}
}

Related

Cuda Implementation of Partitioned Subgroup

is there a more efficient way to implement the "Partitioned Subgroup" functions of Vulkan/OpenGL, which do not have to loop over all elements in the subgroup? My current implementation just uses a loop from 0 to WARP_SIZE.
References:
(slide 37+38) https://developer.download.nvidia.com/video/gputechconf/gtc/2019/presentation/s9909-nvidia-vulkan-features-update.pdf
https://github.com/KhronosGroup/GLSL/blob/master/extensions/nv/GL_NV_shader_subgroup_partitioned.txt
Simple Implementation:
__device__ uint32_t subgroupPartitionNV(ivec2 p)
{
uint32_t result = 0;
for (int i = 0; i < 32; ++i)
{
int x = __shfl_sync(0xFFFFFFFF, p(0), i);
int y = __shfl_sync(0xFFFFFFFF, p(1), i);
uint32_t b = __ballot_sync(0xFFFFFFFF, p(0) == x && p(1) == y);
if (i == threadIdx.x & 31) result = b;
}
return result;
}
__device__ uint32_t subgroupPartitionedAddNV(float value, uint32_t ballot)
{
float result = 0;
for ( unsigned int i = 0; i < 32; ++i)
{
float other_value = __shfl_sync(0xFFFFFFFF, value, i);
if ((1U << i) & ballot) result += other_value;
}
return result;
}
Thanks to the hint of Abator I came up with a more efficient solution. It's a little ugly because labeled_partition is only implemented for int but works quite well.
template <int GROUP_SIZE = 32>
__device__ cooperative_groups::coalesced_group subgroupPartitionNV(ivec2 p)
{
using namespace cooperative_groups;
thread_block block = this_thread_block();
thread_block_tile<GROUP_SIZE> tile32 = tiled_partition<GROUP_SIZE>(block);
coalesced_group g1 = labeled_partition(tile32, p(0));
coalesced_group g2 = labeled_partition(tile32, p(1));
details::_coalesced_group_data_access acc;
return acc.construct_from_mask<coalesced_group>(acc.get_mask(g1) & acc.get_mask(g2));
}
template <typename T, int GROUP_SIZE = 32>
__device__ T subgroupPartitionedAddNV(T value, cooperative_groups::coalesced_group group)
{
int s = group.size();
int r = group.thread_rank();
for (int offset = GROUP_SIZE / 2; offset > 0; offset /= 2)
{
auto v = group.template shfl_down(value, offset);
if (r + offset < s) value += v;
}
return value;
}

Blank Maze Generation

Maze is generating in a weird fashion. I do not know why, but it generates and breaks down every wall.
here is the code:
public class Main extends Sprite
{
//ARRAYS
private var maze:Array = new Array();
private var pos:Array = new Array();
//INTEGERS
private var num:int = 50;
private var cellX:int = 0;
private var cellY:int = 0;
private var mazeX:int = num;
private var mazeY:int = num;
//POINTS
private var startCell:Point = new Point();
//SPRITES
private var mazeSpriteT:Sprite = new Sprite();
private var mazeSpriteB:Sprite = new Sprite();
private var mazeSpriteL:Sprite = new Sprite();
private var mazeSpriteR:Sprite = new Sprite();
//broken wall
private var brWall:Sprite = new Sprite();
public function Main():void
{
//creating the initial grid, cells and points
setMaze();
//calling function to generate maze
generate(startCell);
}
public function setMaze():void
{
//clearing the screen from all graphical images
mazeSpriteT.graphics.clear();
mazeSpriteB.graphics.clear();
mazeSpriteR.graphics.clear();
mazeSpriteL.graphics.clear();
brWall.graphics.clear();
maze = new Array();
pos = new Array();
for (var i:int = 0; i < 10; i++) {
maze[i] = new Array();
pos[i] = new Array();
for (var j:int = 0; j < 10; j++) {
//maze
maze[i][j] = new Cell;
maze[i][j].visited = false;
//pos
pos[i][j] = new Point(cellX, cellY);
//graphics
mazeSpriteT.graphics.lineStyle(5, 0x000000, 1);
mazeSpriteB.graphics.lineStyle(5, 0x000000, 1);
mazeSpriteR.graphics.lineStyle(5, 0x000000, 1);
mazeSpriteL.graphics.lineStyle(5, 0x000000, 1);
//toplines
addChild(mazeSpriteT);
mazeSpriteT.graphics.moveTo(mazeX, mazeY);
mazeSpriteT.graphics.lineTo(mazeX + num, mazeY);
mazeSpriteT = new Sprite();
//bottomlines
addChild(mazeSpriteB);
mazeSpriteB.graphics.moveTo(mazeX, mazeY + num);
mazeSpriteB.graphics.lineTo(mazeX + num, mazeY + num);
mazeSpriteB = new Sprite();
//rightlines
addChild(mazeSpriteR);
mazeSpriteR.graphics.moveTo(mazeX + num, mazeY);
mazeSpriteR.graphics.lineTo(mazeX + num, mazeY + num);
mazeSpriteR = new Sprite();
//leftlines
addChild(mazeSpriteL);
mazeSpriteL.graphics.moveTo(mazeX, mazeY);
mazeSpriteL.graphics.lineTo(mazeX, mazeY + num);
mazeSpriteB = new Sprite();
cellX += 10;
mazeX += num;
}
cellX = 0;
cellY += 10;
mazeX = num;
mazeY += num;
}
//maze entrance
startCell = pos[0][0];
}
public function generate(cell:Point):void
{
var cx:int = cell.x / 10;
var cy:int = cell.y / 10;
maze[cy][cx].visited = true;
var neighbours:Array = new Array();
fillNeighbours(neighbours, cell);
trace(neighbours.length);
while (neighbours.length > 0) {
var index:int = (Math.random() * neighbours.length);
Math.floor(index);
var arr:Array = neighbours.splice(index, 1);
var pnt:Point = new Point(arr[0].x, arr[0].y);
breakWall(cell, pnt);
generate(pnt);
//trace("index: " + index);
//trace("obx: " + arr[0].x + " oby: " + arr[0].y);
//trace("pnt: " + pnt);
}
}
public function fillNeighbours(neighbours:Array, cell:Point):Array
{
var cx:int = cell.x / 10;
var cy:int = cell.y / 10;
/*for (var i:int = 0; i < maze.length; i++) {
for (var j:int = 0; j < maze[i].length; j++) {
//outerwall parameters
maze[0][j].north = false;
maze[maze.length - 1][j].south = false;
maze[i][maze[i].length-1].east = false;
maze[i][0].west = false;
}
} */
//south neigbours
if (cy < maze.length - 1) {
if (maze[cy + 1][cx].visited == true) {
maze[cy][cx].south = false;
} else {
neighbours.push(pos[cy + 1][cx]);
}
}
if (cy > 0) {
//north neighbours
if (maze[cy - 1][cx].visited == true) {
maze[cy][cx].north = false;
} else {
neighbours.push(pos[cy - 1][cx]);
}
}
if (cx < maze.length - 1) {
//east neighbours
if (maze[cy][cx + 1].visited == true) {
maze[cy][cx].east = false;
} else {
neighbours.push(pos[cy][cx + 1]);
}
}
if (cx > 0) {
//west neighbours
if (maze[cy][cx - 1].visited == true) {
maze[cy][cx].west = false;
} else {
neighbours.push(pos[cy][cx - 1]);
}
}
trace("--");
return(neighbours);
}
public function breakWall(cell:Point, pnt:Point):void
{
var cx:int = cell.x / 10;
var cy:int = cell.y / 10;
var px:int = pnt.x / 10;
var py:int = pnt.y / 10;
brWall.graphics.lineStyle(5, 0xFFFFFF, 1); //white walls
addChild(brWall);
trace(cx, px);
if (cy == py) { //horizontal transition
if (cx > px) { //right to left
brWall.graphics.moveTo((cx * num) + num, (cy * num) + num);
brWall.graphics.lineTo((cx * num) + num, (cy * num) + (num * 2));
} else if (cx < px) { //left to right
brWall.graphics.moveTo((cx * num) + (num * 2), (cy * num) + (num * 2));
brWall.graphics.lineTo((cx * num) + (num * 2), (cy * num) + num);
}
}
if (cx == px) { //vertical transition
if (cy > py) { //down to up
brWall.graphics.moveTo((cx * num) + (num * 2), (cy * num) + num);
brWall.graphics.lineTo((cx * num) + num, (cy * num) + num);
} else if (cy < py){ //up to down
brWall.graphics.moveTo((cx * num) + num, (cy * num) + (num * 2));
brWall.graphics.lineTo((cx * num) + (num * 2), (cy * num) + (num * 2));
}
}
brWall = new Sprite();
}
}
}
I have been praying for help. Be the one to answer my prayers (I will give you five internet dollars).
I'm not too sure I understand completely. You're running a loop that breaks down each wall
while (neighbours.length > 0) {
var index:int = (Math.random() * neighbours.length);
Math.floor(index);
var arr:Array = neighbours.splice(index, 1);
var pnt:Point = new Point(arr[0].x, arr[0].y);
breakWall(cell, pnt);
generate(pnt);
//trace("index: " + index);
//trace("obx: " + arr[0].x + " oby: " + arr[0].y);
//trace("pnt: " + pnt);
}
Just remove breakWall(cell,pnt)?

Divide function

I need to write the divide function in the Jack language.
my code is:
function int divide(int x, int y) {
var int result;
var boolean neg;
let neg = false;
if(((x>0) & (y<0)) | ((x<0) & (y>0))){
let neg = true;
let x = Math.abs(x);
let y = Math.abs(y);
}
if (y>x){
return 0;
}
let result = Math.divide(x, y+y);
if ((x-(2*result*y)) < y) {
if (neg){
return -(result + result);
} else {
return (result + result);
}
} else {
if (neg){
return -(result + result + 1);
} else {
return (result + result + 1);
}
}
}
this algorithm is sub-optimal since each multiplication operation also requires O(n) addition and subtraction operations.
Can I compute the product 2*result*y without any multiplication?
Thanks
Here's an implementation of (unsigned) restoring division (x/y), I don't actually know Jack though so I'm not 100% sure about this
var int r;
let r = 0;
var int i;
let i = 0;
while (i < 16)
{
let r = r + r;
if ((x & 0x8000) = 0x8000) {
let r = r + 1;
}
if ((y ^ 0x8000) > (r ^ 0x8000)) { // this is an unsigned comparison
let x = x + x;
}
else {
let r = r - y;
let x = x + x + 1;
}
let i = i + 1;
}
return x;
You should be able to turn that into signed division.

Function to equation

Given a function fun, what is the mathematical equation for Rec?
public class Fun {
public static int Rec(int n) {
if ((n==1) || (n==2))
return 1;
else {
int result = 0;
for(int i=2; i<=(n-1); i++)
result = result+Rec(n-1)+ Rec(n-2);
return result;
}
}
}
f(0) = 0
f(1) = 1
f(2) = 1
f(3) = 2
f(4) = 6
f(5) = 24
f(6) = 120
f(7) = 720
f(8) = 5040
f(9) = 40320
f(10) = 362880
f(11) = 3628800
looks like (n-1)!

I am having problems with my FFT in c#

Does Microsoft have a good FFT that I can use ?
so I made my owe FFT and it work from some case but now all...
like if I get it
f(t) =10*sin(2*pi *3000*t) + 20*sin(1000* 2* PI* t)
it will work but if I add
+ 5*sin(2*pi*100*T) is start acting fun?
now in Matlab it works good but not in my close, also my fft only seem to return the right numbers in the Image not so much in the real...
here is my code:
enter code here
public struct polar1
{
public double real;
public double img;
};
private float Fs;
private int N;
private polar1 [] F;
private int R;
public DSPclass(float[] DSP1,int f1)
{
N = DSP1.Length;
R = DSP1.Length;
F = new polar1[N];
Fs = (float)f1;
}
public void FFT1(float[] DSP1)
{
polar1[] x = new polar1[DSP1.Length];
for (int v = 0; v < N; v++)
{
x[v].real = DSP1[v];
x[v].img = 0;
}
F = FFT(x);
int temp;
}
public polar1[] FFT(polar1[] x)
{
int N2 = x.Length;
polar1[] X = new polar1[N2];
if (N2 == 1)
{
return x;
}
polar1[] odd = new polar1[N2 / 2];
polar1[] even = new polar1[N2 / 2];
polar1[] Y_Odd = new polar1[N2 / 2];
polar1[] Y_Even = new polar1[N2 / 2];
for (int t = 0; t < N2 / 2; t++)
{
even[t].img = x[t * 2].img;
even[t].real = x[t * 2].real;
odd[t].img = x[(t * 2) + 1].img;
odd[t].real = x[(t * 2) + 1].real;
}
Y_Even = FFT(even);
Y_Odd = FFT(odd);
polar1 temp4;
for (int k = 0; k < (N2 / 2); k++)
{
temp4 = Complex1(k, N2);
X[k].real = Y_Even[k].real + (Y_Odd[k].real * temp4.real);
X[k + (N2 / 2)].real = Y_Even[k].real - (Y_Odd[k].real * temp4.real);
X[k].img = Y_Even[k].img + (Y_Odd[k].real * temp4.img);
X[k + (N2 / 2)].img = Y_Even[k].img - (Y_Odd[k].real * temp4.img);
}
return X;
}
public double magnitude( polar1 temp)
{
double tempD;
tempD = Math.Sqrt ( (temp.img * temp.img) + (temp.real * temp.real));
return tempD;
}
public polar1 Complex2(int K, int N, int F3)
{
polar1 temp;
double temp1;
temp1 = (2D * K *F3) / N;
if (temp1 % 2 == 0 || temp1 == 0)
{
temp.real = 1D;
temp.img = 0D;
}
else if ((temp1 - 1) % 2 == 0)
{
temp.real = -1D;
temp.img = 0D;
}
else if ((temp1 / .5D) - 1 % 2 == 0)
{
if ((temp1 - .5D) % 2 == 0)
{
temp.real = 0D;
temp.img = -1D;
}
else
{
temp.real = 0D;
temp.img = 1D;
}
}
else
{
temp.real = Math.Cos(temp1 * Math.PI);
temp.img = -1D * Math.Sin(temp1 * Math.PI);
}
return temp;
}
public polar1 Complex1(int K, int N3)
{
polar1 temp;
double temp1;
temp1 = (2D * Math.PI *K) / N3;
temp.real = Math.Cos(temp1);
temp.img = Math.Sin(temp1);
return temp;
}
public int Apm(double[] img, double[] real)
{
for (int i = 0; i < R; i++)
{
img[i] = F[i].img;
real[i] = F[i].real;
}
return R;
}
public int frequencies(float [] freq, float [] Ctemp)
{
bool flag = false;
bool flagD = false;
float tempOld = 0;
float tempNew =0;
int tempc = 0;
int counter = 0;
for (int i = 0; i < R; i++)
{
if (((i / N) * Fs) >= (Fs / 2))
{
return counter;
}
if ((int)F[i].img != 0 )
{
flag = true;
tempOld = (float)(Math.Abs(F[i].img));
}
else
{
if (flagD == true)
{
freq[counter] = ((float)tempc / (float)N) * Fs;
Ctemp[counter] = tempNew; //magnitude(F[tempc]);
counter++;
flagD = false;
}
flag = false;
tempOld = 0;
tempNew = 0;
}
if(flag == true)
{
if (tempOld > tempNew)
{
tempNew = tempOld;
tempc = i;
flagD = true;
}
}
}
return counter;
}
}