Stop background from refreshing? - processing

I am trying to get my gif to do something similar to this gif.
I have been able to get the line to draw, and the 'planets' to orbit, but can't figure out how to keep the line connecting the two circles, like the gif does.
Here's the basic code:
int x = 500;
int y = 500;
int radius = y/2;
int cX = x/2;
int cY = y/2;
String text1;
int lg_xBall;
int lg_yBall;
int sm_xBall;
int sm_yBall;
void setup() {
size(x, y);
smooth();
colorMode(RGB);
}
void draw() {
background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
void drawCircle() { // This will draw a simple circle
stroke(1);
// x1=a+r*cos t, y1=b+r*sin t
ellipse(x/2, y/2, x/2, y/2);
}
void drawLines() { // This will draw lines from the center of the circle.
stroke(1);
line(x/2, y/2, radius/2, radius); // line from 6 to center
line(x/2, y/2, x/2, y/4); // line from 12 to center
for (int i = 0; i <= 5; i+=2.5) {
float x1 = x/2+radius/2*cos(i);
float y1 = y/2+radius/2*sin(i);
line(x/2, y/2, x1, y1);
}
}
void moveSmBall(float ky) { // This will create, and move, a small 'planet'
pushStyle();
stroke(100);
sm_xBall = (int)(cX+radius*cos(ky));
sm_yBall = (int)(cY+radius*sin(ky));
fill(190, 0, 0);
// background(0);
ellipse(sm_xBall, sm_yBall, 10, 10);
popStyle();
}
void drawSmBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, cX+radius, cY+radius);
popStyle();
}
void moveLgBall(float kx) {
kx = kx/.7;
pushStyle();
lg_xBall = (int)(cX+radius*cos(kx)*.6);
lg_yBall = (int)(cY+radius*sin(kx)*.6);
fill(0, 0, 230);
ellipse(lg_xBall, lg_yBall, 30, 30);
popStyle();
}
void drawLgBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, (cX+radius)*.6, (cY+radius)*.6);
popStyle();
}
void sun() {
pushStyle();
fill(250, 250, 0);
ellipse(cX, cY, 40, 40);
popStyle();
}
void connectingLines() {
line(sm_xBall, sm_yBall, lg_xBall, lg_yBall);
}
void showMouse() {
text("X: " + mouseX, x/2, y/2-30);
text("Y: " + mouseY, x/2, y/2-50);
}
Thanks for any help/advice!

The problem is that you're calling background() during every frame, which will clear away anything you've already drawn.
So you either need to stop calling background(), or you need to redraw the old lines every frame.
If you simply move the call to background() out of your draw() function and into your setup() function, you're about 50% there already:
void setup() {
size(x, y);
smooth();
colorMode(RGB);
background(0);
}
void draw() {
// background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
However, the original animation does not show the previous positions of the ellipses. So you need to clear away the previous frame by calling the background() function, and then redraw previous line positions. You'd do that by having an ArrayList that holds those previous positions.
Here's a simple example that uses an ArrayList to redraw anywhere the mouse has been:
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
}
void draw() {
background(0);
stroke(255);
points.add(new PVector(mouseX, mouseY));
for(PVector p : points){
ellipse(p.x, p.y, 10, 10);
}
}
You would need to do something very similar, but you'd have to keep track of two points at a time instead of one, since you're tracking two ellipses and not just the mouse position.

Related

How to draw a circle and then when keyPressed, draw another circle etc

I am learning how to code in Processing 4.
I am trying to make a code where when keyPressed() is clicked, one circle is drawn then when the button is pressed again, the first circle remains and then a second circle is drawn but with extent increased by 10, then the key pressed for a final time (3) and the third circle is drawn with the extent increased by 3 then it stops producing more circles.
This is the code I have so far but I am confused on how to approach it. Right now, the first circle just increases in size and it doesn't draw a second one. How do I draw 3 circles, one once keyPressed()?
int sizeIncrease = 10;
int initialSize = 70;
void setup() {
size(500, 500);
}
void draw() {
background(0);
stroke(255,0,0);
strokeWeight(25);
fill(255);
pushMatrix();
translate(20, 50);
circle(width/2, height/2, initialSize);
popMatrix();
}
void keyPressed() {
initialSize += sizeIncrease;
}
Add a variable count. Increment the variable when a key is pressed and draw the circles in a for-loop:
int sizeIncrease = 10;
int initialSize = 70;
int count = 1;
void setup() {
size(500, 500);
}
void draw() {
background(0);
noFill();
stroke(255);
pushMatrix();
translate(20, 50);
for (int i = 0; i < count; i++) {
circle(width/2, height/2, initialSize + i*sizeIncrease);
}
popMatrix();
}
void keyPressed() {
count ++;
}
int sizeIncrease = 10;
int initialSize = 70;
int count = 1;
void setup() {
size(500, 500);
}
void draw() {
background(0);
noFill();
stroke(255);
pushMatrix();
translate(20, 50);
for (int i = 0; i < count; i++)
{
circle(width/2, height/2, initialSize + i*sizeIncrease);
**if(i == 1)
{
sizeIncrease = 3;
}**
}
popMatrix();
}
void keyPressed() {
count ++;
}

