I need to figure out how to properly use variables/instance variables? - processing

float x = 100;
float y = 100;
float p = 150;
float l = 10;
int r = 150;
int t = 100;
int s = 100;
int w = 60;
int h = 60;
int z = 11;
int eyeSize = 10;
int pigNose = 30;
int pigBody = 30;
int pigEars = 35;
int pigTail = 20;
int speed = 1;
void setup () {
size (600, 600);
}
void draw () {
background(255);
//Draw legs
fill(255);
rect(x+(2*w), y+h/3.5, z, 2*z);
rect(x+(w), y+h/3, z, 2*z);
rect(x+(1.5*w), y+h/3, z, 2*z);
rect(x+(2.5*w), y+h/3.5, z, 2*z);
////draw body
fill(255);
ellipse(2.1*x,y-pigBody, p, p-(2*l));
//draw tail
fill(0);
line(2.85*x, y-pigTail, (6+l)*pigTail, pigTail*3);
// Draw payer's head
fill(255);
ellipse(x,y-pigNose,t,t);
// Draw player's eyes
fill(0);
ellipse(x-w/3+1,y-h/2,eyeSize,eyeSize);
ellipse(x+w/3-1,y-h/2,eyeSize,eyeSize);
//Draw nose
fill(0);
ellipse(x, y, pigNose, pigNose);
//draw ears
fill(0);
ellipse(x-(w/2),y-h, pigEars, pigEars);
fill(0);
ellipse(x+(w/2),y-h, pigEars, pigEars);
}
void mousePressed(){
x = mouseX;
y = mouseY;
}
I'm not that great at using variables instead of magic numbers and I'm wondering why when I click somewhere on the screen the pig splits apart? I'm also supposed to be using instance variables but I'm not sure how. Can anyone help? This is for Processing.

You've got the right idea by using x and y variables and basing all your shapes off those variables. But you got one thing wrong: you're multiplying those variables by different values to get the positions of your shapes, when you should really be adding to those variables to get the positions of your shapes.
Think about it this way, using a simpler example:
size(200, 100);
float x = 100;
float y = 50;
ellipse(x, y, 20, 20);
ellipse(x*.8, y, 20, 20);
This creates a drawing of two circles next to each other:
That might seem correct, but now what happens if I change my x variable?
size(200, 100);
float x = 50;
float y = 50;
ellipse(x, y, 20, 20);
ellipse(x*.8, y, 20, 20);
Since I'm multiplying my x value by .8, now that I change my x value to 50, the second ellipse will be at 40, which is only 10 pixels away from the first circle. But in the first sketch, the second ellipse was 20 pixels away!
Note that the same thing will happen if I increase x, the space between the circles will increase. This is what's happening in your example.
To fix this, I need to add values to my variables to get the locations of my other shapes:
size(200, 100);
float x = 150;
float y = 50;
ellipse(x, y, 20, 20);
ellipse(x-20, y, 20, 20);
Now the circles will stay next to each other (in this case, 20 pixels apart) no matter what the value of x is.
You have to do something similar, just with two variables instead of one. If it doesn't make sense, try drawing your figure out on a piece of paper, and use a few different example values for x and y. What are the locations of the other shapes?
Also, you're already using instance variables. Those are just the variables at the top of your sketch. (Unless you're supposed to be using classes, but I doubt that's the case here.)

Related

Processing Square Stacking loop

