why do the circles disappear from the screen? - processing

Processing code as below, one quick question: why do the circles disappear from the screen when my mouse is playing with them? i've already add the boundary check however it does not seem to work. why???
int maxCircle = 200;
float minDistance=30;
float distance1;
float distance2;
Circle [] circles= new Circle[maxCircle];
void setup() {
size(800,800);
smooth();
for(int i=0;i<maxCircle;i++){
circles[i] = new Circle(random(width),random(height),random(2,20));
}
}
void draw() {
background(255,255);
for(int i=0;i<maxCircle;i++) {
circles[i].update(width,height);
for (int j=0; j<maxCircle; j++) {
distance1 = dist(circles[i].x,circles[i].y,circles[j].x,circles[j].y);
if ( distance1 < minDistance ) {
stroke(0,10);
noFill();
line(circles[i].x,circles[i].y,circles[j].x,circles[j].y);
}
}
circles[i].display();
}
}
void mouseMoved() {
for(int i = 0; i<maxCircle;i++) {
distance2 = dist(mouseX,mouseY,circles[i].x,circles[i].y);
circles[i].x-=(mouseX-circles[i].x)/distance2;
circles[i].y-=(mouseX-circles[i].y)/distance2;
if(circles[i].x<circles[i].r || circles[i].x>width-circles[i].r) {
circles[i].vx*=-1;
};
if(circles[i].y<circles[i].r || circles[i].y> height-circles[i].r) {
circles[i].vy*=-1;
}
}
}
class Circle {
float x,y,vx,vy,r,speed;
Circle(float tempx, float tempy, float tempr) {
x=tempx;
y=tempy;
vx=random(-1,1);
vy=random(-1,1);
r=tempr;
}
void update(int w,int h) {
x+=vx;
y+=vy;
if(x<r || x>w-r) {
vx*=-1;
}
if(y<r || y>h-r) {
vy*=-1;
}
}
void display() {
fill(0,50);
noStroke();
ellipse(x,y,r,r);
}
}

Oh i found the solution:
int maxCircle = 200;
float minDistance = 20;
Circle [] circles = new Circle[maxCircle];
void setup() {
size(800, 800);
smooth();
for (int i = 0; i < maxCircle; i++) {
circles[i] = new Circle();
}
}
void draw() {
background(255, 255);
for (int i = 0; i < maxCircle; i++) {
circles[i].update();
noFill();
for (int j = 0; j < maxCircle; j++) {
if (i == j)
continue;
float distance = dist(circles[i].x, circles[i].y, circles[j].x, circles[j].y);
if (distance < minDistance) {
stroke(0, 20);
line(circles[i].x, circles[i].y, circles[j].x, circles[j].y);
}
}
circles[i].display();
}
}
void mouseMoved() {
for (int i = 0; i < maxCircle; i++) {
float distance = dist(mouseX, mouseY, circles[i].x, circles[i].y);
circles[i].x -= (mouseX - circles[i].x) / distance;
circles[i].y -= (mouseX - circles[i].y) / distance;
circles[i].checkBounds();
}
}
class Circle {
float x, y, vx, vy, r, speed;
Circle() {
vx = random(-1, 1);
vy = random(-1, 1);
r = random(1, 10); // See below
x = random(r, width - r);
y = random(r, height - r);
}
void checkBounds() {
if (x < r || x > width - r) {
vx *= -1;
if (x < r) {
x = r;
} else {
x = width - r;
}
}
if (y <= r || y >= height - r) {
vy *= -1;
if (y < r) {
y = r;
} else {
y = width - r;
}
}
}
void update() {
x += vx;
y += vy;
checkBounds();
}
void display() {
fill(0, 50);
noStroke();
ellipse(x, y, r * 2, r * 2);
}
}

in your update() method, when you calculate a new coordinate with your vector, you are potentially setting the coordinate offscreen. I have added 4 conditional statements that reset the value to the bounds of the screen if it exceeds it.
void update(int w,int h) {
x+=vx;
y+=vy;
if(x<r || x>w-r) {
vx*=-1;
if (x>w-r) x = w-r;
if (x<r) x = r;
}
if(y<r || y>h-r) {
vy*=-1;
if (y>h-r) y = h-r;
if (y<r) y = r;
}
}