I am trying to make an abstract kind of object i guess, referencing the book processing creative coding examples

Here is the code, i can get screenshots of everything if need be, but Im just getting one error - "syntax error you might be mixing active and static modes."
Im fairly new to this so any help would be great.
float boxSize = 40;
float margin = boxSize*2;
float depth = 400;
color boxFill;
void setup(){
size(500,500,P3D);
}
void draw(){
translate(width/2, height/2, -depth/2);
rotateY(frameCount*PI/60);
rotateX(frameCount*PI/60);
}
for (float i=-depth/2+margin; i<=depth/2-margin; i+=boxSize){
pushMatrix();
for (float j=-height/2+margin; j<=height/2-margin; j+=boxSize){
pushMatrix();
for (float k=-width/2+margin; k<=width/2-margin; k+=boxSize){
boxFill = color(abs(i), abs(j), abs(k), 50);
pushMatrix();
translate(k, j, i);
fill(boxFill);
box(boxSize, boxSize, boxSize);
popMatrix();
}
popMatrix();
}
popMatrix();
}
}
I recommend formatting your code first: Processing > Edit > Auto Format (CMD+T / Ctrl+T)
This will reveal this error right after the rotateX() call:
Missing left curly bracket "{"
What it actually means is that you have an extra } and it shouldn't be (as the for loop after should be part of the draw() function:
float boxSize = 40;
float margin = boxSize*2;
float depth = 400;
color boxFill;
void setup() {
size(500, 500, P3D);
}
void draw() {
translate(width/2, height/2, -depth/2);
rotateY(frameCount*PI/60);
rotateX(frameCount*PI/60);
for (float i=-depth/2+margin; i<=depth/2-margin; i+=boxSize) {
pushMatrix();
for (float j=-height/2+margin; j<=height/2-margin; j+=boxSize) {
pushMatrix();
for (float k=-width/2+margin; k<=width/2-margin; k+=boxSize) {
boxFill = color(abs(i), abs(j), abs(k), 50);
pushMatrix();
translate(k, j, i);
fill(boxFill);
box(boxSize, boxSize, boxSize);
popMatrix();
}
popMatrix();
}
popMatrix();
}
}

How to execute a function only once in voice draw(); but still have it displayed for the whole animation

I'm struggling with something here.
Basically I made an animation with several functions. I want the functions to be animated, except for one that I want to be still.
If I specify noLoop, then nothing gets animated, if I tell the function to run a set number of times, then after that number it stops being displayed. What I want is to have it run once but then be still displayed.
Do you guys have any idea of how I could do that ?
Here is the code :
int r1,r2,r3 = 0;
int i1, i2,i3;
void setup(){
size(800,800);
background(255,0);
//noLoop();
}
void draw(){
background(255,0);
rosace();
croix();
sillon1();
sillon2();
}
void rosace(){
for (i1 = 0;i1<230; i1++){
rectMode(CENTER);
noFill();
stroke(20);
strokeWeight(1);
pushMatrix();
translate(width/2,height/2);
translate(400,400);
rotate(radians(r1));
rect(0,0,400,400);
r1 +=1;
//println(r);
popMatrix();
println("rosace ex");
}
}
void croix(){
pushMatrix();
strokeWeight(2);
stroke(0);
translate(width/2, height/2);
rotate(radians(45));
line(-10,0,10,0);
line(0,-10,0,10);
popMatrix();
}
void sillon1(){
for (i2 =0; i2<360; i2++){
pushMatrix();
translate(width/2,height/2);
strokeWeight(int(random(0,7)));
rotate(radians(r2));
point(-330,0);
popMatrix();
r2 +=1;
}
}
void sillon2(){
for (i2 =0; i2<2000; i2++){
pushMatrix();
translate(width/2,height/2);
strokeWeight(int(random(1,3)));
rotate(radians(r2));
point(-360,0+(random(-2,2)));
popMatrix();
r2 +=1;
}
}
The void rosace(); is the one that I'd like to be non-animated.
The problem is that you're storing r1 as a global variable. This means that it keeps it's value after every iteration.
Instead, make it a local variable:
void rosace() {
int r1 = 0;
for (i1 = 0; i1<230; i1++) {
rectMode(CENTER);
noFill();
stroke(20);
strokeWeight(1);
pushMatrix();
translate(width/2, height/2);
translate(400, 400);
rotate(radians(r1));
rect(0, 0, 400, 400);
r1 +=1;
popMatrix();
println("rosace ex");
}
}
You can't just keep a part of the scene, when animations are drawn on top of it. You have to draw the entire scene in every frame. Ensure that rosace draws the same in every frame.
Just set r1 = 0 in every frame, then the algorithm in rosace generates the same rectangles in every frame:
void rosace(){
r1 = 0;
for (i1 = 0;i1<230; i1++){
// [...]
}
}