This is my first time writing here so i'll be direct, i've been trying to recreate this image:
and so far all the code i've got is:
void setup() {
size(500, 500);
}
void draw() {
rectMode(CENTER);
recta();
}
void recta() {
noFill();
int a = 10;
int y = 250;
for (int x = 0; x<20; x++) {
pushMatrix();
translate(y, y);
rect(0, 0, a, a);
popMatrix();
rotate(radians(2.0*PI));
stroke(0, 0, 0);
a= a - 20;
}
}
And i have no idea what to do next since this is what i get from it:
So i'd like to ask for help on how to get the same result as the image.
You are so close !
You're absolutely on the right track using pushMatrix()/popMatrix() to isolate coordinate systems, however you might have accidentally placed the rotation after popMatrix() which defeats the purpose. You probably meant to for each square to have an independent rotation from each other and not accumulate 2 * PI to the global rotation.
The other catch is that you're rotating by the same angle (2 * PI) for each iteration in your for loop and that rotation is 360 degrees so even if you fix rotation like this:
pushMatrix();
translate(y, y);
rotate(radians(2.0*PI));
rect(0, 0, a, a);
popMatrix();
you'll get a scaling effect:
(Minor note 2.0 * PI already exists in Processing as the TWO_PI constant)
To get that spiral looking effect is to increment the angle for each iteration (e.g. x = 0, rotation = 0, x = 1, rotation = 5, x = 2, rotation = 10, etc.). The angle increment is totally up to you: depending on how you map the x increment to a rotation angle angle you'll get a tighter or looser spiral.
Speaking of mapping, Processing has a map() function which makes it super easy to map from one range of numbers (let's say x from 0 to 19) to another (let's say 0 radians to PI radians):
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
Here's a basic sketch based on your code:
int a = 10;
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
background(255);
recta();
}
void recta() {
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
}
I've removed draw() because it was rendering the same frame without any change: drawing once in setup() achieves the same visual effect using less CPU/power.
You can use draw(), but might as add some interactivity or animation to explore shapes. Here's a tweaked version of the above with comments:
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
}
void draw(){
background(255);
recta();
}
void recta() {
// map mouse X position to -180 to 180 degrees (as radians)
float maxAngle = map(mouseX, 0, width, -PI, PI);
// reset square size
int a = 10;
// for each square
for (int x = 0; x < 20; x++) {
// isolate coordinate space
pushMatrix();
// translate first
translate(y, y);
// then rotate: order matters
// map x value to mouse mapped maximum rotation angle
rotate(map(x, 0, 19, 0, maxAngle));
// render the square
rect(0, 0, a, a);
popMatrix();
// decrease square size
a = a - 20;
}
}
Remember transformation order matters (e.g. translate() then rotate() would produce different effects compared to rotate() then translate()). Have fun!

Ellipses not expanding?

I'm working on a Processing project for an art class and my plan was to make an audio visualizer where circles would appear from the amplitudes from the audio file. My main problem is that I'm trying to achieve a ripple effect where the circles would expand and ripple outward beyond the window after generating, but all of my circles stay put.
Here's my draw function:
void draw(){
int n = 1000;
fft.forward(song.mix);
for (int i = 0; i <fft.specSize(); i++ ) {
z = fft.getBand(i) * 20;
if (n < 150){
stroke(colors [(int)random(0,9)]);
strokeWeight(random(50, 300)); //bigger strokes towards the middle
ellipse(x, y, z, z); //basic lines and shapes
z ++;
}
else{
stroke(colors [(int)random(0,9)]);
strokeWeight(random(10));
ellipse(x, y, z, z); //basic lines and shapes
z ++;
}
}
}
I'm not sure where I'm going wrong since I am incrementing z, so as far as I know each ellipses should expand.
You're not seeing any expansion, since you're only incrementing z within a single draw call and then it is reset. But in order to see the expansion, z must be incremented over multiple draw cycles. You can do this by using an if statement instead of a loop. Note that draw is continually called.
int i = -1;
void draw(){
int n = 1000;
fft.forward(song.mix);
if(++i < fft.specSize()) {
z = fft.getBand(i) * 20;
if (n < 150){
stroke(colors [(int)random(0,9)]);
strokeWeight(random(50, 300)); //bigger strokes towards the middle
ellipse(x, y, z, z); //basic lines and shapes
z ++;
}else{
stroke(colors [(int)random(0,9)]);
strokeWeight(random(10));
ellipse(x, y, z, z); //basic lines and shapes
z ++;
}
}
}
I haven't tested it, but this should redraw the ellipses as they expand.
P.S. If the height and width of your ellipse are equal, you can use circle(x, y, z).

Calculate ellipse size in relation to distance from center point

