I have been working on a program in Processing that compares two images and gives me the percent match. I am doing this by using a for loop that calls a get() for every pixel in the image. I have to find a way to call a variable that is initialized inside of the for loops outside of the loops. I have browsed several websites that can't seem to give me any good answers, and I was wondering if it is even possible, and if not, if there is some way to work around it. Here is my code:
PImage fce1;
PImage fce2;
color f1;
color f2;
void setup(){
fullScreen();
background(#353535);
fce1 = loadImage("Face1.jpg");
fce2 = loadImage("Face2.jpg.png");
}
void draw(){
image(fce1, width/2 - 500, 200, 350, 500);
image(fce2, width/2 + 150, 200, 350, 500);
//line(width/2 - 150, height/2 - 250, width/2 + 150, height/2 - 250);
for(int i = height/2 - 250; i <= fce1.height + (height/2 - 250); i ++){
for(int x = width/2 - 500; x <= fce1.width + (width/2 - 500); x ++){
color vm1 = fce1.get(x, i);
this.f1 = vm1;
}
}
for(int i = height/2 - 250; i <= fce2.height + (height/2 - 250); i ++){
for(int x = width/2 + 150; x <= fce2.width + (width/2 + 150); x ++){
color vm2 = fce2.get(x, i);
this.f2 = vm2;
}
}
}
void mousePressed(){
if(mouseX >= 20 && mouseX <= 70 && mouseY >= 20 && mouseY <=70){
exit();
}
}
I am trying to call the variable f1 outside of the for() loop, since the for() loop initializes it. Thanks in advance!
You can just use it after the for loop since you've created it as a global variable. But your f1 and f2 variables are just going to store the last pixel in each image. If you need to compare pixel by pixel, your images would need to have the same pixel count anyway right? So just do the comparisons in your for loop, instead of looping through the whole first image then the whole second one, it'll run faster and actually do what you want I think.
Related
When running this code, the rectangle 'moves' from left to right.
How does the code x = x + 1 generates this?
How does it keep creating rectangles one pixel further on the x-axis?
void setup() {
size(400, 400);
stroke(255);
background(192, 64, 0);
}
int hoogte = 50;
int breedte = 50;
int x = 50;
void draw () {
rect(x,100, breedte, hoogte);
stroke(181);
x = x + 1;
}
Result of running the code
Keep in mind that the draw() function is called 60 times per second.
The x = x + 1 line adds one to the x variable. Since you're drawing your rectangle based on the x variable, the rectangle moves across the screen over time.
Shameless self-promotion: here is a tutorial explaining animation in Processing.
I've got some code that displays 10 ellipses in random locations on the screen, and a square that descends from the top of the screen to the bottom, at which point it resets back at the top. What I'm trying to do is get a counter to increment when that square passes any of the ellipses (by comparing their y-positions). However, the counter increases rapidly instead of steadily and just doesn't behave desirably in general.
Here's my draw() function. barriers[i][0] stores the x-pos, barriers[i][1] the y-pos obviously.
void draw()
{
background(255);
fill(0);
for(int i = 0; i < barriers.length; i++) {
// Draw barriers
ellipse(barriers[i][0], barriers[i][1], 50, 50);
// Did we pass a barrier? (doesn't work!)
if(y >= barriers[i][0] - 1 && y <= barriers[i][1] + 1) {
counter++;
}
}
// Draw the square
rect(x, y, 25, 25);
// Draw counter alongside square
fill(255, 0, 0);
text(counter, x + 25, y - 5);
// Reset
if(y < height) {
y+=5;
} else {
y = -25;
counter = 0;
}
}
Apologies if the solution is blindingly obvious, but I'm just not seeing the problem here...
Looking forward to some assistance.
Look at this section of code:
if(y >= barriers[i][0] - 1 && y <= barriers[i][1] + 1) {
counter++;
}
The draw() function fires 60 times a second, so this code will be fired 60 times per second. That means that while you're passing a barrier, the counter variable will increment 60 times per second!
Presumably you only want the counter to increase once for each barrier. There are a number of ways to do this. You could have another data structure that keeps track of whether each barrier has already been passed, and then only check barriers that haven't been passed yet. Or you could keep track of the previous positions of the square, and then use that to determine when the square starts passing a barrier.
Think about how you would do this in your head, without a computer. How do you know when the square is passing a circle? How do you, in your head, only count one for each barrier?
Following Kevin's advice, I was able to get it working using an array of booleans which I used to ensure I wasn't incrementing counter more than once:
Full code:
float barriers[][] = new float[10][2];
float x = 400;
float y = -25;
int counter = 0;
boolean barriersChecked[] = {false, false, false, false, false, false, false, false, false, false};
void setup()
{
size(800, 600);
genBarriers();
}
void genBarriers()
{
for (int i = 0; i < barriers.length; i++) {
barriers[i][0] = random(width);
barriers[i][1] = random(height);
}
}
void draw()
{
background(255);
fill(0);
for (int i = 0; i < barriers.length; i++) {
// Draw barriers
ellipse(barriers[i][0], barriers[i][1], 50, 50);
// Did we pass a barrier?
if (barriers[i][1] < y && !barriersChecked[i]) {
counter++;
barriersChecked[i] = true;
}
}
// Draw the square
rect(x, y, 25, 25);
// Draw counter alongside square
fill(255, 0, 0);
text(counter, x + 25, y - 5);
// Reset
if (y < height) {
y+=2;
} else {
y = -25;
genBarriers();
// Reset barriersChecked
for(int i = 0; i < barriersChecked.length; i++) {
barriersChecked[i] = false;
}
}
}
Out of curiosity, is there a more elegant (loopless) way of resetting every element in barriersChecked back to false?
Suggestions of additional improvements would also be greatly appreciated.
I'm fairly new to processing but I am having trouble shifting the z position on one of my line sets.
The x axis lines look as I need it to, but I am basically trying to bring up the Y set of lines so they arent just going downwards but are more linked up with the first set of lines. I hope I'm making sense, It's kind of hard to explain. Thanks!
Edit: Basically what Im trying to make is a tiled floor.
int grid = 80;
void setup() {
size (1024, 900, P3D);
}
void draw() {
int movement = mouseY-500;
background(0);
strokeWeight(2.5);
stroke(100, 255, 0, 60);
//floorx
for (int i = 0; i < width; i+=grid) {
line (i , height/2 , 0, i , height, 5000);
}
//floory
for (int i = 0; i < height; i+=grid) {
line (0, i + height/2, 0, width, i + height/2,0 );
}
}
I think that you want the grid to appear more geometrically correct. To achieve this you need different distances between the horizontal lines.
Try this in your floory part:
grid = 40;
//floory
for (int i = 0; i < height; i+=grid) {
line (0, i + height/2, 0, width, i + height/2, 0 );
grid += 20;
}
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)
I have created a grid of thumbs. When a certain thumb is pressed I want the image that is linked to the thumb added on screen. I know i'm supposed to write the loadImages in setup(), but i'm a bit confused on how to do this.
PShape[] Quotes = new PShape[6];
int qLength = Quotes.length;
setup() {
size(1024, 768);
}
draw() {
stroke(bruin);
strokeWeight(5);
fill(wit);
rectMode(CORNER);
rect(guide, 280, bBorder, 145);
noStroke();
fill(bruin);
rect(guide, 280, bBorder, 40);
textFont(kaffeesatzFont);
textSize(30);
fill(wit);
text("Quotes", 80, 308);
createGridQ();
}
void createGridQ(){
xOffset = 30;
yOffset = 325;
xSize = 50;
ySize = 38;
padding = 10;
xPos = padding + xOffset;
yPos = yOffset;
cols = 3;
for(int j = 0; j < qLength; j++){
// Grid
xPos = xOffset + ((j % cols) * (xSize+padding));
yPos = yOffset + ((j / cols) * (ySize+padding));
Quotes[j] = loadShape("Q" + j + ".svg");
shape(Quotes[j], xPos, yPos);
if((mouseX >= xPos) && (mouseX <= xPos+xSize) &&
(mouseY >= yPos) && (mouseY <= yPos+ySize)){
cursor(HAND);
if (mousePressed){
cursor(HAND);
Quotes[j] = loadShape("Q" + j + "groot" + ".svg");
shape(Quotes[j], width/5, height/2-200);
}
}
}
}
You can load an image by declaring a PImage and loading it from a web url or by placing it into your data or source directory (where your .pde files are) and then loading it from there.
PImage img;
img = loadImage("laDefense.jpg");
Processing loadImage Reference
So, replace "laDefense.jpg" with the name of the image you want to use and place that image into your data folder. After that, you can place the image in the scene and manipulate it as you would a shape.