Array index out of bounds exception: 100 - processing

//----------------------------------------------\\
float x = 300;
float y = 300;
float direction = 0;
float increment = 1;
float speed = 5;
boolean toggle = true; // - For spaceship reversal
float wormX = random(0, 600); // - For wormHole v
float wormY = random(0, 600);
float wormGrowth = 0;
boolean growthSwitch = true; // - for wormHole ^
float[] starXpos = new float[100]; //starsRandom
float[] starYpos = new float[100]; //starsRandom
float d = dist(x, y, wormX, wormY);
int score = 0;
//----------------------------------------------\\
//----------------------------------------------\\ Setup
void setup (){
size (600, 600);
starsP1();
}
//----------------------------------------------\\ Draw
void draw (){
background (0);
spaceShip();
starsP2();
wormHole ();
score();
warpInitial();
blackHoleAt(100, 40);
blackHoleAt(400, 500);
}
//----------------------------------------------\\
//----------------------------------------------\\ starsRandom
void starsP1(){
int i = 0;
while (i < 100){
starXpos[i] = random(0, width);
starYpos[i] = random(0, height);
i = i + 1;
}
}
void starsP2(){
stroke(255);
strokeWeight(5);
int i = 0;
while (i < 100){
point(starXpos[i], starYpos[i]);
i = i + 1;
}
if (key == 'w'){
starYpos[i] = starYpos[i] + 1;
}
}
I'm trying to create a form of parallax for the stars in my code. When the user presses w,a,s,d the array of stars should correspond to the direction. I don't understand how this should work as I keep getting this error.

Try formatting your code to better see what's going on:
void starsP2(){
stroke(255);
strokeWeight(5);
int i = 0;
while (i < 100){
point(starXpos[i], starYpos[i]);
i = i + 1;
}
if (key == 'w'){
starYpos[i] = starYpos[i] + 1;
}
}
Your while loop executes until i == 100. Then after the while loop exits, you use that i variable again. Since i is 100, and your starYpos array only has up to index 99, you get an error.
The fix is to either move that if statement to inside the while loop, or to refactor your code so i doesn't go outside the bounds of the array.

Related

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

Automation of selection in Processing