Related

Can someone help me fix my DDA collision algorithm in processing?

I have been trying to make a DDA algorithm for a raycaster for a while now. For some reason I'm having a ton of trouble. The way my code works is that it puts a player into the map that spins at a constant rate. the green circle should be landing wherever the player is looking on the nearest wall. It seems to almost work when the line is more vertical than horizontal, but it still is a bit off. the moment it passes the y=x or y=-x line it goes crazy, seeming to shoot off into infinity. I suspect it has something to do with slope, but frankly I'm not really sure.
I have been following this video closely, but to no avail. I hope someone can spot the error in my code so I can continue with this project.
Here's a condensed version of my code:
int[][] map = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
float fov;
Player p;
void setup() {
size(800, 600);
background(0);
stroke(255);
fov = PI/2;
p = new Player(12.5, 12.5, -PI/4);
}
void draw() {
background(0);
p.map_();
p.ddaTest4();
p.dir += PI/512;
p.dir %= TWO_PI;
}
class Player {
float dir;
PVector pos = new PVector();
Player (float x, float y, float dir) {
this.dir = dir;
this.pos.x = x;
this.pos.y = y;
}
// this draws the map array as rectangles
void map_() {
noStroke();
float sf = height/map.length;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map.length; j++) {
if (map[j][i] != 0) {
stroke(0);
fill(255);
rect(i*sf, j*sf, height/sf, height/sf);
} else {
stroke(255);
fill(0);
rect(i*sf, j*sf, height/sf, height/sf);
}
}
}
}
void ddaTest4() {
float sf = height/map.length;
PVector rayDir = PVector.fromAngle(dir);
PVector stepScale = new PVector(sqrt(((rayDir.y/rayDir.x) * (rayDir.y/rayDir.x)) + 1), sqrt(((rayDir.x/rayDir.y) * (rayDir.x/rayDir.y)) + 1));
PVector mapPos = new PVector((int)pos.x, (int)pos.y);
PVector rayLength = new PVector();
PVector step = new PVector(1, 1);
if (rayDir.x < 0) {
step.x = -1;
rayLength.x = (pos.x - mapPos.x) * stepScale.x;
} else {
rayLength.x = ((mapPos.x + 1) - mapPos.x) * stepScale.x;
}
if (rayDir.y < 0) {
step.y = -1;
rayLength.x = (pos.y - mapPos.y) * stepScale.y;
} else {
rayLength.x = ((mapPos.y + 1) - mapPos.y) * stepScale.y;
}
boolean hit = false;
float distance = 0;
while(!hit) {
if (rayLength.x < rayLength.y) {
mapPos.x += step.x;
distance = rayLength.x;
rayLength.x += stepScale.x;
} else {
mapPos.y += step.y;
distance = rayLength.y;
rayLength.y += stepScale.y;
}
if (map[(int)mapPos.y][(int)mapPos.x] != 0) {
hit = true;
}
}
PVector hitPoint = PVector.add(pos, PVector.mult(rayDir, distance));
fill(0, 255, 0);
stroke(0, 255, 0);
line(pos.x*sf, pos.y*sf, hitPoint.x*sf, hitPoint.y*sf);
ellipse(hitPoint.x*sf, hitPoint.y*sf, 5, 5);
}
}
PS: sorry if I have poorly phrased my question, I'm not really sure how else to put it.

Is there a way for me to distribute points so that they're more compact near a different set of points?

