Processing Image Load Error - processing

I've added a background image to my processing file which works fine when I run it in Processing locally, however, I'm receiving this error in console when I host the file:
Uncaught Error using image in background(): PImage not loaded.
I can't find anywhere why this may be happening. Please see my code below:
Particle p = new Particle();
final int LIGHT_FORCE_RATIO = 70; final int LIGHT_DISTANCE= 70 * 50; final int BORDER = 100; float baseRed, baseGreen, baseBlue; float baseRedAdd, baseGreenAdd, baseBlueAdd; final float RED_ADD =
3.2; final float GREEN_ADD = 1.7; final float BLUE_ADD = 4.3; float boxX, boxY; float widthSize = width;
int rectWidth = 915; int rectHeight = 197;
PImage img;
void setup() { img = loadImage("https://s3.amazonaws.com/zcom-media/sites/a0iE000000QK9yZIAT/media/mediamanager/bannerbg.jpg");
background(img); size(1840, 400); // surface.setResizable(true); noCursor(); //img = loadImage("flowtoy.jpg"); baseRed = 0; baseRedAdd = RED_ADD;
baseGreen = 0; baseGreenAdd = GREEN_ADD;
baseBlue = 0; baseBlueAdd = BLUE_ADD;
boxX = width/2; boxY = height/2;
img.loadPixels(); for (int i = 0; i < img.pixels.length; i++) { img.pixels[i] = color(0, 90, 102); } img.updatePixels(); }
void draw() { //image(img, 400, 100, img.width/2, img.height/2); if (mouseX>boxX-rectWidth && mouseX<boxX+rectWidth &&
mouseY>boxY-rectHeight && mouseY<boxY+rectHeight) {
//saveFrame("output/LightDrawing_####.png");
baseRed += baseRedAdd;
baseGreen += baseGreenAdd;
baseBlue += baseBlueAdd;
colorOutCheck();
p.move(mouseX, mouseY);
int tRed = (int)baseRed;
int tGreen = (int)baseGreen;
int tBlue = (int)baseBlue;
tRed *= tRed;
tGreen *= tGreen;
tBlue *= tBlue;
loadPixels();
int left = max(0, p.x - BORDER);
int right = min(width, p.x + BORDER);
int top = max(0, p.y - BORDER);
int bottom = min(height, p.y + BORDER);
for (int y = top; y < bottom; y++) {
for (int x = left; x < right; x++) {
int pixelIndex = x + y * width;
int r = pixels[pixelIndex] >>16 & 0xFF;
int g = pixels[pixelIndex] >> 8 & 0xFF;
int b = pixels[pixelIndex] & 0xFF;
int dx = x - p.x;
int dy = y - p.y;
int distance = (dx *dx ) + (dy* dy);
if (distance < LIGHT_DISTANCE) {
int fixFistance = distance * LIGHT_FORCE_RATIO;
if (fixFistance == 0) {
fixFistance = 1;
}
r = r + tRed / fixFistance;
g = g + tGreen / fixFistance;
b = b + tBlue / fixFistance;
}
pixels[x + y * width] = color(r, g, b);
}
}
updatePixels(); } else {
setup(); }
//updatePixels(); }
void colorOutCheck() { if (baseRed < 10) {
baseRed = 10;
baseRedAdd *= -1; } else if (baseRed > 255) {
baseRed = 255;
baseRedAdd *= -1; }
if (baseGreen < 10) {
baseGreen = 10;
baseGreenAdd *= -1; } else if (baseGreen > 255) {
baseGreen = 255;
baseGreenAdd *= -1; }
if (baseBlue < 10) {
baseBlue = 10;
baseBlueAdd *= -1; } else if (baseBlue > 255) {
baseBlue = 255;
baseBlueAdd *= -1; } }
void mousePressed() { setup(); }
class Particle { int x, y; float vx, vy; //float slowLevel;
Particle() {
x = (int)3;
y = (int)2; // slowLevel = random(100) + 1; }
void move(float targetX, float targetY) {
vx = (targetX - x) ;
vy = (targetY - y) ;
x = (int)(x + vx);
y = (int)(y + vy); } }
Can anybody explain why this may be happening? It's much appreciated, thank you.

I assume by 'hosting the file' you mean running the sketch at www.openprocessing.org.
There are two problem with your code:
Using background() inside setup. This will not work, you will get the error you mentioned. You can try moving that to draw().
Using an image which is hosted in another server. You should host your own images.
A workaround to problem 2 is to store the image as a base64 encoded string.
String uriBase64 = "data:image/jpeg;base64,/9j/4AAQSkZJRgA";
img = loadImage(uriBase64);
Full example here: https://www.openprocessing.org/sketch/511424

Related

Change variable in array coded with processing

Help!
I'm drawing a sketch with randomized letters that fill the screen. The code issue is with my
for (int i = 0; i < I1; i++) {
targets = tX + i * ts;
targets2 = tY;
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets = random(ts, width - ts);
targets2 = random(ts, height - ts);`
** I need to update i within the for loop to denote the array letters' locations. The error returns a type mismatch, "float" does not match with int[]
How do I update the i within the for loop?/ (the targets= and targets2=)
Here is the code**
String message = "a,b,c,d,e,f";
int []positions = new int [0];
int[]positions2= new int[1];
int []targets = new int [0] ;
int [] targets2= new int[1];
int I1= message.length();
boolean runTowards = true;
float runSpeed = 100;
float restSpeed = 1;
float currentSpeed = restSpeed;
float ts = 64;
boolean thisHasReached;
float bk;
float elapsedTime;
boolean allHaveReached;
float pauseTime = 1000;
float distX;
float distY;
float changeX;
float changeY;
float tX;
float tY;
float reachedTargetAt = 0;
boolean hasReachedTarget = true;
void setup() {
size (600,600);
background(255);
if ((I1 > targets.length) && (I1 > positions.length)){
pickNewTarget();
}
}
void draw() {
elapsedTime = millis() - reachedTargetAt;
if (elapsedTime > pauseTime) {
pickNewTarget();
}
drawChars();
updatePositions();
updateCurrentSpeed();
}
void drawChars() {
for (int i = 0; i < I1; i++) {
text(message.charAt(i),positions[i], positions[i]);
}
}
void updatePositions() {
allHaveReached = true;
thisHasReached = false;
for (int i = 0; i < I1; i++) {
distX = abs(positions[i] - targets[i]);
distY = abs(positions2[i] - targets2[i]);
changeX = random(currentSpeed);
changeY = random(currentSpeed);
thisHasReached = changeX > distX && changeY > distY;
if (positions[i] > targets[i]) {
changeX = -changeX;
}
if (positions2[i] > targets2[i]) {
changeY = -changeY;
}
positions[i] += changeX;
positions2[i] += changeY;
allHaveReached = allHaveReached && thisHasReached;
}
if ((!hasReachedTarget) && (allHaveReached)) {
hasReachedTarget = true;
reachedTargetAt = millis();
}
}
void updateCurrentSpeed() {
if (hasReachedTarget) {
if (currentSpeed >= restSpeed) {
currentSpeed -= (currentSpeed - restSpeed) * 9;
} else {
currentSpeed += 1;
}
} else {
if (currentSpeed <= runSpeed) {
currentSpeed += (runSpeed - currentSpeed) * 0.25;
} else {
currentSpeed -= 1;
}
}
}
void pickNewTarget() {
if (!runTowards && random(1) > 0.75) {
runTowards = true;
tX = random(ts, width - 3 * ts);
tY = random(ts, height - ts);
for (int i = 0; i < I1; i++) {
targets = tX + i * ts;
targets2 = tY;
}
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets = random(ts, width - ts);
targets2 = random(ts, height - ts);
}
}
hasReachedTarget = false;
}
Please look at this reference for random(): https://processing.org/reference/random_.html. Note that it states "If two parameters are specified, the function will return a float with a value between the two values." You got the error message because you tried to mix ints and floats. You can correct it by changing the array types from int to float, eg.
float[] targets = new float[80] ;
float[] targets2= new float[80];
You'll also need to make those arrays large enough to handle the size of your data or you'll wind up with another error that the array length has been overrun. Then change the loop to reflect that you are adding data to the arrays ([i]):
void pickNewTarget() {
if (!runTowards && random(1) > 0.75) {
runTowards = true;
tX = random(ts, width - 3 * ts);
tY = random(ts, height - ts);
for (int i = 0; i < I1; i++) {
targets[i] = tX + i * ts;
targets2[i] = tY;
}
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets[i] = random(ts, width - ts);
targets2[i] = random(ts, height - ts);
}
}
hasReachedTarget = false;
}
Also need to add a fill() for the text characters or you will see a blank screen.

Simulation stops after certain UI elements are used

Im working on a project in processing, and I'm having some difficulty with this super annoying bug. All the code is pasted below, 4 class files.
Whenever the "Simulation speed" slider is moved up and then moved back down, the simulation will stop giving no errors. Same thing with the "Auto" button. I have no idea why this is occurring and I've gone through my code following the variables and I don't see anything wrong.
Help!
noisedemo file
int tableHeight = 20;
int tableWidth = 20;
float prismWidth = 10;
float tableTopx = 260;
float tableTopy = 200;
int k = 0;
int simulationSpeed;
int frameCounter;
Prism[][] prisms = new Prism[tableWidth][tableHeight];
//Declare the sliders
Slider simulationSpeedSlider = new Slider(10, 20, 100, 30, "Simulation Speed");
Slider noiseOctaveSlider = new Slider(10, 50, 100, 4, "Noise Ocatave");
Slider noiseScaleSlider = new Slider(10, 80, 100, 10, 10, "Noise Scale", true);
//Declare the buttons
Button autoScrollButton = new Button(400, 100, "Auto");
void setup(){
size(500, 500);
smooth();
pixelDensity(2);
frameRate(30);
noiseDetail((int)noiseOctaveSlider.sliderValue, noiseScaleSlider.sliderValue);
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
prisms[i][j] = new Prism(noise(i, j)*30+10, prismWidth);
prisms[i][j].setHeight(noise(i, j)*30+10);
}
}
}
float[] convertCoordinate(int xcoord, int ycoord, float xtop, float ytop, float pwidth){
float[] coord = new float[2];
coord[0] = (xtop + xcoord*cos(radians(40))*prismWidth - ycoord * cos(radians(40))*prismWidth)*0.95;
coord[1] = (ytop + ycoord*sin(radians(40))*prismWidth + xcoord * sin(radians(40))*prismWidth)*0.95;
return coord;
}
void updateHeight(){
for(int i = 0; i < tableWidth; i++){
for(int j = 0; j < tableHeight; j++){
prisms[i][j].drawPrism(convertCoordinate(i, j, tableTopx, tableTopy, prismWidth)[0], convertCoordinate(i, j, tableTopx, tableTopy, prismWidth)[1]);
}
}
}
void setHeight(){
for(int i = 0; i < tableWidth; i++){
for(int j = 0; j < tableHeight; j++){
prisms[i][j].setHeight(noise(i+k, j+k)*30+10);
}
}
}
void mouseClicked(){
if(autoScrollButton.isInRange()){
autoScrollButton.buttonActive = !autoScrollButton.buttonActive;
}
}
void draw(){
background(0, 150, 0);
noiseDetail((int)noiseScaleSlider.sliderValue, noiseScaleSlider.sliderValue);
simulationSpeedSlider.drawSlider();
simulationSpeed = (int)simulationSpeedSlider.sliderValue;
noiseOctaveSlider.drawSlider();
noiseScaleSlider.drawSlider();
autoScrollButton.drawButton();
if(frameCounter == simulationSpeed && autoScrollButton.buttonActive){
k++;
frameCounter = 0;
setHeight();
}
updateHeight();
frameCounter++;
}
button file
class Button{
boolean buttonActive = true;
float buttonX;
float buttonY;
float buttonWidth = 30;
float buttonHeight = 15;
String buttonLabel;
Button(float x, float y, String label){
buttonX = x;
buttonY = y;
buttonLabel = label;
}
void drawButton(){
if(!buttonActive){
fill(100);
rect(buttonX, buttonY, buttonWidth, buttonHeight, 5);
fill(255);
text(buttonLabel, buttonX + 4, buttonY + 10);
}else{
fill(200);
rect(buttonX, buttonY, buttonWidth, buttonHeight, 5);
fill(0);
text(buttonLabel, buttonX + 4, buttonY + 10);
}
}
boolean isInRange(){
if(mouseX > buttonX && mouseX < buttonX + buttonWidth && mouseY > buttonY && mouseY < buttonY + buttonHeight){
return true;
}
else{
return false;
}
}
}
prism file
class Prism{
float pheight;
float pwidth;
Prism(float tempheight, float tempwidth){
pheight = tempheight;
pwidth = tempwidth;
}
Prism(){
pheight = 10;
pwidth = 5;
}
void drawPrism(float x, float y){
noStroke();
fill(175);
quad(x, y, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - pheight);
fill(100);
quad(x, y, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - pheight);
fill(225);
quad(x, y - pheight, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - 2*sin(radians(40))*pwidth - pheight, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight);
}
void setHeight(float tempheight){
pheight = tempheight;
}
}
slider file
class Slider{
float sliderLength;
float sliderX;
float sliderY;
float sliderWidth;
float handleWidth;
float sliderValue;
float sliderPos;
int sliderTotal;
boolean handleActive;
boolean isPrecise;
String sliderLabel;
//provide x and y position, length and the max value, the least amount of info
Slider(float x, float y, float slength, int total){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = 10;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = "";
}
//provide x and y position, length and the max value AND a label
Slider(float x, float y, float slength, int total, String label){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = 10;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = label;
}
//provide default values AND a label AND a width AND whether its precise
Slider(float x, float y, float slength, float swidth, int total, String label, boolean p){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = swidth;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = label;
isPrecise = p;
}
void drawSlider(){
fill(255);
textSize(10);
text(sliderLabel, sliderX, sliderY - 5);
text(sliderValue, sliderX + sliderLength + 7, sliderY + sliderWidth/1.1);
fill(100);
rect(sliderX-1, sliderY, sliderLength+1, sliderWidth, 5);
fill(255);
ellipse(sliderPos, sliderY + (sliderWidth/2), handleWidth, handleWidth);
if(!isPrecise){
sliderValue = (int)((sliderPos - sliderX)/(sliderLength/sliderTotal));
}else if(isPrecise){
sliderValue = (sliderPos - sliderX)/(sliderLength/sliderTotal);
}
if(mouseX >= sliderX && mouseX <= sliderX+sliderLength + sliderX && mouseY >= sliderY - (handleWidth/2) && mouseY <= sliderY + (handleWidth/2) && mousePressed){
handleActive = true;
}
if(!mousePressed){
handleActive = false;
}
if(handleActive && sliderPos <= sliderX + sliderLength && sliderPos >= sliderX){
sliderPos = mouseX;
}
if(sliderPos > sliderX + sliderLength){
sliderPos = sliderX + sliderLength;
}
if(sliderPos < sliderX){
sliderPos = sliderX + 1;
}
}
}
Thank you! Sorry if the code is a little messy :)
In your main file, this block relies on the values of those two controls:
if(frameCounter == simulationSpeed && autoScrollButton.buttonActive){
k++;
frameCounter = 0;
setHeight();
}
When that gets skipped (because you changed simulationSpeed or buttonActive), your frameCounter gets out of sync with simulationSpeed so the block continues to get skipped.

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();
}

Kd Tree or Bounding Box Not Working Properly

Hope everyone is well.I am having a bit of an issue implementing the kd tree from pbrt v2.It's fast but all the normals on the model are wrong after rendering.The funny thing is if I change the values of pMin and pMax in the Bounding Box constructor,I get the correct model with the correct normals but the render takes substantially longer.I dont know what could be causing this.By the way pbrt v2 uses a left-handed coordinate system while I am using a right-handed coordinate system.I have tried changing my coordinate to left-handed and also importing models from a left-handed system instead of a right-handed system but the issue still remains.At one point it worked but the models positions were reversed.Its best to show you my code so u can better understand my dilemma.
*BOUNDING BOX CODE *
class BBox
{
public:
Point pMin,pMax;
BBox(){
pMin = Point(INFINITY,INFINITY,INFINITY);
pMax = Point(-INFINITY,-INFINITY,-INFINITY);
}
BBox(const Point& p) : pMin(p),pMax(p) { }
BBox(const Point& p1,const Point& p2) {
pMin = Point(min(p1.x,p2.x),min(p1.y,p2.y),min(p1.z,p2.z));
pMax = Point(max(p1.x,p2.x),max(p1.y,p2.y),max(p1.z,p2.z));
}
Point boxCentroid() const {
float x = (pMin.x+pMax.x)/2;
float y = (pMin.y+pMax.y)/2;
float z = (pMin.z+pMax.z)/2;
return Point(x,y,z);
}
BBox Union(const BBox &b,const Point& p) {
BBox ret = b;
ret.pMin.x = min(b.pMin.x,p.x);
ret.pMin.y = min(b.pMin.y,p.y);
ret.pMin.z = min(b.pMin.z,p.z);
ret.pMax.x = max(b.pMax.x,p.x);
ret.pMax.y = max(b.pMax.y,p.y);
ret.pMax.z = max(b.pMax.z,p.z);
return ret;
}
friend BBox Union(const BBox& b,const BBox& b2){
BBox ret;
ret.pMin.x = min(b.pMin.x, b2.pMin.x);
ret.pMin.y = min(b.pMin.y, b2.pMin.y);
ret.pMin.z = min(b.pMin.z, b2.pMin.z);
ret.pMax.x = max(b.pMax.x, b2.pMax.x);
ret.pMax.y = max(b.pMax.y, b2.pMax.y);
ret.pMax.z = max(b.pMax.z, b2.pMax.z);
return ret;
}
bool Overlaps(const BBox &b) const {
bool x = (pMax.x >= b.pMin.x) && (pMin.x <= b.pMax.x);
bool y = (pMax.y >= b.pMin.y) && (pMin.y <= b.pMax.y);
bool z = (pMax.z >= b.pMin.z) && (pMin.z <= b.pMax.z);
return (x && y && z);
}
bool Inside(const Point& pt) const {
return (pt.x >= pMin.x && pt.x <= pMax.x &&
pt.y >= pMin.y && pt.y <= pMax.y &&
pt.z >= pMin.z && pt.z <= pMax.z);
}
void Expand(float delta) {
pMin -= Vector(delta,delta,delta);
pMax += Vector(delta,delta,delta);
}
float SurfaceArea() const {
Vector d = pMax - pMin;
return 2.f * (d.x*d.y + d.x*d.z + d.y*d.z);
}
float Volume() const {
Vector d = pMax - pMin;
return d.x*d.y*d.z;
}
int MaximumExtent() const {
Vector diag = pMax - pMin;
if (diag.x > diag.y && diag.x > diag.z)
return 0;
else if (diag.y > diag.z)
return 1;
else
return 2;
}
const Point &operator[](int i) const {
//Assert(i == 0 || i == 1);
return (&pMin)[i];
}
Point &operator[](int i) {
//Assert(i == 0 || i == 1);
return (&pMin)[i];
}
Point Lerp(float tx, float ty, float tz) const {
return Point(::Lerp(tx, pMin.x, pMax.x), ::Lerp(ty, pMin.y, pMax.y),
::Lerp(tz, pMin.z, pMax.z));
}
Vector Offset(const Point &p) const {
return Vector((p.x - pMin.x) / (pMax.x - pMin.x),
(p.y - pMin.y) / (pMax.y - pMin.y),
(p.z - pMin.z) / (pMax.z - pMin.z));
}
void BBox::BoundingSphere(Point *c, float *rad) const {
*c = pMin * 0.5f + pMax * 0.5f;
*rad = Inside(*c) ? Distance(*c, pMax) : 0.f;
}
bool IntersectP(const Ray &ray,float *hitt0,float *hitt1) const {
float t0 = 0.00001f, t1 = INFINITY;
for (int i = 0; i < 3; ++i) {
// Update interval for _i_th bounding box slab
float invRayDir = 1.f / ray.d[i];
float tNear = (pMin[i] - ray.o[i]) * invRayDir;
float tFar = (pMax[i] - ray.o[i]) * invRayDir;
// Update parametric interval from slab intersection $t$s
if (tNear > tFar) swap(tNear, tFar);
t0 = tNear > t0 ? tNear : t0;
t1 = tFar < t1 ? tFar : t1;
if (t0 > t1) return false;
}
if (hitt0) *hitt0 = t0;
if (hitt1) *hitt1 = t1;
return true;
}
};
If I use the current default BBox constructor with the above pMin and pMax values.I get this
But if I change it to
pMin = Point(-INFINITY,-INFINITY,-INFINITY);
pMax = Point(INFINITY,INFINITY,INFINITY);
I get the right model.This...
But it takes substantially longer.(7secs to 51 minutes) You see the issue ??? Anyways I need help.Any help is appreciated.Thanks
Here is the rest of the necessary code (KD-TREE) and (CAMERA)
*KD TREE CODE *
struct BoundEdge
{
//BoundEdge Methods
BoundEdge() { }
BoundEdge(float tt,int pn,bool starting){
t = tt;
primNum = pn;
type = starting ? START : END;
}
bool operator<(const BoundEdge &e) const {
if (t == e.t)
return (int)type < (int)e.type;
else return t < e.t;
}
float t;
int primNum;
enum { START,END } type;
};
struct KdAccelNode
{
void initLeaf(uint32_t *primNums,int np,MemoryArena &arena);
void initInterior(uint32_t axis,uint32_t ac,float s)
{
split = s;
flags = axis;
aboveChild |= (ac<<2);
}
float SplitPos() const { return split; }
uint32_t nPrimitives() const { return nPrims >> 2; }
uint32_t SplitAxis() const { return flags & 3; }
bool isLeaf() const { return (flags & 3)==3; }
uint32_t AboveChild() const { return aboveChild >> 2; }
union{
float split;
uint32_t onePrimitive;
uint32_t *primitives;
};
private:
union{
uint32_t flags;
uint32_t nPrims;
uint32_t aboveChild;
};
};
struct KdToDo{
const KdAccelNode *node;
float tMIN,tMAX;
};
class KdTreeAccel : public Primitive
{
public:
KdTreeAccel(const vector<Primitive*> &p,int icost,int tcost,float ebonus,int maxp,int md)
:primitives(p),isectCost(icost),traversalCost(tcost),emptyBonus(ebonus),maxPrims(maxp),maxDepth(md)
{
//Build Kd-Tree
nextFreeNode = nAllocedNodes = 0;
if(maxDepth <= 0)
maxDepth = Round2Int(8+1.3f * Log2Int(float(primitives.size())));
//<Compute Bounds>
vector<BBox> primBounds;
primBounds.reserve(primitives.size());
for(uint32_t i=0;i<primitives.size();++i)
{
BBox b = primitives[i]->BoxBound();
bounds = Union(bounds,b);
primBounds.push_back(b);
}
//<Allocate Working Memory>
BoundEdge *edges[3];
for(int i=0;i<3;++i)
edges[i] = new BoundEdge[2*primitives.size()];
uint32_t *prims0 = new uint32_t[primitives.size()];
uint32_t *prims1 = new uint32_t[(maxDepth+1) * primitives.size()];
//<Initialize primNums
uint32_t *primNums = new uint32_t[primitives.size()];
for(uint32_t i=0;i<primitives.size();++i)
primNums[i] = i;
//<Start Recursive Construction
buildTree(0,bounds,primBounds,primNums,primitives.size(),maxDepth,edges,prims0,prims1);
//<Free Memory
delete[] primNums;
for (int i = 0; i < 3; ++i)
delete[] edges[i];
delete[] prims0;
delete[] prims1;
}
virtual bool intersect(const Ray& r,float t_min,float t_max,primitive_record &rec) const;
virtual bool intersect_p(const Ray& r,float t_min,float t_max) const;
virtual float area() const;
virtual Vector _normal(const Point& in_point) const;
virtual Point randomSamplePoint() const;
virtual BBox BoxBound() const ;
virtual Point centroid() const ;
private:
void buildTree(int nodeNum,const BBox &nodeBounds,const vector<BBox> &allPrimBounds,uint32_t *primNums,
int nPrimitives,int depth,BoundEdge *edges[3],uint32_t *prims0,uint32_t *prims1,
int badRefines=0);
int isectCost,traversalCost,maxPrims,maxDepth;
float emptyBonus;
vector<Primitive*> primitives;
KdAccelNode *nodes;
int nAllocedNodes,nextFreeNode;
BBox bounds;
MemoryArena arena;
};
void KdAccelNode::initLeaf(uint32_t *primNums,int np,MemoryArena &arena)
{
flags = 3;
nPrims |= (np<<2);
//Store primitive id for leaf node
if(np == 0)
onePrimitive = 0;
else if(np == 1)
onePrimitive = primNums[0];
else{
primitives = arena.Alloc<uint32_t>(np);
for(int i=0;i<np;++i)
primitives[i] = primNums[i];
}
}
void KdTreeAccel::buildTree(int nodeNum,const BBox &nodeBounds,const vector<BBox> &allPrimBounds,uint32_t *primNums,
int nPrimitives,int depth,BoundEdge *edges[3],uint32_t *prims0,uint32_t *prims1,
int badRefines)
{
//Get Next Free Node
assert(nodeNum == nextFreeNode);
if(nextFreeNode == nAllocedNodes){
int nAlloc = max(2*nAllocedNodes,512);
KdAccelNode *n = AllocAligned<KdAccelNode>(nAlloc);
if(nAllocedNodes > 0){
memcpy(n,nodes,nAllocedNodes*sizeof(KdAccelNode));
FreeAligned(nodes);
}
nodes = n;
nAllocedNodes = nAlloc;
}
++nextFreeNode;
//Initialize leaf Node
if(nPrimitives <= maxPrims || depth == 0){
nodes[nodeNum].initLeaf(primNums,nPrimitives,arena);
return;
}
//Initialize Interior Node
//--Choose split axis
int bestAxis = -1, bestOffset = -1;
float bestCost = INFINITY;
float oldCost = isectCost * float(nPrimitives);
float totalSA = nodeBounds.SurfaceArea();
float invTotalSA = 1.f / totalSA;
Vector d = nodeBounds.pMax - nodeBounds.pMin;
uint32_t axis = nodeBounds.MaximumExtent();
int retries = 0;
retrySplit:
for (int i = 0; i < nPrimitives; ++i) {
int pn = primNums[i];
const BBox &bbox = allPrimBounds[pn];
edges[axis][2*i] = BoundEdge(bbox.pMin[axis], pn, true);
edges[axis][2*i+1] = BoundEdge(bbox.pMax[axis], pn, false);
}
sort(&edges[axis][0], &edges[axis][2*nPrimitives]);
int nBelow = 0, nAbove = nPrimitives;
for (int i = 0; i < 2*nPrimitives; ++i) {
if (edges[axis][i].type == BoundEdge::END) --nAbove;
float edget = edges[axis][i].t;
if (edget > nodeBounds.pMin[axis] &&
edget < nodeBounds.pMax[axis]) {
//Compute cost for split at ith edge
uint32_t otherAxis0 = (axis + 1) % 3, otherAxis1 = (axis + 2) % 3;
float belowSA = 2 * (d[otherAxis0] * d[otherAxis1] +
(edget - nodeBounds.pMin[axis]) *
(d[otherAxis0] + d[otherAxis1]));
float aboveSA = 2 * (d[otherAxis0] * d[otherAxis1] +
(nodeBounds.pMax[axis] - edget) *
(d[otherAxis0] + d[otherAxis1]));
float pBelow = belowSA * invTotalSA;
float pAbove = aboveSA * invTotalSA;
float eb = (nAbove == 0 || nBelow == 0) ? emptyBonus : 0.f;
float cost = traversalCost +
isectCost * (1.f - eb) * (pBelow * nBelow + pAbove * nAbove);
if (cost < bestCost) {
bestCost = cost;
bestAxis = axis;
bestOffset = i;
}
}
if (edges[axis][i].type == BoundEdge::START) ++nBelow;
}
assert(nBelow == nPrimitives && nAbove == 0);
//--Create leaf if np good splits found
if (bestAxis == -1 && retries < 2) {
++retries;
axis = (axis+1) % 3;
goto retrySplit;
}
if (bestCost > oldCost) ++badRefines;
if ((bestCost > 4.f * oldCost && nPrimitives < 16) ||
bestAxis == -1 || badRefines == 3) {
nodes[nodeNum].initLeaf(primNums, nPrimitives, arena);
return;
}
//--Classify primitives with respect to split
int n0 = 0, n1 = 0;
for (int i = 0; i < bestOffset; ++i)
if (edges[bestAxis][i].type == BoundEdge::START)
prims0[n0++] = edges[bestAxis][i].primNum;
for (int i = bestOffset+1; i < 2*nPrimitives; ++i)
if (edges[bestAxis][i].type == BoundEdge::END)
prims1[n1++] = edges[bestAxis][i].primNum;
//--Recursively initialize children nodes
float tsplit = edges[bestAxis][bestOffset].t;
BBox bounds0 = nodeBounds, bounds1 = nodeBounds;
bounds0.pMax[bestAxis] = bounds1.pMin[bestAxis] = tsplit;
buildTree(nodeNum+1, bounds0,
allPrimBounds, prims0, n0, depth-1, edges,
prims0, prims1 + nPrimitives, badRefines);
uint32_t aboveChild = nextFreeNode;
nodes[nodeNum].initInterior(bestAxis, aboveChild, tsplit);
buildTree(aboveChild, bounds1, allPrimBounds, prims1, n1,
depth-1, edges, prims0, prims1 + nPrimitives, badRefines);
}
bool KdTreeAccel::intersect(const Ray& r,float t_min,float t_max,primitive_record &rec) const {
//Compute initial Parametric range of ray inside kd-tree extent
float tMIN,tMAX;
if(!bounds.IntersectP(r,&tMIN,&tMAX))
return false;
//Prepare to traverse kd-tree for ray
Vector invDir(1.f/r.d.x,1.f/r.d.y,1.f/r.d.z);
#define MAX_TODO 64
KdToDo todo[MAX_TODO];
int todoPos = 0;
//Traverse kd-tree nodes in order for ray
bool hit = false;
const KdAccelNode *node = &nodes[0];
while (node != NULL) {
if(t_max < tMIN) break;
if(!node->isLeaf())
{
//Process kd-tree interior node
int axis = node->SplitAxis();
float tplane = (node->SplitPos() - r.o[axis]) * invDir[axis];
const KdAccelNode *firstChild, *secondChild;
int belowFirst = (r.o[axis] < node->SplitPos()) ||
(r.o[axis] == node->SplitPos() && r.d[axis] <= 0);
if (belowFirst) {
firstChild = node + 1;
secondChild = &nodes[node->AboveChild()];
}
else {
firstChild = &nodes[node->AboveChild()];
secondChild = node + 1;
}
if (tplane > tMAX || tplane <= 0)
node = firstChild;
else if (tplane < tMIN)
node = secondChild;
else {
todo[todoPos].node = secondChild;
todo[todoPos].tMIN = tplane;
todo[todoPos].tMAX = tMAX;
++todoPos;
node = firstChild;
tMAX = tplane;
}
}
else
{
//Check for intersections inside leaf node
uint32_t nPrimitives = node->nPrimitives();
if (nPrimitives == 1) {
primitive_record tempRec;
Primitive* prim = primitives[node->onePrimitive];
//Check one prim inside leaf node
if(prim->intersect(r,t_min,t_max,tempRec))
{
rec = tempRec;
hit = true;
}
}
else {
primitive_record tempRec;
float closest_so_far = t_max;
uint32_t *prims = node->primitives;
for (uint32_t i = 0; i < nPrimitives; ++i)
{
//Check one prim inside leaf node
if(primitives[prims[i]]->intersect(r,t_min,closest_so_far,tempRec))
{
hit = true;
closest_so_far = tempRec.t;
rec = tempRec;
}
}
}
//Grab next node to process from todo list
if (todoPos > 0) {
--todoPos;
node = todo[todoPos].node;
tMIN = todo[todoPos].tMIN;
tMAX = todo[todoPos].tMAX;
}
else
break;
}
}
return hit;
}
*CAMERA CODE *
Vector random_in_unit_disk() {
Vector p;
do{
p = 2.f*Vector(drand48(),drand48(),0)-Vector(1.f,1.f,0.f);
}while(Dot(p,p) >= 1.f);
return p;
}
class Camera {
public:
Vector lower_left_corner;
Vector horizontal;
Vector vertical;
Point origin;
Vector u,v,w;
float lens_radius; //Focus
float time0,time1;
Camera(Point lookfrom,Point lookat,Vector vup,
float vfov,float aspect,float aperture,float focus_dist,float t0,float t1){
time0 = t0;
time1 = t1;
lens_radius = aperture/2;
float theta = vfov*M_PI/180.f;
float half_height = tanf(theta/2.f);
float half_width = aspect*half_height;
origin = lookfrom;
w = Normalize(lookfrom - lookat);
u = Normalize(Cross(vup,w));
v = Cross(w,u);
lower_left_corner = toVector(origin) - half_width*focus_dist*u - half_height*focus_dist*v - focus_dist*w;
horizontal = 2*half_width*focus_dist*u;
vertical = 2*half_height*focus_dist*v;
}
Ray get_ray(float s,float t) {
Vector rd = lens_radius*random_in_unit_disk();
Vector offset = u * rd.x + v * rd.y;
float time = time0 + drand48()*(time1-time0);
return Ray(origin + offset,lower_left_corner + s*horizontal + t*vertical - toVector(origin) - offset,time);
}
};

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