When I add the parameter "Color" to owl it says that the method owl is not applicable??
I want the owl to change into random colors any suggestions? This is an exercises from Reas and Fry's processing book.
void setup ( ) {
size(700,500);
background(200);
smooth( );
frameRate(10);
}
void pick () {
color (random(255),random(255),random(255));
}
void draw ( ) {
owl(35,100);
}
void owl (int x, int y, color z) {
pick ();
stroke(0) ;
strokeWeight(70) ;
line(x, -35+y, x, -65+y) ; // body
noStroke() ;
fill(255) ;
ellipse(-17.5+x, -65+y, 35, 35) ; // left eye dome
ellipse( 17.5+x, -65+y, 35, 35) ; // right eye dome
arc(0+x, -65+y, 70, 70, 0, PI) ;
fill(0) ;
ellipse(-14+x, -65+y, 8, 8) ; // left eye
ellipse( 14+x, -65+y, 8, 8) ; // right eye
quad(0+x, -58+y, 4+x, -51+y, x, -44+y, -4+x, -51+y) ;
}
v.k. is actually right, although he did not tell you why the colour does not change. The problem is of course that you are calling owl with two parameters while it needs three. As far as I understand you want to pick the random colour with the pick() method, thus you don't need the third parameter in there.
void owl (int x, int y, color z) {
should be
void owl (int x, int y) {
Also you need to somehow fill (or stroke) things with the random colour you have correctly created. The problem is, as long as you don't pass it in a fill() or a stroke() method, it will not colour anything... So you need to have that colour somehow in the owl() method, you thus return it from the pick() command and use it like this:
color pick () {
return color (random(255),random(255),random(255));
}
and you retrieve it in the owl method and store it in a variable so that you can use it:
color z = pick();
then to change the colour of the eyes you change
fill(0);
to:
fill(z);
Here's the final code in case I have confused you:
void setup ( ) {
size(700,500);
background(200);
smooth( );
frameRate(10);
}
color pick () {
return color (random(255),random(255),random(255));
}
void draw ( ) {
owl(35,100);
}
void owl (int x, int y) {
color z = pick();
stroke(0) ;
strokeWeight(70) ;
line(x, -35+y, x, -65+y) ; // body
noStroke() ;
fill(255) ;
ellipse(-17.5+x, -65+y, 35, 35) ; // left eye dome
ellipse( 17.5+x, -65+y, 35, 35) ; // right eye dome
arc(0+x, -65+y, 70, 70, 0, PI) ;
fill(z) ;
ellipse(-14+x, -65+y, 8, 8) ; // left eye
ellipse( 14+x, -65+y, 8, 8) ; // right eye
quad(0+x, -58+y, 4+x, -51+y, x, -44+y, -4+x, -51+y) ;
}
color is a Processing Datatype for colors. It is aware of colorMode(). The problem is simple, your own method is expecting 3 parameters void owl (int x, int y, color z) {... and you are calling it with 2 owl(35,100). If you say:
owl(35,100, color(random(255),random(255),)random(255));
it will work.
Related
I need some help with a code for an exam in my university.
What I'm trying to do here is a visual representation of a speech between two people. So the code starts when you press "L" and then works a bit like walkie talkie so when the other person speaks need to push "A", when the word goes back to the first person he needs to press "L" again and so on.
I like the result of the code so far but my professor told me to try something and I'm not able to do it.
He would like to see the coloured lines covering all the screen in vertical and not just a portion of it and when they reach the end of the screen on the right split in two so that the first row that just got created becomes half of the screen and the new one creating in the other half. When the second row finishes and the third row is created the screen must split in 3 and so on.
I tried to achieve this but I messed up the code so I will post here the last version of it working.
I hope you can help in any way, all kind of suggestion are appreciated, thank you!
import processing.sound.*;
AudioIn input;
Amplitude amp;
int y;
int x;
int incY = 141;
color bg = color(255, 0);
color high;
color low;
color mid;
void setup() {
size(1440, 846);
background(bg);
pixelDensity(displayDensity());
input = new AudioIn(this, 0);
input.start();
amp = new Amplitude(this);
amp.input(input);
}
void draw() {
textSize(40);
fill(0);
float volume = amp.analyze();
int lncolor = int(map(volume, 0, 0.05, 0, 3));
noFill();
strokeCap(SQUARE);
//strokeWeight(10);
if (lncolor==0) {
stroke(bg);
}
if (lncolor==1) {
stroke(low);
}
if (lncolor==2) {
stroke(mid);
}
if (lncolor==3) {
stroke(high);
}
if (key == 'a') {
x++;
if (x==width) {
x = 0;
y = y + incY;
}
line(x, y, x, y+incY);
high=color(72, 16, 255);
low= color(179, 155, 255);
mid = lerpColor(low, high, .5);
}
if (key == 'l') {
x++;
if (x==width) {
x = 0;
y = y + incY;
}
line(x, y, x, y+incY);
high=color(255, 128, 16);
low= color(255, 203, 156);
mid = lerpColor(low, high, .5);
}
}
The following code won't solve all of your problems, but does show how to keep splitting the screen into proportionate rectangles based on the number of times the graph exceeds the width of the screen. The advancing green bar at the top is where your current signal would be plotted. I'll leave it to you to figure out how to get all the old signal into its respective rectangle. I was unable to run the code that you posted; error message was "Audio Input not configured in start() method". All that I saw was a blank screen.
int x = 0;
int counter = 1;
void rectGrid(int t, int w, int h) {
int top;
for (int k = 0; k < counter; k++) {
top = t + k*h;
stroke(0);
strokeWeight(1);
fill(random(255));
rect( 0, top, w, h);
}
}
void setup() {
size(400, 400);
background(209);
}
void draw() {
fill(0, 255, 0);
rect(0, 0, x++, height/counter);
if (x == width) {
counter++;
println("count = ", counter + " : " + "height = ", height/counter);
x = 0;
background(209);
rectGrid(0, width, height/counter);
}
}
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!
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.)
I'm trying to activate different visuals by pressing different keys. For example, when I press "z" or "Z", an ellipse on a specific position flows down, leaving a trace behind. If I wait for it to reach the canvas border, there's no problem but when I press "0" which activates another ellipse on another position to do the same thing, the ellipse of "z"/"Z" stops flowing. It also happens when I press the same key before the ellipse reaches canvas border. How can I fix this? When I started to code this, I didn't know classes and objects, then I learned and tried to solve it by using creating an object but it got worse, ellipses didn't work at all. I want the first ellipse to continue until the border even if I press another key while it's on its way.
Another thing is I wanted them to fade out after a short time, so I drew semi-transparent rectangles on canvas which seems very primitive to me. Would you suggest a different way? This is less important but it would be better to have them completely fade over time rather than leaving a slight trace.
Here's my code, I cleaned irrelevant parts to make it look more understandable:
void setup() {
size(640, 500);
background(bgRenk);
frameRate(60);
colorMode(HSB);
noStroke();
}
int bgRenk = #e7e7e7;
int C3Yer;
int C3Y;
int Fd6Yer;
int Fd6Y;
void draw() {
// This part probably sucks because it's a primitive solution to make ellipses fade out by putting semi-transparent rectangles on the canvas.
fill(bgRenk, 10);
rect(0, 0, 640, 500);
// I basically map x and y positions to hue and opacity.
float C3Renk= map(C3Yer, 0, width, 0, 255);
float C3Opak = map(C3Y, height, 0, 0, 200);
// When z/Z is pressed, an ellipse appears and goes down, leaving trace behind.
if (key == 'z' || key == 'Z') {
C3Yer = 10;
fill(C3Renk, 255, 255, C3Opak);
ellipse(C3Yer, C3Y, 20, 20);
C3Y += 20;
}
if (key == '0') {
// Same mapping and ellipse thing.
float Fd6Renk= map(Fd6Yer, 0, width, 0, 255);
float Fd6Opak = map(Fd6Y, height, 0, 0, 200);
Fd6Yer = 630;
fill(Fd6Renk, 255, 255, Fd6Opak);
ellipse(Fd6Yer, Fd6Y, 20, 20);
Fd6Y += 20;
}
}
void keyPressed() {
if (key == 'z' || key == 'Z') {
// When z/Z is pressed, y position of those ellipses are reset.
C3Y = 10;
}
if (key == '0') {
// Same reset thing.
Fd6Y = 10;
}
}
Thank you for your time.
Problem with creating new ellipse while other is still flowing is with variable key which always contains the value of the most recent key used (for more see). So when you press any key after "z" your ellipse will stop being drawn.
You can avoid this using global variables indicating which ellipses should be drawn.
But I would suggest using creating objects that will have defined state (position, color, opacity) and will be stored inside array or list. It will also help you with fading so find a time and read more about classes and objects. On processing site you can find nice tutorials like this one
But because you sad you already tried creating objects and i don't works I will give you few tips and basic example of such a class:
class Ball {
float x, y; // position of ball
color col = 10; // color of ball
int opac = 255; // opacity of ball
Ball(float _x, float _y) {
x = _x;
y = _y;
}
void move() {
y += 20;
opac -= 10;
}
void display() {
fill(col, 255, 255, opac);
ellipse(x, y, 20, 20);
}
}
Then you can create new ball objects:
void mousePressed() {
//this will create new ball on mouse position
balls.add( new Ball(mouseX, mouseY) );
}
and store them into ArrayList like this:
ArrayList<Ball> balls = new ArrayList();
Last thing that you need to do is display and move all balls within draw method.
for (Ball b : balls) // for each ball in list
{
b.display(); // first display ball
b.move(); // move and change opacity
}
This is very basic example and should be improved but I hope it will help you with understanding of classes.
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)