How can I make this rectangle slow down?

The rectangle is moving and when I click it needs to be moving at 0.1 instead of 3. I don't know how to code the mousePressed part so that it stays at 0.1 the whole time.
float stripeX = 0;
void setup() {
size(500, 300);
}
void draw() {
background(255);
fill(10, 10, 100);
rect(stripeX, 90, 150, 250);
stripeX = stripeX + 3;
stripeX = stripeX % width;
}
void mousePressed() {
stripeX = stripeX - 2.9;
}
You could just use the mousePressed variable along with an if statement inside the draw() function:
float stripeX = 0;
void setup() {
size(500, 300);
}
void draw() {
background(255);
fill(10, 10, 100);
rect(stripeX, 90, 150, 250);
if(mousePressed){
stripeX = stripeX + .1;
}
else{
stripeX = stripeX + 3;
}
stripeX = stripeX % width;
}
The best way in Your case is to use mouseReleased() method:
float stripeX, deltaX;
void setup() {
size(500, 300);
stripeX = 0f; // init values here, in setup()
deltaX = 3f;
}
void draw() {
background(255);
fill(10, 10, 100);
rect(stripeX, 90, 150, 250);
stripeX += deltaX;
stripeX = stripeX % width;
}
void mousePressed(){
deltaX = 0.1;
}
void mouseReleased(){
deltaX = 3f;
}
This is all a bit dicey. How often is draw() called? On every frame? Generally it's a bad idea to adjust things in a draw function, it should just draw.
To hack it somewhat
float stripeX = 0;
float deltaX = 3.0;
void draw()
{
//omitted some code
stripeX += deltaX;
}
void mousePressed()
{
if(deltaX > 0.1)
deltaX = 0.1;
else
deltaX = 3.0; // let a second press put it back to 3.0
}
However you probably want to put it back to 3.0 on mouse up. You haven't
given enough information to know how to intercept that event.

Setting (0,0) to bottom-left without switching X- and Y-axis in Processing(.org)

I'd like to change the coordinate system in a 2d processing sketch, putting (0,0) in the bottom-left rather than the top-left. The following code will move (0,0) to the bottom-left:
transform(0, height);
rotate(radians(-90));
However, it also makes the X-axis the vertical axis. Is there a simple way to move (0,0) to the bottom-left and keep the X-axis horizontal?
One option I've considered is using P3D with a combination of rotate and rotateY, but would prefer a solution for the 2d case.
Thanks for any help!
You could simply translate without rotating:
transform(0, height);
And handle your coordinates as flipped:
boolean useVFlip = true;
void setup(){
size(400,400);
}
void draw(){
background(255);
if(useVFlip) translate(0,height);
drawAxes(100);
translate(width * .5, useVFlip ? (height-mouseY)*-1 : mouseY);
triangle(0,0,100,0,100,100);
}
void keyPressed(){ useVFlip = !useVFlip; }
void drawAxes(int size){
pushStyle();
strokeWeight(10);
stroke(192,0,0);
line(0,0,size,0);
stroke(0,192,0);
line(0,0,0,size);
popStyle();
}
If it makes it easier to get flipped coordinates, you could flip the whole coordinate system using the scale() method:
boolean useVFlip = true;
void setup(){
size(400,400);
}
void draw(){
background(255);
if(useVFlip){
scale(1,-1);
translate(0,-height);
}
drawAxes(100);
translate(width * .5, useVFlip ? height-mouseY : mouseY);
triangle(0,0,100,0,100,100);
}
void keyPressed(){ useVFlip = !useVFlip; }
void drawAxes(int size){
pushStyle();
strokeWeight(10);
stroke(192,0,0);
line(0,0,size,0);
stroke(0,192,0);
line(0,0,0,size);
popStyle();
}
You could do the same with a PMatrix2D, but not sure how familiar your are with them:
boolean useCustomCS = true;
PMatrix2D customCS;
void setup(){
size(400,400);
customCS = new PMatrix2D( 1, 0, 0,
0, -1,height);
fill(0);
}
void draw(){
background(255);
if(useCustomCS) applyMatrix(customCS);
drawAxes(100);
translate(width * .5, useCustomCS ? height-mouseY : mouseY);
text("real Y:" + mouseY + " flipped Y: " + (height-mouseY),0,0);
triangle(0,0,100,0,100,100);
}
void keyPressed(){ useCustomCS = !useCustomCS; }
void drawAxes(int size){
pushStyle();
strokeWeight(10);
stroke(192,0,0);
line(0,0,size,0);
stroke(0,192,0);
line(0,0,0,size);
popStyle();
}
Try the following:
translate(0,height);
scale(1,-1);

Resources