Skip to content

Instantly share code, notes, and snippets.

@p5info
Created April 9, 2013 06:06
Show Gist options
  • Save p5info/5343320 to your computer and use it in GitHub Desktop.
Save p5info/5343320 to your computer and use it in GitHub Desktop.
@fladdict さんの 「JSでアメーバのシミュレーション作ってみた」 http://fladdict.net/blog/2013/04/js-ameba.html のjavascriptソースコードをProcessing及びProcessing.jsで動くように修正してみた。動くように修正しただけなので、リファクタリングもかけてないですし、中のコメントも残したまんまです。
int numberOfNodes = 200;
Node[] nodes = new Node[numberOfNodes];
int pressedCount = 0;
float pressedX;
float pressedY;
//var calcTable;
float lineAlpha = 0;
void setup() {
size(displayWidth, displayHeight); //Processing 2.x以降はdisplayWidth
//size(screenWidth, screenHeight); //if Processing 1.5.1まではscreenWidth
background(0, 0, 0);
//For FullScreen
//@//HTMLのためのコードなので無視
//@ window.onresize = function()
//@ {
//@ size(window.innerWidth,window.innerHeight);
//@ };
setup2();
}
void setup2() {
for (int i=0; i<numberOfNodes; i++) {
Node nd = new Node();
nd.x = random(1f) * width;
nd.y = random(1f) * height;
nd.nodes = nodes;
nd.nodeType = int(random(1f)*2);
nodes[i]= nd;
};
//@高速化テーブル [NodeXId][NodeYId][dx,dy,dist];
//@あとで採用して最適化すること
//@ calcTable = [];
//@ for(var yy=0; i<numberOfNodes; yy++){
//@ var ar = [];
//@ for(var xx=0; j<numberOfNodes; xx++){
//@ ar.push([0,0,0]);
//@ }
//@ calcTable.push(ar);
//@ }
}
void draw() {
colorMode(RGB, 255);
fill(0);
noStroke();
rect(0, 0, width, height);
int n = nodes.length;
if (pressedCount>0) {
pressedCount--;
for (int i=0; i<n; i++) {
Node nd = nodes[i];
nd.maxVelocity=3;
nd.friction = 0.99;
nd.updateVelocity();
nd.updatePosition();
}
}else {
lineAlpha = lineAlpha + (1-lineAlpha)*0.01;
for (int i=0; i<n; i++) {
Node nd = nodes[i];
nd.maxVelocity=1;
nd.friction = 0.9;
nd.resetForce();
nd.update();
}
}
for (int i=0; i<n; i++)
{
for (int j=i; j<n; j++)
{
Node nd0 = nodes[i];
Node nd1 = nodes[j];
if (nd0!=nd1) {
float dx = nd1.x - nd0.x;
float dy = nd1.y - nd0.y;
float dist = sqrt(dx*dx+dy*dy);
if (dist<150 && dist!=0 && nd0.nodeType==nd1.nodeType) {
//255で0、 100で1
// (255-dist);
float strokeCol = (150-dist)*1.5;
stroke(strokeCol * lineAlpha);
line(nd0.x, nd0.y, nd1.x, nd1.y);
}
}
}
}
for (int i=0; i<n; i++) {
Node nd = nodes[i];
nd.draw();
};
}
void mousePressed()
{
pressedCount = 120;
pressedX = mouseX;
pressedY = mouseY;
lineAlpha = 0;
int n = nodes.length;
for (int i=0; i<n; i++) {
Node nd = nodes[i];
float fx = nd.x - mouseX;
float fy = nd.y - mouseY;
float dist = sqrt(fy*fy+fx*fx);
float rad = atan2(fy, fx);
if (dist>1) {
nd.fx += cos(rad)/dist*800;
nd.fy += sin(rad)/dist*800;
nd.updateVelocity();
nd.updatePosition();
}
};
}
class Node {
float x =0;
float y = 0;
float vx = 0;
float vy = 0;
int maxVelocity = 2;
float fx = 0;
float fy = 0;
int nodeType;
float rotation = 0;
Node[] nodes;
float friction = 0.9;
void init() {
}
void update() {
this.updateBoid();
this.updateVelocity();
this.updatePosition();
}
void resetForce()
{
this.fx = 0;
this.fy = 0;
}
void updateBoid()
{
//ここでBoid計算
int n = this.nodes.length;
//Calc Position
int deathCount = 0;
float fx = 0;
float fy = 0;
//仲間に近づく / 離れる
for (int i=0; i<n; i++) {
Node nd = this.nodes[i];
if (nd==this)
continue;
float dx = nd.x - this.x;
float dy = nd.y - this.y;
float dist = sqrt(dx*dx+dy*dy);
if (dist<50 && dist>1) {
deathCount++;
fx -= dx / dist / dist / dist * 40;
fy -= dy / dist / dist / dist * 40;
}
else if (dist<200 && this.nodeType==nd.nodeType) {
fx += dx / dist / dist / dist * 30;
fy += dy / dist / dist / dist * 30;
}
}
//仲間と同じ方向に移動する
for (int i=0; i<n; i++) {
Node nd = this.nodes[i];
if (nd==this)
continue;
float dx = nd.x - this.x;
float dy = nd.y - this.y;
float dist = sqrt(dx*dx+dy*dy);
if (dist>1) {
float vx = nd.vx;
float vy = nd.vy;
float rad = atan2(vy, vx);
fx += cos(rad) /dist/dist;
fy += sin(rad) /dist/dist;
}
}
//マウスから逃げる
float mfx = mouseX - this.x;
float mfy = mouseY - this.y;
float mdist = sqrt(mfx*mfx+mfy*mfy);
float mrad = atan2(mfy, mfx);
//console.log(mdist);
if (mdist>0) {
fx -= cos(mrad)/mdist/mdist*300;
fy -= sin(mrad)/mdist/mdist*300;
}
/*
if(deathCount>20){
this.x = random()*width;
this.y = random()*height;
}*/
//Normalize Speed
//@//変数distが参照可能なスコープから見当たらない。
//@ float d = dist(fx, fy);
//@ if (d>1) {
//@ fx = fx / dist;
//@ fy = fy / dist;
//@ }
this.fx += (random(1f)-0.5)*0.2;
this.fy += (random(1f)-0.5)*0.2;
this.fx += fx * 3;
this.fy += fy * 3;
}
void updateVelocity()
{
this.vx = this.vx * this.friction + this.fx;
this.vy = this.vy * this.friction + this.fy;
//@//dist(x1,y1,x2,y2)なので動かない。
//@//this.vx / v * this.maxVelocity;が代入などが行われない無効なコード
//@ float v = dist(this.vx, this.vy);
//@ if (v>this.maxVelocity) {
//@ this.vx / v * this.maxVelocity;
//@ this.vy / v * this.maxVelocity;
//@ }
}
void updatePosition()
{
this.x += this.vx;
this.y += this.vy;
if (this.x<0) {
this.x =0;
this.vx = abs(this.vx);
this.fx = 0;
}
if (this.x>width) {
this.x=width;
this.vx = -abs(this.vx);
this.fx = 0;
}
if (this.y<0) {
this.y=0;
this.vy = abs(this.vy);
this.fy = 0;
}
if (this.y>height) {
this.y=height;
this.vy = -abs(this.vy);
this.fy = 0;
}
}
void draw()
{
stroke(150);
ellipse(this.x, this.y, 10, 10);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment