Skip to content

Commit

Permalink
interactive
Browse files Browse the repository at this point in the history
  • Loading branch information
DomonJi committed Nov 26, 2016
1 parent d25c58c commit 8c0cb5a
Show file tree
Hide file tree
Showing 6 changed files with 440 additions and 1 deletion.
91 changes: 91 additions & 0 deletions FlowFiled.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

class FlowField {
PVector[][] field;
int cols, rows;
int resolution;
int affectRadius;
File file = new File(dataPath("field.txt"));

FlowField(int r) {
resolution = r;
cols = 1200 / resolution;
rows = 950 / resolution;
field = new PVector[cols][rows];
init();
affectRadius = 3;
}

void init() {
try { readField(); }
catch(Exception e) {
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
field[i][j] = new PVector(0, 0);
}
}
}
}

PVector lookup(float x, float y) {
int column = int(constrain(x/resolution, 0, cols-1));
int row = int(constrain(y/resolution, 0, rows-1));
return field[column][row];
}

void drawField(float x, float y, PVector v) {
int column = int(constrain(x/resolution, 0, cols-1));
int row = int(constrain(y/resolution, 0, rows-1));
for (int i=-affectRadius; i<=affectRadius; i++) {
for (int j=-affectRadius; j<=affectRadius; j++) {
if (i*i+j*j<affectRadius*affectRadius) {
try { field[column+i][row+j] = v; }
catch(Exception e) {}
}
}
}
}

void onMouseDrag() {
PVector direc = new PVector(mouseX-pmouseX, mouseY-pmouseY).normalize();
drawField(pmouseX, pmouseY, direc);
}

void saveField() {
try {
FileWriter out = new FileWriter(file);
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
out.write(field[i][j].x+","+field[i][j].y+"\t");
}
out.write("\r\n");
}
out.close();
}
catch(Exception e) {}
}

void readField() throws IOException {
try {
BufferedReader in = new BufferedReader(new FileReader(file));
String line;
for (int i = 0; (line = in.readLine()) != null; i++) {
String[] temp = line.split("\t");
for (int j=0; j<temp.length; j++) {
String[] xy = temp[j].split(",");
float x = Float.parseFloat(xy[0]);
float y = Float.parseFloat(xy[1]);
field[i][j] = new PVector(x, y);
}
}
in.close();
}
catch(Exception e) {
throw new IOException("no field.txt");
}
}
}
100 changes: 100 additions & 0 deletions InteractiveStarryNight.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
final int STAGE_WIDTH = 1200;
final int STAGE_HEIGHT = 950;
final int NB_PARTICLES = 60000;
final float MAX_PARTICLE_SPEED = 2.5;
final float PARTICULE_SIZE = 2;
final int MIN_LIFE_TIME = 10;
final int MAX_LIFE_TIME = 20;
final String IMAGE_PATH = "starrynight.jpg";
myVector tabParticles[];
PImage myImage;
int imageW;
int imageH;
color myPixels[];
FlowField ff;

void setup()
{
size(1200, 950, P3D);
background(0);
initializeImage();
initializeParticles();
ff = new FlowField(5);
}

void initializeImage()
{
myImage = loadImage(IMAGE_PATH);
imageW = myImage.width;
imageH = myImage.height;
myPixels = new color[imageW * imageH];
myImage.loadPixels();
myPixels = myImage.pixels;
image(myImage, 0, 0);
}

void setParticle(int i) {
tabParticles[i] = new myVector((int)random(imageW), (int)random(imageH));
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
tabParticles[i].count = (int)random(MIN_LIFE_TIME, MAX_LIFE_TIME);
tabParticles[i].myColor = myPixels[(int)(tabParticles[i].y)*imageW + (int)(tabParticles[i].x)];
}

void initializeParticles()
{
tabParticles = new myVector[NB_PARTICLES];
for (int i = 0; i < NB_PARTICLES; i++)
{
setParticle(i);
}
}

void draw()
{
float vx;
float vy;
PVector v;
for (int i = 0; i < NB_PARTICLES; i++)
{
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
v = ff.lookup(tabParticles[i].x, tabParticles[i].y);
vx = v.x;
vy = v.y;
vx = constrain(vx, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
vy = constrain(vy, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
tabParticles[i].x += vx;
tabParticles[i].y += vy;
tabParticles[i].count--;
if ((tabParticles[i].x < 0) || (tabParticles[i].x > imageW-1) ||
(tabParticles[i].y < 0) || (tabParticles[i].y > imageH-1) ||
tabParticles[i].count < 0) {
setParticle(i);
}
strokeWeight(sqrt(vx*vx + vy*vy)*1.5*PARTICULE_SIZE);
stroke(tabParticles[i].myColor, 200);
line(tabParticles[i].prevX, tabParticles[i].prevY, tabParticles[i].x, tabParticles[i].y);
}
}

void mouseDragged() {
ff.onMouseDrag();
}

void keyPressed() {
if (key =='s' || key == 'S') {
//ff.saveField();
}
}

class myVector extends PVector
{
myVector (float p_x, float p_y) {
super(p_x, p_y);
}
float prevX;
float prevY;
int count;
color myColor;
}
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# InteractiveStarryNight
# InteractiveStarryNight

An interactive starry night implementation made with processing.

You can draw your own flow field and press `S` to save your field.

##

![](./starrynight.gif)
Loading

0 comments on commit 8c0cb5a

Please sign in to comment.