In Processing, I keep getting 0 when I multiply width or height by a number. For example:
int x = width*2;
I get x = 0. Why?
When you define a size in processing, width and height are automatically assigned (example size(500,500)). width and height are 500 in this case.
Note that width and height only have values after you call the size() function. (Or if you don't call the size() function, after setup() is called.)
That can be a problem if you do stuff before calling the size() function, such as at the beginning of your sketch:
//this happens before the size() function is called!
int x = width*2;
void setup(){
size(500, 500);
}
The solution is to put the declaration of sketch-level variables at the top of your sketch, but only do their initialization after calling the size() function:
int x;
void setup(){
size(500, 500);
x = width*2;
}
This could also be caused if you try to define your own width and height variables:
//don't do this!
int width;
int height;
void setup(){
size(500, 500);
println(width);
}
Don't do this! Just use the width and height variables that Processing has already declared for you.
More generally, as you've seen, questions tend to be closed pretty quickly if people can't reproduce your problem. Although you did include the fact that you're using Processing, you'll have better luck in the future if you include an MCVE that we can run to see the problem ourselves. The code I've posted in this answer is a good example of the type of thing you should include in your questions in the future, that way they don't get closed.
Related
I want to make a background with changing color on each point of the window depending on the distance of that point from the center of the window in Processing. All I need is a variable to designate x and y coordinates of the screen. How can I do that?
Now, I tried to define such a variable in Processing but failed to do so. But, I've written this code with built-in variables mouseX and mouseY. This is the code I've written:
void setup(){
size(640,360);
frameRate(144);
}
void draw(){
int x=0;
int y=0;
x=x+1;
y=y+1;
float d=dist(width/2,height/2, mouseX,mouseY);
float maxd=dist(width/2,height/2, width,height);
float colour=map(d,0,maxd,0,255);
stroke(50,20,30);
strokeWeight(2);
for(x=0; x<width; x=x+20){
for(y=0; y<height; y=y+20){
rect(x,y,20,20);
fill(colour);
}
}
}
and it works perfectly as I expected. Now, all I need is some variables (like mathematical variables which change the values within some defined range) to specify the coordinates of each point on the screen. Any hint is appreciated.
You're already doing most of what you've described with this nested for loop:
for(x=0; x<width; x=x+20){
for(y=0; y<height; y=y+20){
This nested for loop creates x and y variables that iterate over every point in the frame.
From here, you could use those variables to calculate a color. Here's a simplified example:
for(x=0; x<width; x=x+20){
for(y=0; y<height; y=y+20){
fill(x, y, 0);
rect(x, y, 20, 20);
}
}
This code now uses the x and y variables directly in the calculation of the fill color.
From here, you could add logic that calculates a color based on the distance between 0,0 and x,y. You already have most of that logic as well, but you need to move it to be inside this nested for loop.
Shameless self-promotion: here is a tutorial on for loops, and here are some examples that use for loops, including examples that draw a different color at each point.
When I use the height and width as a constant I was wondering why it's giving me the value 100? Is it because size(); was not declared above? How do I set it to the size of the canvas? Because the following prints 100
Any help would do!!
Here is a copy of my code:
final int SIZE = height;
void setup() {
size (1000,1000);
println(SIZE);
}
For primitive types the value itself is stored in a variable.
So when you call final int SIZE = height; SIZE will have the value which height had immediately prior to that assignment. All subsequent changes to height will not affect SIZE.
The width and height variables are set when you call the size() function. You're using them outside of a function, which means they're happening before the size() function is called, which is why they still have their default values.
To fix this, you need to move the variable initialization to be after size() is called:
int SIZE;
void setup() {
size (1000,1000);
SIZE = height
println(SIZE);
}
See the processing documentation for size():
... If size() is not used, the window will be given a default size of 100 x 100 pixels.
and height:
... The value of height defaults to 100 if size() is not used in a program.
This means as long size() was not called, the values for height and width are initialized to 100.
If you read the variables before, as you do it, then they will return 100.
You have to initialize SIZE after calling size():
void setup() {
size (1000,1000);
SIZE = height;
}
float speed = 1;
void setup() {
size(400, 300);
}
void draw() {
background(255);
move();
display();
}
void move() {
x = x + speed;
if (x > 350) {
speed = 0;
}
}
void display(x,y) {
fill(#FF2121);
translate(x,y);
ellipse(0, 0, 60, 60);
rect(-10, 15, 20, 100);
}
Unexpected token: x on "Void display (x,y)"
Basically this program moves the ellipse and rect to other side of the window. is this the right way to do it? or is there any other easy way.
Example
0 = ellipse
[] = rect
move to other side of window (speed of 1) and when it hit the edge, both them stop.
Parameters need types, just like variables do.
void display(float x, float y) {
Also note that since your display() function takes 2 parameters, it's illegal to call it without any parameters, which is what you're doing in your draw() function.
Also note that you've never defined the x variable, so that's another error.
Please get into the habit of working in smaller chunks instead of trying to write your whole program all at one time. You've got quite a few errors here, and it's going to be hard to fix one without fixing the others. I recommend starting over with something simpler, and only moving forward when you have something that works.
The code is supposed to fade and copy the window's image to a buffer f, then draw f back onto the window but translated, rotated, and scaled. I am trying to create an effect like a feedback loop when you point a camera plugged into a TV at the TV.
I have tried everything I can think of, logged every variable I could think of, and still it just seems like image(f,0,0) is doing something wrong or unexpected.
What am I missing?
Pic of double image mirror about x-axis:
PGraphics f;
int rect_size;
int midX;
int midY;
void setup(){
size(1000, 1000, P2D);
f = createGraphics(width, height, P2D);
midX = width/2;
midY = height/2;
rect_size = 300;
imageMode(CENTER);
rectMode(CENTER);
smooth();
background(0,0,0);
fill(0,0);
stroke(255,255);
}
void draw(){
fade_and_copy_pixels(f); //fades window pixels and then copies pixels to f
background(0,0,0);//without this the corners dont get repainted.
//transform display window (instead of f)
pushMatrix();
float scaling = 0.90; // x>1 makes image bigger
float rot = 5; //angle in degrees
translate(midX,midY); //makes it so rotations are always around the center
rotate(radians(rot));
scale(scaling);
imageMode(CENTER);
image(f,0,0); //weird double image must have something not working around here
popMatrix();//returns window matrix to normal
int x = mouseX;
int y = mouseY;
rectMode(CENTER);
rect(x,y,rect_size,rect_size);
}
//fades window pixels and then copies pixels to f
void fade_and_copy_pixels(PGraphics f){
loadPixels(); //load windows pixels. dont need because I am only reading pixels?
f.loadPixels(); //loads feedback loops pixels
// Loop through every pixel in window
//it is faster to grab data from pixels[] array, so dont use get and set, use this
for (int i = 0; i < pixels.length; i++) {
//////////////FADE PIXELS in window and COPY to f:///////////////
color p = pixels[i];
//get color values, mask then shift
int r = (p & 0x00FF0000) >> 16;
int g = (p & 0x0000FF00) >> 8;
int b = p & 0x000000FF; //no need for shifting
// reduce value for each color proportional
// between fade_amount between 0-1 for 0 being totallty transparent, and 1 totally none
// min is 0.0039 (when using floor function and 255 as molorModes for colors)
float fade_percent= 0.005; //0.05 = 5%
int r_new = floor(float(r) - (float(r) * fade_percent));
int g_new = floor(float(g) - (float(g) * fade_percent));
int b_new = floor(float(b) - (float(b) * fade_percent));
//maybe later rewrite in a way to save what the difference is and round it differently, like maybe faster at first and slow later,
//round doesn't work because it never first subtracts one to get the ball rolling
//floor has a minimum of always subtracting 1 from each value each time. cant just subtract 1 ever n loops
//keep a list of all the pixel as floats? too much memory?
//ill stick with floor for now
// the lowest percent that will make a difference with floor is 0.0039?... because thats slightly more than 1/255
//shift back and or together
p = 0xFF000000 | (r_new << 16) | (g_new << 8) | b_new; // or-ing all the new hex together back into AARRGGBB
f.pixels[i] = p;
////////pixels now copied
}
f.updatePixels();
}
This is a weird one. But let's start with a simpler MCVE that isolates the problem:
PGraphics f;
void setup() {
size(500, 500, P2D);
f = createGraphics(width, height, P2D);
}
void draw() {
background(0);
rect(mouseX, mouseY, 100, 100);
copyPixels(f);
image(f, 0, 0);
}
void copyPixels(PGraphics f) {
loadPixels();
f.loadPixels();
for (int i = 0; i < pixels.length; i++) {
color p = pixels[i];
f.pixels[i] = p;
}
f.updatePixels();
}
This code exhibits the same problem as your code, without any of the extra logic. I would expect this code to show a rectangle wherever the mouse is, but instead it shows a rectangle at a position reflected over the X axis. If the mouse is on the top of the window, the rectangle is at the bottom of the window, and vice-versa.
I think this is caused by the P2D renderer being OpenGL, which has an inversed Y axis (0 is at the bottom instead of the top). So it seems like when you copy the pixels over, it's going from screen space to OpenGL space... or something. That definitely seems buggy though.
For now, there are two things that seem to fix the problem. First, you could just use the default renderer instead of P2D. That seems to fix the problem.
Or you could get rid of the for loop inside the copyPixels() function and just do f.pixels = pixels; for now. That also seems to fix the problem, but again it feels pretty buggy.
If somebody else (paging George) doesn't come along with a better explanation by tomorrow, I'd file a bug on Processing's GitHub. (I can do that for you if you want.)
Edit: I've filed an issue here, so hopefully we'll hear back from a developer in the next few days.
Edit Two: Looks like a fix has been implemented and should be available in the next release of Processing. If you need it now, you can always build Processing from source.
An easier one, and works like a charm:
add f.beginDraw(); before and f.endDraw(); after using f:
loadPixels(); //load windows pixels. dont need because I am only reading pixels?
f.loadPixels(); //loads feedback loops pixels
// Loop through every pixel in window
//it is faster to grab data from pixels[] array, so dont use get and set, use this
f.beginDraw();
and
f.updatePixels();
f.endDraw();
Processing must know when it's drawing in a buffer and when not.
In this image you can see that works
//pig animation
float x = 100;
float y = 100;
float p = 150;
float l = 10;
float a = 100;
float b = 100;
float n =20;
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 otherpigTail = 200;
int speed = 1;
void setup () {
size (600, 600);
a = width/2.5;
b = height/2;
}
void draw() {
background(184, 233, 249);
//Draw legs
stroke(0);
fill(249, 137, 244);
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
stroke(0);
fill(249, 137, 244);
ellipse(110+x,y-pigBody, p, p-20);
//draw tail
fill(0);
line(185+x, y-pigTail, x+otherpigTail, y-(2*pigTail));
// Draw payer's head
fill(249, 137, 244);
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
stroke(0);
fill(198, 105, 194);
ellipse(x, y, pigNose, pigNose);
//draw ears
stroke(0);
fill(198, 105, 194);
ellipse(x-(w/2),y-h, pigEars, pigEars);
ellipse(x+(w/2),y-h, pigEars, pigEars);
}
class Pet {
float pigX;
float pigY;
}
I have to make animations appear for this pig under the Class Pet section. I'm not exactly sure how to do this, so if you guys could help that would be great!
Even just an example with an ellipse or something would help. Also, have I set this up correctly so far?
Please note that you aren't actually using your Pet class. You never create an instance of it. You're still just using the variables at the top of your sketch. Please see my answer to your previous question for an explanation of how to use a class instead of variables at the top of your sketch.
As for a winking eye, you need to take a step back and ask yourself exactly what that looks like. If you have a circle for an eye, what would winking look like? Try to describe what it's doing, in English. Write down a series of steps that you could give to another person who has no idea what you're working on, and have that person describe exactly what's happening to you. Have them draw out each frame, and see what they draw out. Hint: The ellipse() function takes arguments for both its width and height. You could use them.
More generally, I really suggest getting into the habit of trying something out before you post a question on Stack Overflow. Stack Overflow isn't really designed for general "how do I do this" type questions. It's designed for more specific "I tried X, expected Y, but got Z instead" type questions. You need to get into the habit of at least coming up with the steps in English (also known as an algorithm) that you want to accomplish, and then we can go from there. Break your problem down into smaller steps: instead of posting about your entire pig, just post the eye part. Try to get that look like it's blinking, and then add that back to your main sketch. Also note that you have asked several questions here, but you've never accepted any answers, which a lot of people don't like.
Anyway I'd love to continue helping you, but you have to get into the habit of breaking your problem down into smaller steps, writing out exactly what you want to do in English, and then trying something before posting. Good luck.