fullscreen
class BaseClass
{
PVector pos;
float radius;
float haitteru;
float edge;
BaseClass(float x,float y,float z,float r,float h,float e)
{
pos = new PVector(x,y,z);
radius = r;
haitteru = h;
edge = e;
}
}
import peasy.*;
PeasyCam cam;
GridClassController gcc;
TimerClass timer;
void setup()
{
size(600, 400, P3D);
colorMode(RGB, 256);
background(255);
frameRate(300);
//--------------------------------------------------------------
//create GridClassController
//--------------------------------------------------------------
gcc = new GridClassController();
gcc.init();
timer = new TimerClass();
//--------------------------------------------------------------
//init Camera
//--------------------------------------------------------------
cam = new PeasyCam(this, 200);
cam.setMinimumDistance(50);
cam.setMaximumDistance(50000000);
}
void update()
{
background(255);
lights();
directionalLight(80, 80, 80, 100, 500, 1000);
directionalLight(80, 80, 80, 500, 100, 1000);
gcc.update();
timer.update();
if (timer.time > 400)
{
if (timer.time %35 == 0)
{
gcc.addNew();
}
}
}
void draw()
{
update();
gcc.renderBox();
}
class GridClass
{
BaseClass[][] parameter;
int gridSize;
int numberOfPertions;
GridClass(int n, int g)
{
numberOfPertions = n;
gridSize = g;
}
void init(float z)
{
parameter = new BaseClass[numberOfPertions+ 2][numberOfPertions + 2];
for (int x=0; x<numberOfPertions; x++)
{
for (int y=0; y<numberOfPertions; y++)
{
parameter[x][y] = new BaseClass(x*gridSize, y*gridSize, z, .0, .0, .0);
}
}
}
void update()
{
}
PVector getPos(int x, int y)
{
return parameter[x][y].pos;
}
void setHaitteru(float n[][])
{
for (int x=0; x<numberOfPertions; x++)
{
for (int y=0; y<numberOfPertions; y++)
{
parameter[x][y].haitteru = n[x][y];
}
}
}
void drawBoxies()
{
pushMatrix();
translate(-width/2+80, -height/2-50);
for (int x=1; x<numberOfPertions; x++)
{
for (int y=1; y<numberOfPertions; y++)
{
if (parameter[x][y].haitteru == 1.0f)
{
fill(100);
noStroke();
float margin = 1.1;
pushMatrix();
translate(parameter[x][y].pos.x*margin, parameter[x][y].pos.y*margin, parameter[x][y].pos.z*margin);
box(gridSize);
popMatrix();
} //if
}
}
popMatrix();
}//drawBoxies
}
class GridClassController
{
GridClass[] gridClass;
ReactionDiffusion rd;
int total= 100000;
int gridSize = 5;
int numberOfPertions = 80;
int posZ = 0;
int num = 0;
boolean delayFlag = false;
GridClassController()
{
}
//---------------------------------------------
//public
//---------------------------------------------
void init()
{
rd = new ReactionDiffusion(numberOfPertions, gridSize);
rd.init();
gridClass = new GridClass[total];
}
void update()
{
rd.update(); //ReactionDiffusion計算を毎フレームアップデート
}
void renderBox()
{
for (int i=0; i<num; i++)
{
gridClass[i].drawBoxies();
}
}
void addNew()
{
//毎フレームグリッドクラスを生成
posZ = num*gridSize *-1;
gridClass[num] = new GridClass(numberOfPertions, gridSize);
gridClass[num].init(posZ);
gridClass[num].setHaitteru(rd.getNitikaNoudo()); //gridクラスにRDクラスで計算した濃度を渡してとこ
num++;
}
}
class ReactionDiffusion
{
int heightVertexNum, widthVertexNum;
int gridSize;
float[][] noudoArray;
float[][] u, v, u1, v1;
//syokiti
float dt = .5; //defolt = .5
float h = 0.1;
float h2 = h*h;
float a = 0.024, b = 0.078;
float cu = 0.002, cv = 0.001;
ReactionDiffusion(int n, int g)
{
heightVertexNum = n;
widthVertexNum = n;
gridSize = g;
}
//---------------------------------------------
//public
//---------------------------------------------
public void init()
{
noudoArray = new float[widthVertexNum+ 2][heightVertexNum + 2];
for (int x = 0; x <= widthVertexNum; x++)
{
for (int y = 0; y <= heightVertexNum; y++)
{
noudoArray[x][y] = .0;
}
}
u = new float[widthVertexNum+ 2][heightVertexNum + 2];
v = new float[widthVertexNum + 2][heightVertexNum + 2];
u1 = new float[widthVertexNum + 2][heightVertexNum + 2];
v1 = new float[widthVertexNum + 2][heightVertexNum + 2];
clear();
initNoudo();
}
public void update()
{
boundary();
for (int x = 1; x <= widthVertexNum; x++)
{
for (int y = 1; y <= heightVertexNum; y++)
{
float Du = (u[x+1][y] + u[x][y+1] + u[x-1][y] + u[x][y-1] - 4 * u[x][y]) / h2;
float Dv = (v[x+1][y] + v[x][y+1] + v[x-1][y] + v[x][y-1] - 4 * v[x][y]) / h2;
float f = - u[x][y] * sq(v[x][y]) + a * (1 - u[x][y]);
float g = u[x][y] * sq(v[x][y]) - b * v[x][y];
u1[x][y] = u[x][y] + (cu * Du + f) * dt;
v1[x][y] = v[x][y] + (cv * Dv + g) * dt;
}
}
for (int x = 1; x <= widthVertexNum; x++) {
for (int y = 1; y <= heightVertexNum; y++) {
u[x][y] = u1[x][y];
v[x][y] = v1[x][y];
}
}
} //update
//-------------------------------
//オリジナルの濃度(0から255)
//-------------------------------
public float[][] getNoudo()
{
for (int x = 1; x <= widthVertexNum; x++)
{
for (int y = 1; y <= heightVertexNum; y++)
{
noudoArray[x][y] = (u[x][y] * 255) + (v[x][y] * 255 *-1); //計算した濃度を入れ込んでるとこ(0〜255)
}
}
return noudoArray;
}
//-------------------------------
//濃度のグラデーションを2値化したものを返すとこ
//-------------------------------
public float[][] getNitikaNoudo()
{
for (int x = 1; x <= widthVertexNum; x++)
{
for (int y = 1; y <= heightVertexNum; y++)
{
noudoArray[x][y] = (u[x][y] * 255) + (v[x][y] * 255 *-1); //計算した濃度を入れ込んでるとこ(0〜255)
//if ( noudoArray[x][y]>110 && noudoArray[x][y] < 150) //2値化するスレッショルド
if ( noudoArray[x][y]>130 && noudoArray[x][y] < 181)
{
noudoArray[x][y] = 1.0f;
}
else {
noudoArray[x][y] = .0f;
}
}
}
//return nitikaNoudoArray;
return noudoArray;
}
//---------------------------------------------
//private
//---------------------------------------------
private void boundary()
{
for (int i = 1; i <= widthVertexNum; i++)
{
// u
u[i][0] = u[i][heightVertexNum];
u[i][heightVertexNum+1] = u[i][1];
u[0][i] = u[widthVertexNum][i];
u[widthVertexNum+1][i] = u[1][i];
// v
v[i][0] = v[i][heightVertexNum];
v[i][heightVertexNum+1] = v[i][1];
v[0][i] = v[widthVertexNum][i];
v[widthVertexNum+1][i] = v[1][i];
}
}
private void clear()
{
for (int x = 1; x <= widthVertexNum; x++) {
for (int y = 1; y <= heightVertexNum; y++) {
u[x][y] = 1.0;
v[x][y] = 0.0;
}
}
}
private void initNoudo()
{
for (int i = 0; i < 4; i++)
{
int clickX = int(random(5, widthVertexNum-5));
int clickY = int(random(5, heightVertexNum-5));
for (int x = 1; x <= widthVertexNum; x++) {
for (int y = 1; y <= heightVertexNum; y++) {
float r = sqrt((clickX - x) * (clickX - x) + (clickY - y) * (clickY - y));
if (r < 8)
{
u[x][y] = 0.6 + random(-0.06, 0.06);
v[x][y] = 0.2 + random(-0.02, 0.02);
}
}
}
}
} //initNoudo
/*
void clicked()
{
int xx, yy;
xx = mouseX / gridSize + 1;
yy = mouseY / gridSize + 1;
for (int x = 1; x <= widthVertexNum; x++){
for (int y = 1; y <= heightVertexNum; y++){
float r = sqrt((xx - x) * (xx - x) + (yy - y) * (yy - y));
if (r < 8){
u[x][y] = 0.6 + random(-0.06, 0.06);
v[x][y] = 0.2 + random(-0.02, 0.02);
}
}
}
} //clicked
*/
}
class TimerClass
{
int time;
TimerClass(){
time = 0;
}
void update()
{
time++;
}
}
This object is a casestudy of generative spase.
This generative algorism is a reaction diffusion system.
Please Check
C4D render version
http://creatorshigh.com/blog/?p=482
---controls--------------------
Peasycam use. (Drag & Scroll)