I am currently using a processing sketch to work through a large number of images I have in a folder. I have set an onClick command to advance to the next image in the string. It is quite time consuming and I would like to automate the action that once the sketch is completed the sketch would repeat it's self selecting the next image from the string. The onClick command also save the image the export folder but each time saves with the same file name, I've tried to set up sequential numbering but it hasn't worked so far. Any help would be greatly appreciated.
String[] imgNames = {"1.jpg", "2.jpg", "3.jpg"};
PImage img;
int imgIndex = 0;
void nextImage() {
background(255);
frameRate(10000);
loop();
frameCount = 0;
img = loadImage(imgNames[imgIndex]);
img.loadPixels();
imgIndex += 1;
if (imgIndex >= imgNames.length) {
imgIndex = 0;
}
}
void paintStroke(float strokeLength, color strokeColor, int strokeThickness) {
float stepLength = strokeLength/4.0;
// Determines if the stroke is curved. A straight line is 0.
float tangent1 = 0;
float tangent2 = 0;
float odds = random(1.0);
if (odds < 0.7) {
tangent1 = random(-strokeLength, strokeLength);
tangent2 = random(-strokeLength, strokeLength);
}
// Draw a big stroke
noFill();
stroke(strokeColor);
strokeWeight(strokeThickness);
curve(tangent1, -stepLength*2, 0, -stepLength, 0, stepLength, tangent2, stepLength*2);
int z = 1;
// Draw stroke's details
for (int num = strokeThickness; num > 0; num --) {
float offset = random(-50, 25);
color newColor = color(red(strokeColor)+offset, green(strokeColor)+offset, blue(strokeColor)+offset, random(100, 255));
stroke(newColor);
strokeWeight((int)random(0, 3));
curve(tangent1, -stepLength*2, z-strokeThickness/2, -stepLength*random(0.9, 1.1), z-strokeThickness/2, stepLength*random(0.9, 1.1), tangent2, stepLength*2);
z += 1;
}
}
void setup() {
size(1600, 700);
nextImage();
}
void draw() {
translate(width/2, height/2);
int index = 0;
for (int y = 0; y < img.height; y+=1) {
for (int x = 0; x < img.width; x+=1) {
int odds = (int)random(20000);
if (odds < 1) {
color pixelColor = img.pixels[index];
pixelColor = color(red(pixelColor), green(pixelColor), blue(pixelColor), 100);
pushMatrix();
translate(x-img.width/2, y-img.height/2);
rotate(radians(random(-90, 90)));
// Paint by layers from rough strokes to finer details
if (frameCount < 20) {
// Big rough strokes
paintStroke(random(150, 250), pixelColor, (int)random(20, 40));
} else if (frameCount < 1000) {
// Thick strokes
paintStroke(random(75, 125), pixelColor, (int)random(8, 12));
} else if (frameCount < 1500) {
// Small strokes
paintStroke(random(20, 30), pixelColor, (int)random(1, 4));
} else if (frameCount < 10000) {
// Big dots
paintStroke(random(5, 10), pixelColor, (int)random(5, 8));
} else if (frameCount < 10000) {
// Small dots
paintStroke(random(1, 2), pixelColor, (int)random(1, 3));
}
popMatrix();
}
index += 1;
}
}
if (frameCount > 10000) {
noLoop();
}
// if(key == 's'){
// println("Saving...");
// saveFrame("screen-####.jpg");
// println("Done saving.");
// }
}
void mousePressed() {
save("001.tif");
nextImage();
}
Can't you just call the nextImage() function from inside this if statement?
if (frameCount > 10000) {
noLoop();
}
Would be:
if (frameCount > 10000) {
nextImage();
}
As for using different filenames, just use an int that you increment whenever you save the file, and use that value in the save() function. Or you could use the frameCount variable:
save("img" + frameCount + ".tif");
If you have follow-up questions, please post a MCVE instead of your whole project. Try to isolate one problem at a time in a small example program that only does that one thing. Good luck.

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++) {

Save image with Processing

I'm trying to save an image after certain time, the problem is that the image size is bigger than the display so when I use the save or saveFrame function it only saves the image that I can see in the display. There is any other way to save the whole image?
This is my code:
PImage picture, pictureFilter, img;
int total, cont, current;
ArrayList<ArrayList<Position>> columns;
String[] fontList;
public class Position {
public int x;
public int y;
}
void setup() {
fontList = PFont.list();
picture = loadImage("DSC05920b.JPG");
pictureFilter = loadImage("filtrePort2.jpg");
frame.setResizable(true);
size(picture.width, picture.height);
columns = new ArrayList<ArrayList<Position>>();
for(int i = 0; i < picture.width; i++) {
ArrayList<Position> row = new ArrayList<Position>();
for(int j = 0; j < picture.height; j++){
Position p = new Position();
p.x = i;
p.y = j;
row.add(p);
}
columns.add(row);
}
total = picture.width * picture.height;
cont = total;
current = 0;
img = createImage(picture.width, picture.height, RGB);
}
float randomLetter() {
float value = 23;
boolean found = false;
while(!found) {
value = random(48, 122);
if(value >48 && value <58) found = true;
if(value >65 && value <91) found = true;
if(value >97 && value <123) found = true;
}
return value;
}
void draw() {
int x = int(random(0, columns.size()));
ArrayList<Position> rows = columns.get(x);
int y = int(random(0, rows.size()));
Position p = rows.get(y);
color c = pictureFilter.get(p.x, p.y);
int r = (c >> 16) & 0xFF; // Faster way of getting red(argb)
if(r < 240) {
PFont f = createFont(fontList[int(random(0,fontList.length))],random(5, 24),true);
textFont(f);
fill(picture.get(p.x,p.y));
char letter = (char) int(randomLetter());
text(letter, p.x, p.y);
}
if(rows.size() == 1) {
if(columns.size() == 1) {
saveFrame("lol.jpg");
columns.remove(x);
} else {
columns.remove(x);
}
} else {
println(rows.size());
rows.remove(y);
}
--cont;
float percent = float(total-cont)/float(total)*100;
if(int(percent) != current) {
current = int(percent);
save("image_" + current + ".jpg");
}
println("DONE: " + (total-cont) + "/" + total + " Progress: " + percent + "%");
}
The code do a lot of stuff but the part that its not working well is at the final when I check if the percentage have been increased in order to save the image
You can write this into a PGraphics context - aka a graphics buffer.
The buffer can be as big as you need it to be, and you can choose whether to draw it on the screen or not..
// Create the buffer at the size you need, and choose the renderer
PGraphics pg = createGraphics(myImage.width, myImage.height, P2D);
// Wrap all your drawing functions in the pg context - e.g.
PFont f = createFont(fontList[int(random(0,fontList.length))],random(5, 24),true);
textFont(f);
pg.beginDraw();
pg.fill(picture.get(p.x,p.y));
char letter = (char) int(randomLetter());
pg.text(letter, p.x, p.y);
pg.endDraw();
// Draw your PG to the screen and resize the representation of it to the screen bounds
image(pg, 0, 0, width, height); // <-- this wont actually clip/resize the image
// Save it
pg.save("image_" + current + ".jpg");
The PImage class contains a save() function that exports to file. The API should be your first stop for questions like this.

Resources