I want to achieve a slow fade in size on every collapse into itself. In other words, when the circle is at its biggest, the ellipses will be at the largest in size and conversely the opposite for the retraction. So far I am trying to achieve this affect by remapping the cSize from the distance of the center point, but somewhere along the way something is going wrong. At the moment I am getting a slow transition from small to large in ellipse size, but the inner ellipses are noticeably larger. I want an equal distribution of size amongst all ellipses in relation to center point distance.
I've simplified the code down to 4 ellipses rather than an array of rows of ellipses in order to hopefully simplify this example. This is done in the for (int x = -50; x <= 50; x+=100).
I've seen one or two examples that slightly does what I want, but is more or less static. This example is kind of similar because the ellipse size gets smaller or larger in relation to the mouse position
Distance2D
Here is an additional diagram of the grid of ellipses I am trying to create, In addition, I am trying to scale that "square grid" of ellipses by a center point.
Multiple ellipses + Scale by center
Any pointers?
float cSize;
float shrinkOrGrow;
void setup() {
size(640, 640);
noStroke();
smooth();
fill(255);
}
void draw() {
background(#202020);
translate(width/2, height/2);
if (cSize > 10) {
shrinkOrGrow = 0;
} else if (cSize < 1 ) {
shrinkOrGrow = 1;
}
if (shrinkOrGrow == 1) {
cSize += .1;
} else if (shrinkOrGrow == 0) {
cSize -= .1;
}
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
float d = dist(x, y, 0, 0);
float fromCenter = map(cSize, 0, d, 1, 10);
pushMatrix();
translate(x, y);
rotate(radians(d + frameCount));
ellipse(x, y, fromCenter, fromCenter);
popMatrix();
}
}
}
The values you're passing into the map() function don't make a lot of sense to me:
float fromCenter = map(cSize, 0, d, 1, 100);
The cSize variable bounces from 1 to 10 independent of anything else. The d variable is the distance of each ellipse to the center of the circle, but that's going to be static for each one since you're using the rotate() function to "move" the circle, which never actually moves. That's based only on the frameCount variable, which you never use to calculate the size of your ellipses.
In other words, the position of the ellipses and their size are completely unrelated in your code.
You need to refactor your code so that the size is based on the distance. I see two main options for doing this:
Option 1: Right now you're moving the circles on screen using the translate() and rotate() functions. You could think of this as the camera moving, not the ellipses moving. So if you want to base the size of the ellipse on its distance from some point, you have to get the distance of the transformed point, not the original point.
Luckily, Processing gives you the screenX() and screenY() functions for figuring out where a point will be after you transform it.
Here's an example of how you might use it:
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
pushMatrix();
//transform the point
//in other words, move the camera
translate(x, y);
rotate(radians(frameCount));
//get the position of the transformed point on the screen
float screenX = screenX(x, y);
float screenY = screenY(x, y);
//get the distance of that position from the center
float distanceFromCenter = dist(screenX, screenY, width/2, height/2);
//use that distance to create a diameter
float diameter = 141 - distanceFromCenter;
//draw the ellipse using that diameter
ellipse(x, y, diameter, diameter);
popMatrix();
}
}
Option 2: Stop using translate() and rotate(), and use the positions of the ellipses directly.
You might create a class that encapsulates everything you need to move and draw an ellipse. Then just create instances of that class and iterate over them. You'd need some basic trig to figure out the positions, but you could then use them directly.
Here's a little example of doing it that way:
ArrayList<RotatingEllipse> ellipses = new ArrayList<RotatingEllipse>();
void setup() {
size(500, 500);
ellipses.add(new RotatingEllipse(width*.25, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.75));
ellipses.add(new RotatingEllipse(width*.25, height*.75));
}
void draw() {
background(0);
for (RotatingEllipse e : ellipses) {
e.stepAndDraw();
}
}
void mouseClicked() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
void mouseDragged() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
class RotatingEllipse {
float rotateAroundX;
float rotateAroundY;
float distanceFromRotatingPoint;
float angle;
public RotatingEllipse(float startX, float startY) {
rotateAroundX = (width/2 + startX)/2;
rotateAroundY = (height/2 + startY)/2;
distanceFromRotatingPoint = dist(startX, startY, rotateAroundX, rotateAroundY);
angle = atan2(startY-height/2, startX-width/2);
}
public void stepAndDraw() {
angle += PI/64;
float x = rotateAroundX + cos(angle)*distanceFromRotatingPoint;
float y = rotateAroundY + sin(angle)*distanceFromRotatingPoint;
float distance = dist(x, y, width/2, height/2);
float diameter = 50*(500-distance)/500;
ellipse(x, y, diameter, diameter);
}
}
Try clicking or dragging in this example. User interaction makes more sense to me using this approach, but which option you choose really depends on what fits inside your head the best.