I want to make a Voronoi tiling which fits itself to some text in Processing 3.5.3. I've got the algorithm for standard Voronoi tiling implemented, but I initialise all points to just be randomly distributed across the window.
I've got a list of points which make up some letters, generated by the geomerative package. They're all in the standard (x, y) format.
I'm looking for a function which would take the text points and the window size into account and give me back a sort of distribution, or, better yet, a list of points already following that distribution.
My code:
import geomerative.*;
public class Point {
public RPoint p = new RPoint(0, 0);;
public color c;
public boolean isTextPt;
public Point(int _w, int _h, float[][] distribution) {
this.p.x = random(_w);
this.p.y = random(_h);
//this.c = color(random(100, 250), random(100, 250), random(100, 250));
this.c = color(map(p.x, 0, _w, 50, 160), map(p.y, 0, _h, 0, 150), 255);
this.isTextPt = false;
}
public Point(float _x, float _y) {
this.p.x = _x;
this.p.y = _y;
this.c = color(random(50, 160), random(100, 250), 255);
this.isTextPt = true;
}
}
int baseAmountOfCells = 50;
RShape shape;
RPoint[] textPts;
Point[] points;
void setup() {
RG.init(this);
shape = new RFont("RobotoMono-Medium.ttf", 140, RFont.CENTER).toShape("voronoi songs for worley days");
textPts = shape.getPoints();
fullScreen();
colorMode(HSB);
points = new Point[baseAmountOfCells + textPts.length];
for (int i = 0; i < baseAmountOfCells; i ++) {
points[i] = new Point(width, height);
}
for (int i = 0; i < textPts.length; i ++) {
points[baseAmountOfCells + i] = new Point(textPts[i].x / 2 + width / 2, textPts[i].y / 2 + height / 2);
}
println("Amount of text points: " + str(textPts.length));
}
void draw() {
loadPixels();
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float record = width * height; //it can never be more than this
int recIndex = 0;
for (int i = 0; i < points.length; i++) {
float d = dist(x, y, points[i].p.x, points[i].p.y);
if (d < record) {
record = d;
recIndex = i;
}
}
Point pt = points[recIndex];
pixels[index] = color(pt.c);
index++;
}
}
updatePixels();
for (Point pt : points) {
if (pt.isTextPt) {
stroke(0);
strokeWeight(2);
point(pt.p.x, pt.p.y);
}
}
noLoop();
}

How do i make the movement function for the player count only once so that they can be executed one by one?

