I am trying to create a vertical carousel in processing with three ellipses.
I am able to get this done with two ellipses – that the carousel repeats itself over and over.
So far so good – it thought I could use the same logic for three but I am wrong. I started to think it works with more variables but wrong again… what am I missing in the logic? I really can not figure out how to set the values to make it seamless repeating itself…
Here is the example with two (this one is "seamless"):
float yspeed = 5;
float circleY;
int d = 720;
void setup() {
size(1080, 1620 );
circleY = 0;
}
void draw() {
background(255);
fill(0);
noStroke();
ellipse(width/2, circleY+height/2, d,d);
ellipse(width/2, circleY-height/2, d,d );
circleY = circleY + yspeed;
if (circleY > height) {
circleY=0;}
}
Here is my WIP with three … (BTW colors are only to see better):
float yspeed1 = 5;
float yspeed2 = 5;
float yspeed3 = 5;
float circleY1;
float circleY2;
float circleY3;
int d = 720;
void setup() {
size(1080, 1620);
circleY1 = 0;
circleY2 = 0;
circleY3 = 0;
}
void draw() {
background(255);
noStroke();
fill(255, 0, 0);
ellipse(width/2, circleY1, d, d);
circleY1= circleY1 + yspeed1;
if (circleY1 > height+d/2 ) {
circleY1=0;
}
fill(0, 255, 0);
ellipse(width/2, circleY2-810, d, d);
circleY2= circleY2 + yspeed2;
if (circleY2 > height+d/2 ) {
circleY2=0 ;
}
fill(0, 0, 255);
ellipse(width/2, circleY2-1620, d, d);
circleY3= circleY3 + yspeed3;
if (circleY3 > height+d/2 ) {
circleY3=0 ;
}
}
The one with three always starts at the intital point for all of them – but I thought that using individual variables would change it?
Thank you for any kind of help!
I found a solution myself! I used a trick – I did it with a loop and used four instead of three – three is in the end the only ones you see anyway!
float yspeed = 1;
float circleY;
int d = 360;
void setup() {
size(540, 810 );
circleY = 0;
}
void draw() {
background(255);
fill(0);
noStroke();
// fill(255,0,0);
translate(0, - height/2);
for (int i = 0; i< 5; i++) {
ellipse(width/2, circleY+height/2*i, d, d);
}
circleY = circleY + yspeed;
if (circleY > 405) {
circleY= 0;
}
}
Related
I'm very new to Processing and coding in general and trying to program a row of falling Domino bricks activated by an ellipse.
I have programmed a function for the bricks standing upright and one for the fallen bricks, but I can only get the bricks to fall all at the same time.
I'm looking for a way to make them fall one after the other. It would be great if someone could help me out.
This is my Code so far -
First tab:
Dom[] dominos = new Dom[20];
int m;
float x = 100;
void setup() {
size (600, 600);
for (int i=0; i < dominos.length; i++) {
dominos[i] = new Dom();
}
}
void draw() {
background(0);
if (m<91) {
m = m + 1;
}
fill(0);
ellipse(m, height/2 + 15, 20, 20);
fill(255, 80, 0);
ellipse (m, height/2 + 15, 20, 20);
for (int i=0; i < dominos.length; i++) {
if (m < 90)
dominos[1].show();
if (m >= 90)
dominos[i].fall();
}
}
Second tab:
class Dom {
float x = 100;
float y = height/2 - 22.5;
void fall() {
push();
stroke(255);
strokeWeight(10);
strokeCap(SQUARE);
for (int i = 0; i<15; i++) {
line (x + i*30 + 45, y+40, x + i *30, y+50);
}
pop();
}
void show() {
push();
stroke(255);
strokeWeight(10);
strokeCap(SQUARE);
for (int i = 0; i<15; i++) {
line (x + i*30, y, x + i *30, y+45);
}
pop();
}
}``
First of all, look what Your Dom.fall(), and Dom.show() is doing.
Each method draws 15 rectangles.
Next, look what Are You doing with dominos. It's an Array of 20 elements.
So, in draw() You are drawing 15 rectangles, 20 times with every frame refresh.
Basically You need an Array of 15 objects each drawing one rectangle. Or one object drawing 15 rectangles. But not 20 objects drawing 15 rectangles.
So, here is the simpler solution of Your problem:
Dom dominos;
int m;
void setup() {
size (600, 600);
dominos = new Dom();
}
void draw() {
background(0);
if (m<91) {
m++;
}
fill(255, 80, 0);
ellipse(m, height/2 + 15, 20, 20);
if (m>=90) {
dominos.fallenNumber++;
}
dominos.draw();
}
class Dom {
float x = 100;
float y = height/2 - 22.5;
int fallenNumber = 0;
void draw() {
push();
stroke(255);
strokeWeight(10);
strokeCap(SQUARE);
for (int i=0; i<15; i++) {
if (i<fallenNumber){
line (x + i*30 + 45, y+40, x + i *30, y+50);
} else {
line (x + i*30, y, x + i *30, y+45);
}
}
pop();
}
}
Can anyone help me?
So, I'm supposed to have a ball that is moving horizontally, such that every time I press the mouse, a ball would get shoot vertically, then slows down due to friction. The vertical ball would stay in the old position but the player would reset.
How do I go about doing that without using classes?
Here my code so far:
boolean circleupdatetostop = true;
float x = 100;
float yshot = 880;
float speedshot = random(4,10);
float speedx = 6;
void setup() {
size(1280,960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(x,880,80);
if (x > width || x < 0 ) {
speedx = speedx * -1;
}
if (circleupdatetostop) {
x = x + speedx;
}
if (circleupdatetostop == false) {
float locationx = x;
stroke(0);
fill(255,0,255);
circle(locationx,yshot,30);
yshot = yshot - speedshot;
}
}
void mousePressed () {
circleupdatetostop = !circleupdatetostop;
}
I'm not entirely sure if this is what you meant, but you could achieve shooting multiple balls by using ArrayList as well as processing's PVector to better handle the x and y coordinate pairs. If you wanted to look at classes, see this post.
import java.util.*;
// Whether the ball is moving or not
boolean circleupdatetostop = true;
// Information about the main_ball
PVector position = new PVector(100, 880);
PVector speed = new PVector(6, 0);
float diameter = 80;
// Information about the sot balls
ArrayList<PVector> balls_loc = new ArrayList<PVector>();
ArrayList<PVector> balls_speed = new ArrayList<PVector>();
float diameter_shot = 30;
float friction = 0.994;
void setup() {
size(1280, 960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(position.x, position.y, diameter);
// Remember to consider the radius of the ball when bouncing off the edges
if (position.x + diameter/2 > width || position.x - diameter/2 < 0 ) {
speed.mult(-1);
}
if (circleupdatetostop) {
position.add(speed);
}
// Cycle through the list updating their speed and draw each ball
for (int i = 0; i<balls_loc.size(); i++) {
balls_speed.get(i).mult(friction+random(-0.05, 0.05));
balls_loc.get(i).add(balls_speed.get(i));
stroke(0);
fill(255, 0, 255);
circle(balls_loc.get(i).x, balls_loc.get(i).y, diameter_shot);
}
}
void mousePressed(){
// Add a new ball to be drawn
if(circleupdatetostop){
balls_loc.add(new PVector(position.x, position.y));
balls_speed.add(new PVector(0, random(-4, -10)));
}
circleupdatetostop = !circleupdatetostop;
}
I need to create a loop which will space circles equally around a circle in Processing.
I know I can somehow implement a FOR loop.
I need to be able to increase or decrease the number of circles around this circle (with button presses) but keep them equally spaced.
I know the formula's I need to include in the FOR loop to get the X and Y axis. The formulas:
being
X = R*cos(angle-90)+Y0
Y = R*sin(angle-90)+X0
I understand the three parameters of the FOR loop; when does it start, when does it finish, what changes when it runs.
What I can't see is how to implement the formulas into the FOR loop.
Many thanks
Here is the code I do have
void setup () {
size (600, 600);
background (255, 255, 255);
smooth ();
ellipse (width/2, height/2, 200, 200); // the guide circle. Not needed in final code.
}
void draw() {
for (int i = 0; i < 20; i ++) {
for (int j = 0; j < 20; j ++) {
ellipse (i *20, j * 20, 20, 20);
}
}
}
This code should do the trick:
float incrementalAngle = 0.0;
void setup(){
size(600, 600);
smooth();
background(0);
ellipse(width/2, height/2, 200, 200);
drawCircles(20, 200);
}
void draw(){
}
void drawCircles(int circlesNumber, int bigCircleNumber){
float angle = incrementalAngle;
for(int i = 0; i < circlesNumber; i++){
ellipse(bigCircleNumber * cos(incrementalAngle) + height/2,
bigCircleNumber * sin(incrementalAngle) + width/2,
circlesNumber, circlesNumber);
incrementalAngle += TWO_PI / circlesNumber;
}
}
So the second loop wasn't needed, and the formula you were trying to introduce would go in the X and Y position of your ellipse, there by playing whit the angle and the cos and sin you can get the result you were looking for.
What's left now is for you to get the number of circles you want by the clicking inside a mousePressed() method and drawing that amount.
Hope this comes useful and call me if you need more help
Regards
Jose.
Thank you to everyone who helped.
I managed to do it (slightly differently to you #Jose Gonzalez
int nbr_circles = 2;
void setup() {
size(600, 600);
smooth();
background(255);
}
void draw() {
background(255);
float cx = width/2.0;
float cy = height/2.0;
fill(0);
//float x, y; //
for (int i = 0; i < nbr_circles; i++)
{
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
}
void mousePressed() {
if (mouseButton == LEFT) {
if (nbr_circles < 20)
nbr_circles = nbr_circles + 1;
} else if (mouseButton == RIGHT) {
if (nbr_circles > 2)
nbr_circles = nbr_circles - 1;
}
}
I'm new to Processing and want to make the following sketch move images down, rather than up. I have tried adjusting the y to y+= speed in void move(), which does this but the images don't reload, they just do one cycle and the screen goes blank.
Your help would be appreciated :-)
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
sp[i] = new Spot(random(width), random(height), random(0.2,1.0), random(0.1,1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
y -= speed;
if (y < - myImage.width*diameter/2) {
x = random(width);
y = height + myImage.width*diameter/2;
speed = random(0.5,3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
The logical is kind of inverted already,but just invert it again :)
here there are comments in the code:
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
// a little change where spots are created...
sp[i] = new Spot(random(width), random(-myImage.height, height - 100), random(0.2, 1.0), random(0.1, 1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
// invert movement direction
y += speed;
// also invert the test...
if (y > height + myImage.width*diameter/2) {
x = random(width);
y = height + myImage.width*diameter/2;
speed = random(0.5, 3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
A friend helped me out, this is the solution to my problem :-)
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
// a little change where spots are created...
sp[i] = new Spot(random(width), random(-myImage.height, height - 100), random(0.2, 1.0), random(0.1, 1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
y += speed;
// change y = 0 - ...
if (y > height + myImage.width*diameter/2) {
x = random(width);
y = 0 - myImage.width*diameter/2;
speed = random(0.5, 3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
I am trying to create a visualization where the nodes of my network change size in a loop as the visualization progresses (I have stripped out the interactions between the nodes for simplicity here). I have the array sizes that is looped over in the draw function with index j. I am not sure why the nodes are not changing size. Any insight into this problem would be appreciated.
int numBalls = 5;
Ball[] balls = new Ball[numBalls];
float[] sizes = {15,25,35,45,55,65};
void setup() {
size(800, 400);
int l = 0 ;
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width),random(height), random(30, 50), i, balls);
}
noStroke();
fill(255, 204);
}
void draw() {
background(0);
for (int j = 0; j < 6; j++){
for (int i = 0; i < numBalls; i++) {
print("\nNEW ID\n");
print(i);
print("\n");
print("Diameter in balls\n");
print(balls[i].diameter);
print("\n");
balls[i].diameter = sizes[j];
print("Diameter in balls after fix\n");
print(balls[i].diameter);
balls[i].display();
}
}
}
class Ball {
float x, y;
float diameter;
float mass;
float vx = 0;
float vy = 0;
int id;
Ball[] others;
Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
diameter = din;
mass = 50;
id = idin;
others = oin;
}
void display() {
textSize(32);
fill(0,255,0,255);
print("\nDiameter in display\n");
print(diameter);
print("\n");
ellipse(x, y, diameter, diameter);
print("\nDiameter in display\n");
print(diameter);
print("\n");
fill(255, 0, 0, 255);
text(id,x,y);
}
}
The thing is, in your draw() function you are running over the array of sizes with the first for-loop and assigning the value of that size to the balls. This way in each draw() you subsequently attach each size on each ball, and every time the size you attach overwrites the previous one... Remember, the window of Processing only refreshes after the draw() has finished! Instead of looping over all the sizes in each draw() you probably want a different size in each draw(). So a way to do that would be:
int numBalls = 5;
int sizeCounter = 0;
int everySoManyFramesChange = 3;
Ball[] balls = new Ball[numBalls];
float[] sizes = {
15, 25, 35, 45, 55, 65
};
void setup() {
size(800, 400);
int l = 0 ;
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height), random(30, 50), i, balls);
}
noStroke();
fill(255, 204);
}
void draw() {
background(0);
for (int i = 0; i < numBalls; i++) {
balls[i].diameter = sizes[sizeCounter];
balls[i].display();
}
if (frameCount%everySoManyFramesChange == 0) sizeCounter=(sizeCounter+1)%sizes.length;
}
class Ball {
float x, y;
float diameter;
float mass;
float vx = 0;
float vy = 0;
int id;
Ball[] others;
Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
diameter = din;
mass = 50;
id = idin;
others = oin;
}
void display() {
textSize(32);
fill(0, 255, 0, 255);
ellipse(x, y, diameter, diameter);
fill(255, 0, 0, 255);
text(id, x, y);
}
}
By the way I removed all those print statements because they are making the sketch horribly slow, but be my guest and re-introduce them!