make curtain like behaviour in drawing of lines

I am new to Processing.js and need a little bit support with this issue. I have made a HTML-Canvas animation where I have lines with a curtain like behavior which can be seen here:
Click
this is made with a canvas plugin called Paper.js
I now want to get similar effect on processing but don't really know how to figure it out. My attempt was:
float x;
float y;
void setup() {
size(1024, 768);
strokeWeight(2);
background(0, 0, 0);
}
void mouseMoved() {
x = mouseX;
y = mouseY;
}
void draw() {
background(0);
line(50, 50, x += x - x/5, y += y - y/5);
stroke(255, 255, 255);
line(50, 700, x += x - x/15, y += y - y/15);
stroke(255, 255, 255);
line(75, 50, x += x - x/25, y += y - y/25);
stroke(255, 255, 255);
line(75, 700, x += x - x/35, y += y - y/35);
// and so on, would create it within a loop
}
So what I am trying to do is basically get the same effect which I have done in HTML and adapt it in Processing.js.
Thanks in advance.
I'd strongly recommend ignoring the paper.js and reimplementing this properly. We're seeing a sequence of lines that connect to a historical line of coordinates, based on mouse position, so let's just implement that:
class Point {
float x, y;
Point(float _x, float _y) { x=_x; y=_y; }}
// our list of historical points
ArrayList<Point> points;
// the horizontal spacing of our lines has fixed interval
float interval;
// how many lines do we want to draw?
int steps = 50;
void setup() {
size(500, 500);
// initialise the "history" as just the midpoint
points = new ArrayList<Point>();
for (int i=0; i<steps; i++) {
points.add(new Point(width/2, height/2));
}
// compute the horizontal interval, because it's
// width-dependent. Never hard code dependent values.
interval = width/(float)steps;
// the lower we set this, the slower it animates.
frameRate(60);
}
void draw() {
// white background, black lines
background(255);
stroke(0);
// for each historic point, draw two
// lines. One from height 0 to the point,
// another from height [max] to the point.
Point p;
for (int i=0; i<steps; i++) {
p = points.get(i);
line(interval/2 + i*interval, 0, p.x, p.y);
line(interval/2 + i*interval, height, p.x, p.y);
}
// when we move the mouse, that counts as a new historic point
points.remove(0);
points.add(new Point(mouseX, mouseY));
}
Sketch running in the browser: http://jsfiddle.net/M2LRy/1/
(You could speed this up by using a round-robin array instead of an ArrayList, but ArrayLists are pretty convenient here)

How to draw a Gaussian Curve in Processing

I am trying to draw a Gaussian curve with mean = 0 and standard deviation = 1 using processing, but when my code runs, nothing is drawn to the screen (not even the background).
Here is my code:
float x, y, mu, sigma;
void setup() {
size(900, 650);
background(255);
stroke(0);
strokeWeight(1);
mu = 0.0;
sigma = 1.0;
for(int i = -4; i < 4; i += 0.5) {
x = i;
y = (1/(sigma * sqrt(2 * PI)))*(exp((-1 * sq(x - mu)) / (2 * sq(sigma)) ));
x = map(x, -4, 4, 0, width);
y = map(y, 0, 1, 0, height);
point(x, y);
}
}
void draw() {
}
In your for loop, you are using an int as the counter, but you're incrementing it by 0.5. When i is positive and it is incremented, that 0.5 gets truncated and i remains what is was before-- so the loop runs forever. It's a fun observation that i does increase when it is negative-- truncation works towards zero, so adding 0.5 ends up adding 1. Changing the declaration of i from int i = -4 to float i = -4 fixed it on my computer. You may also want to increase the stroke weight, at least temporarily, to verify that the points are being drawn (they were hard to see for me and I wasn't sure it was working at first).

Resources