I have a game currently which has a player and some obstacles, I want to navigate this player with some commands, but the problem is that the command get executed but the rectangle does not get updated so I have to do some weird while logic with break and a global variable, because otherwise the player would jump. Is there a way to make the functions only count once and maybe loop with for and while normally? this is my code so far:
int border = 20;
int sqsize = 96;
int i = 0;
ArrayList<player> players = new ArrayList<player>();
ArrayList<obstacle> obstacles = new ArrayList<obstacle>();
void setup() {
size(1000, 1000);
players.add(new player(9, 0));
obstacles.add(new obstacle(4, 0));
obstacles.add(new obstacle(4, 1));
obstacles.add(new obstacle(4, 2));
obstacles.add(new obstacle(4, 3));
obstacles.add(new obstacle(4, 4));
obstacles.add(new obstacle(4, 5));
}
void draw() {
background(#767C7C);
for (int l = 0; l < 10; l++) {
for (int w = 0; w < 10; w++) {
fill(#F6F9EF);
stroke(#BABAB6);
strokeWeight(0.5);
rect(border + l*sqsize, border + w*sqsize, sqsize, sqsize);
}
}
players.get(0).draw();
for ( int i = obstacles.size()-1; i>= 0; i--) {
obstacles.get(i).draw();
}
for ( int i = obstacles.size()-1; i>= 0; i--) {
obstacles.get(i).ask();
}
while (i < 5) {
players.get(0).links();
players.get(0).unten();
break;
}
i++;
}
class player {
int x, y;
player(int ix, int iy) {
x = border + ix*sqsize;
y = border + iy*sqsize;
}
void draw() {
fill(255, 0, 0);
rect(x, y, sqsize, sqsize);
}
void right() {
if (x < 1000-2*sqsize) {
x = x + sqsize;
}
}
void left() {
if (x > 20) {
x = x - sqsize;
}
}
void up() {
if (y > 20+sqsize) {
y = y + sqsize;
}
}
void down() {
if (y < 1000-2*sqsize) {
y = y + sqsize;
}
}
void destroy() {
textSize(64);
text("Game Over", 500-2*sqsize, 500-sqsize/2);
noLoop();
}
int[] request() {
int[] pos = {x, y};
return pos;
}
}
class obstacle {
int x, y;
obstacle(int ix, int iy) {
x = border + ix*sqsize;
y = border + iy*sqsize;
}
void draw() {
fill(255, 0, 0);
rect(x, y, sqsize, sqsize);
}
void rechts() {
if (x < 1000-2*sqsize) {
x = x + sqsize;
}
}
void links() {
if (x > 20) {
x = x - sqsize;
}
}
void oben() {
if (y > 20+sqsize) {
y = y + sqsize;
}
}
void unten() {
if (y < 1000-2*sqsize) {
y = y + sqsize;
}
}
void ask() {
for ( int i = players.size()-1; i>= 0; i--) {
int[] check = players.get(i).request();
if (/*dist(check[0]+sqsize, check[1]+sqsize, x, y) == 0 || dist(check[0]-sqsize, check[1]-sqsize, x, y) == 0 ||*/ dist(check[0], check[1], x, y) == 0) {
players.get(i).destroy();
}
}
}
}
Is there a way also to detect which side of the player has touched the obstacle.
thank you very much (I’m a newbie).
This is how I solved my problem (I used cases):
int border = 20;
int sqsize = 96;
int n = 0;
boolean f = true;
long lastTime = 0;
int count = 0;
int[] list = new int[100];
ArrayList<Player> Players = new ArrayList<Player>();
ArrayList<Obstacle> Obstacles = new ArrayList<Obstacle>();
void setup() {
size(1000, 1000);
Players.add(new Player(9, 0));
Obstacles.add(new Obstacle(4, 0));
Obstacles.add(new Obstacle(4, 1));
Obstacles.add(new Obstacle(4, 2));
Obstacles.add(new Obstacle(2, 3));
Obstacles.add(new Obstacle(4, 4));
Obstacles.add(new Obstacle(4, 5));
lastTime = millis();
}
void draw() {
background(#767C7C);
for (int l = 0; l < 10; l++) {
for (int w = 0; w < 10; w++) {
fill(#F6F9EF);
stroke(#BABAB6);
strokeWeight(0.5);
rect(border + l*sqsize, border + w*sqsize, sqsize, sqsize);
}
}
/*Players.get(0).left();
Players.get(0).down();*/
if (f) {
count = 0;
list = new int[50];
player();
f = false;
}
Players.get(0).draw();
for ( int i = Obstacles.size()-1; i>= 0; i--) {
Obstacles.get(i).draw();
}
for ( int i = Obstacles.size()-1; i>= 0; i--) {
Obstacles.get(i).ask();
}
}
class Player {
int x, y;
int posCase = 0;
Player(int ix, int iy) {
x = border + ix*sqsize;
y = border + iy*sqsize;
}
void draw() {
while (n < count) {
if ( millis() - lastTime > 600 ) {
posCase = list[n];
println(n);
if (posCase == 5) {
noLoop();
}
switch(posCase) {
case 1 :
if (x < 1000-2*sqsize) {
x = x + sqsize;
}
break;
case 2 :
if (x > 20) {
x = x - sqsize;
}
break;
case 3 :
if (y > 20+sqsize) {
y = y + sqsize;
}
break;
case 4 :
if (y < 1000-2*sqsize) {
y = y + sqsize;
}
break;
}
n++;
if ( n == count) {
println("yes");
f = true;
}
lastTime = millis();
}
break;
}
fill(255, 0, 0);
rect(x, y, sqsize, sqsize);
}
void right() {
list[count] = 1;
count++;
/*f (x < 1000-2*sqsize) {
x = x + sqsize;
redraw();
}*/
}
void left() {
list[count] = 2;
count++;
/*if (x > 20) {
x = x - sqsize;
redraw();
}*/
}
void up() {
list[count] = 3;
count++;
/*if (y > 20+sqsize) {
y = y + sqsize;
redraw();
}*/
}
void down() {
list[count] = 4;
count++;
/*if (y < 1000-2*sqsize) {
y = y + sqsize;
redraw();*/
}
void ende() {
list[count] = 5;
count++;
}
void destroy() {
textSize(64);
text("Game Over", 500-2*sqsize, 500-sqsize/2);
noLoop();
}
int[] request() {
int[] pos = {x, y};
return pos;
}
}
class Obstacle {
int x, y;
int posCase = 0;
Obstacle(int ix, int iy) {
x = border + ix*sqsize;
y = border + iy*sqsize;
}
void draw() {
while (n < count) {
if ( millis() - lastTime > 600 ) {
posCase = list[n];
println(n);
if (posCase == 5) {
noLoop();
}
switch(posCase) {
case 1 :
if (x < 1000-2*sqsize) {
x = x + sqsize;
}
break;
case 2 :
if (x > 20) {
x = x - sqsize;
}
break;
case 3 :
if (y > 20+sqsize) {
y = y + sqsize;
}
break;
case 4 :
if (y < 1000-2*sqsize) {
y = y + sqsize;
}
break;
}
n++;
if ( n == count) {
println("yes");
f = true;
}
lastTime = millis();
}
break;
}
fill(255, 0, 0);
rect(x, y, sqsize, sqsize);
}
void right() {
list[count] = 1;
count++;
/*f (x < 1000-2*sqsize) {
x = x + sqsize;
redraw();
}*/
}
void left() {
list[count] = 2;
count++;
/*if (x > 20) {
x = x - sqsize;
redraw();
}*/
}
void up() {
list[count] = 3;
count++;
/*if (y > 20+sqsize) {
y = y + sqsize;
redraw();
}*/
}
void down() {
list[count] = 4;
count++;
/*if (y < 1000-2*sqsize) {
y = y + sqsize;
redraw();*/
}
void ende() {
list[count] = 5;
count++;
}
void ask() {
for ( int i = Players.size()-1; i>= 0; i--) {
int[] check = Players.get(i).request();
if ( dist(check[0], check[1], x, y) == 0) {
Players.get(i).destroy();
}
}
}
}

How to use Hashmap or Array to create a "list" of countries with attributes

I'm trying to visualize migration data using particle systems. Each row of the dataset contains: source country, destination country, year, and various amounts.
Each row should be represented as a particle system representing that data.
QUESTION:
What will be the best way to create a list of countries or country objects, with x,y location attributes and maybe some other attributes that could be added later?
Entire code for reference:
// Based on Example Written by Casey Reas and Ben Fry
// Edited by Tom Bar-Gal
//particlesystem()
//addparticle()
//particle()
// ========== Table Data Stuff
Table table;
int k = 0;
String[] destCountryArray = new String[0];
String[] sourceCountryArray = new String[0];
String destCountry = "";
String prevDestCountry = "";
String sourceCountry;
// ========
int maxParticles = 12000;
ParticleSystem ps;
ParticleSystem ps2;
int n = 0, n2=0;
int emmitMultiplyer = 1;
int emmitFreq = 1;
float particleSpeed = 0.002;
float locationX = 250;
float locationY = 450;
int[] sourceX = {10, 40, 200, 400, 700};
int[] destX = {300, 600, 300, 600, 600};
int[] amount = {10, 100, 500, 800, 1000};
int highestAmount = max(amount);
// a,b,c... max*a/{a+b+c...}
ParticleSystem[] PSystems;
void setup() {
size(1200, 800);
//=============== load table and create an array of countries
table = loadTable("asylum_seekers.csv", "header");
destCountryArray = (String[]) append(destCountryArray, "Israel");
for (TableRow row : table.rows()) {
//println("going over row" + row.getString("Country / territory of asylum/residence"));
String tempCountryHolder = row.getString("Country / territory of asylum/residence");
//println("Got a temp country holder" + tempCountryHolder);
boolean exists = countryExists(tempCountryHolder);
if (exists==true) {
//println("exists, skipping");
continue;
}
println("Appending "+tempCountryHolder+" to list of length " +destCountryArray.length);
destCountryArray = (String[]) append(destCountryArray, tempCountryHolder);
println("destCountryArray length = "+ destCountryArray.length);
}
//============================
PSystems = new ParticleSystem[destCountryArray.length];
//frameRate(30);
//colorMode(RGB,255,255,255,255);
for (int i = 0; i<destCountryArray.length; i++) {
// Particle Systems syntax = multiplyer, source, destination, amount);
PSystems[i] = new ParticleSystem(1, new Vector3D(i*40+40, 100, 0), new Vector3D(i*40+40, 500, 0), 1/(i+1));
//println("PSystems " + i + " is " +PSystems[i]);
}
//ps = new ParticleSystem(1, new Vector3D(width/2, height/2, 0));
//ps2 = new ParticleSystem(1, new Vector3D(100, 200, 0));
smooth();
}
void draw() {
background(250);
//ellipse(locationX, locationY, 5, 5);
//ellipse(width/2, height/2, 5, 5);
//ellipse(100, 200, 5, 5);
//println(PSystems.length);
for (int i = 0; i<destCountryArray.length; i++) {
//println(PSystems[i]);
PSystems[i].run();
}
for (int i = 0; i<emmitMultiplyer; i++) {
for (int k = 0; k<destCountryArray.length; k++) {
if (frameCount % (k+1) == 0) {
PSystems[k].addParticle();
n++;
}
}
}
n2+=emmitMultiplyer;
fill(0);
text("Frame rate: "
+ int(frameRate), 10, 20);
println(n);
println(n);
}
// ==============================// A simple Particle class // ===============================================//
class Particle {
Vector3D loc;
Vector3D des;
Vector3D vel;
Vector3D acc;
Vector3D locHome, b, c;
float relativeSpeed;
float r;
float timer;
float t=0.0;
// Another constructor (the one we are using here)
Particle(Vector3D l, Vector3D m) {
//acc = new Vector3D(0,0.0005,0); // particle acceleration
acc = new Vector3D(0, 0, 0); // new Vector3D(random(-0.1, 0.1), random(-0.02, 0), 0);
loc = l.copy();
des = m.copy();
locHome = l.copy();
locHome.x = locHome.x+random(-2, 2);
locHome.y = locHome.y+random(-2, 2);
des.x = des.x+random(-2, 2);
des.y=des.y+random(-2, 2);
relativeSpeed = random(0.5, 1.2);
r = random(0.9, 2.3); // particle radius
timer = 10000.0; // particles lifespan
// * emmitMultiplyer = number of living
b=new Vector3D(locHome.x+random(-20, 20), locHome.y+random(120, 180), 0);
c=new Vector3D(des.x+random(-20, 30), des.y-random(120, 180), 0);
}
void run() {
update();
render();
}
// Method to update location
void update() {
if (t>=1)
return;
// https : // www.processing.org/reference/bezierPoint_.html
loc.x = bezierPoint(locHome.x, b.x, c.x, des.x, t);
loc.y = bezierPoint(locHome.y, b.y, c.y, des.y, t);
t = lerp(t, 1, particleSpeed*relativeSpeed);
//t+=particleSpeed*relativeSpeed;
// curvePoint(a, b, c, d, t)
// vel.add(acc);
// loc.add(vel);
//timer -= 1.0;
}
// Method to display
void render() {
ellipseMode(CENTER);
noStroke();
fill(70, 255);
ellipse(loc.x, loc.y, r, r);
}
// Is the particle still useful?
boolean dead() {
// if (timer <= 0.0||t>=1.0) {
if (t>=0.95) {
return true;
} else {
return false;
}
}
}
// ==============================// A ParticleSystem // ===============================================//
// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles
class ParticleSystem {
ArrayList particles; // An arraylist for all the particles
Vector3D origin; // An origin point for where particles are birthed
Vector3D dest;
int freq;
//ParticleSystem( number of particles / frame, source, destination, frequency);
ParticleSystem(int num, Vector3D v, Vector3D d, float f) {
particles = new ArrayList(); // Initialize the arraylist
origin = v.copy(); // Store the origin point
dest = d.copy();
//if (frameCount % (1/f) == 0){
for (int i = 0; i < num; i++) {
particles.add(new Particle(origin, dest)); // Add "num" amount of particles to the arraylist
}
//}
}
void run() {
// Cycle through the ArrayList backwards b/c we are deleting
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.run();
if (p.dead()) {
particles.remove(i);
n--;
}
}
}
void addParticle() {
particles.add(new Particle(origin, dest));
}
//void addParticle(Particle p) {
// particles.add(p);
//}
// A method to test if the particle system still has particles
boolean dead() {
if (particles.isEmpty()) {
return true;
} else {
return false;
}
}
}
//=================================================== Class Country
public class Country {
public float countryIndex;
public float countryLocationX;
public float countryLocationY;
public float countryName;
}
// ================================================ Simple Vector3D Class
public class Vector3D {
public float x;
public float y;
public float z;
Vector3D(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}
Vector3D(float x_, float y_) {
x = x_;
y = y_;
z = 0f;
}
Vector3D() {
x = 0f;
y = 0f;
z = 0f;
}
void setX(float x_) {
x = x_;
}
void setY(float y_) {
y = y_;
}
void setZ(float z_) {
z = z_;
}
void setXY(float x_, float y_) {
x = x_;
y = y_;
}
void setXYZ(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}
void setXYZ(Vector3D v) {
x = v.x;
y = v.y;
z = v.z;
}
public float magnitude() {
return (float) Math.sqrt(x*x + y*y + z*z);
}
public Vector3D copy() {
return new Vector3D(x, y, z);
}
public Vector3D copy(Vector3D v) {
return new Vector3D(v.x, v.y, v.z);
}
public void add(Vector3D v) {
x += v.x;
y += v.y;
z += v.z;
}
public void sub(Vector3D v) {
x -= v.x;
y -= v.y;
z -= v.z;
}
public void mult(float n) {
x *= n;
y *= n;
z *= n;
}
public void div(float n) {
x /= n;
y /= n;
z /= n;
}
public void normalize() {
float m = magnitude();
if (m > 0) {
div(m);
}
}
public void limit(float max) {
if (magnitude() > max) {
normalize();
mult(max);
}
}
public float heading2D() {
float angle = (float) Math.atan2(-y, x);
return -1*angle;
}
public Vector3D add(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
return v;
}
public Vector3D sub(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
return v;
}
public Vector3D div(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x/n, v1.y/n, v1.z/n);
return v;
}
public Vector3D mult(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x*n, v1.y*n, v1.z*n);
return v;
}
public float distance (Vector3D v1, Vector3D v2) {
float dx = v1.x - v2.x;
float dy = v1.y - v2.y;
float dz = v1.z - v2.z;
return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
}
}
boolean countryExists(String tempCountryHolder) {
for (int i = 0; i < destCountryArray.length; i++) {
//println("comparing '" +tempCountryHolder +"' with '"+destCountryArray[i] + "'");
if (tempCountryHolder.equals(destCountryArray[i]) == true) {
//println("found : "+ tempCountryHolder);
return true; // it exists
} //if
} //for
return false ; // not found
}//func
answer was: hashmap of hashmaps
HashMap<String, HashMap> countries = new HashMap<String, HashMap>();
for (int i=0; i<destCountryArray.length; i++) {
HashMap<String, Float> country = new HashMap<String, Float>();
countries.put(destCountryArray[i], country);
country.put("x", i*20.0);
country.put("y", i*40.0);
}
for (Map.Entry me : countries.entrySet()) {
print(me.getKey() + " is ");
println(me.getValue());
}
You probably don't want to use a nested HashMap like your answer suggests. You probably want to use your own class instead. Something like this:
HashMap<String, Point> countries = new HashMap<String, Point>();
void setup(){
countries.put("one", new Point(2, 3));
countries.put("four", new Point(5, 6));
}
void draw(){
Point pOne = countries.get("one");
point(pOne.x, pOne.y);
}
class Point{
float x;
float y;
public Point(float x, float y){
this.x = x;
this.y = y;
}
}
Or better yet, you could just use Processing's PVector class, which already represents points:
HashMap<String, PVector> countries = new HashMap<String, PVector>();
void setup(){
countries.put("one", new PVector(2, 3));
countries.put("four", new PVector(5, 6));
}
void draw(){
PVector pOne = countries.get("one");
point(pOne.x, pOne.y);
}
More info can be found in the reference. Shameless self-promotion: here is a tutorial on using classes, and here is a tutorial on creating your own classes.

Array is only displaying 1 object instead of the full amount of variables

I'm new to coding (as I'm sure you might be able to tell). The program runs and generates 1 Tubble, but the additional objects don't show.
Here's my class:
class Tubble {
float x;
float y;
float diameter;
float yspeed;
float tempD = random(2,86);
Tubble() {
x = random(width);
y = height-60;
diameter = tempD;
yspeed = random(0.1, 3);
}
void ascend() {
y -= yspeed;
x = x + random(-2, 2);
}
void dis() {
stroke(0);
fill(127, 100);
ellipse(x, y, diameter, diameter);
}
void top() {
if (y < -diameter/2) {
y = height+diameter/2;
}
}
}
Class
class Particle {
float x, y;
float r;
float speed = 2.2;
int direction = 1;
PImage pbubbles;
Particle(float x_, float y_, float r_) {
x = x_;
y = y_;
r = r_;
}
void display() {
stroke(#F5D7D7);
strokeWeight(2.2);
noFill();
ellipse(x, y, r*2, r*2);
}
boolean overlaps(Particle other) {
float d = dist(x, y, other.x, other.y);
if (d < r + other.r) {
return true;
} else {
return false;
}
}
void move() { //testing
x += (speed * direction);
if ((x > (width - r)) || (x < r)) {
direction *= -1;
}
}
void updown() {
y += (speed * direction);
if ((y > (height - r)) || (y < r)) {
direction *= -1;
}
}
}
Main sketch:
Tubble[] tubbles = new Tubble [126];
PImage bubbles;
Particle p1;
Particle p2;
Particle p3;
Particle p4;
Particle p5;
float x,y;
float speed;
int total = 0;
int i;
//int direction = 1;
void setup() {
size(800, 925);
bubbles = loadImage("purple_bubbles.png");
p1 = new Particle (100, 100, 50);
p2 = new Particle (500, 200, 100);
p3 = new Particle (600, 600, 82);
p4 = new Particle (height/2, width/2, 200);
p5 = new Particle ((height/3), (width/3), 20);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i] = new Tubble();
}
}
void mousePressed() {
total = total + 1;
}
void keyPressed() {
total = total - 1;
}
void draw() {
image(bubbles, 0, 0, 800, 925);
//background(0);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i].ascend();
tubbles[i].dis();
tubbles[i].top();
}
if ((p2.overlaps(p1)) && (p2.overlaps(p4))) {
background(#BF55AB, 25);
}
if ((p3.overlaps(p2)) && (p3.overlaps(p4))) {
background(#506381, 80);
}
p2.x = mouseX;
p3.y = mouseY;
p1.display();
p2.display();
p3.display();
p4.display();
p5.display();
p4.move();
p5.updown();
// for (int i = 0; i < tubbles.length; i++); {
// tubbles[i].dis();
// tubbles[i].ascend();
// tubbles[i].top();
// }
}
There are extra semicolons in the lines
for (int i = 0; i < tubbles.length; i++); {
for (int i = 0; i < tubbles.length; i++); {
// for (int i = 0; i < tubbles.length; i++); {
It make the for loop do virtually nothing.
Then the block after the for loop will read the global variable i and do the action only once.
Remove the semicolons like this to put the block in the loop.
for (int i = 0; i < tubbles.length; i++) {
for (int i = 0; i < tubbles.length; i++) {
// for (int i = 0; i < tubbles.length; i++) {

Resources