How do I animate a line from my draw() function? - processing

I'm using Processing to create a learning experience project that allows users to join network components together. I have links using standard lines, but I want to be able to show a signal moving through the line if there is a valid connection. Think of the line as a network cable for example. Is there anyway I can animate this line?
void draw(){
pushStyle();
stroke(0);
line(from.x, from.y, to.x, to.y);
popStyle();
}
} //draw function in the 'link' file

Of course you can, but your question is a little broad. You do have a particular type of animation in mind? Endless possibilities ;)
The basic way to handle something like this in processing is to increase some animation-variables every frame (or use time management - though that is beyond the basics).
Because the animation-variables (for instance position or color) are changed every frame, the animation is different every frame. It's animated.
Below I give an example of a small green line traveling over a black 'connection' line. If you read through the code I think you'll figure it out. This should be incorporated in a nice 'connection' class for ease of use on a larger scale.
//set coordinates for connection-line
int fromX = 100;
int toX = 600;
int fromY = 100;
int toY = 200;
//copy start coordinate for animation
int animx = fromX;
int animy = fromY;
//determine animation stepsize
int stepX = (toX-fromX)/10;
int stepY = (toY-fromY)/10;
void setup() {
size(800, 300);
//set framerate so animation is not to fast
frameRate(5);
//draw thick lines
strokeWeight(10);
}
void draw() {
background(255);
// draw connection in black
stroke(0);
line(fromX, fromY, toX, toY);
//draw animation in green
stroke(0, 255, 0);
line(animx, animy, animx+stepX, animy+stepY);
// step animation for next frame
animx = animx+stepX;
animy = animy+stepY;
// check for reset (if the animation on the next frame is drawn outside the line)
if (animx+stepX > toX)
{
animx = fromX;
}
if (animy+stepY > toY)
{
animy = fromY;
}
}

Related

Processing 3.0 Question - struggling to implement some code

wondering if anyone can help with this. I have to write some ode using processing 3.0 for college, basically creating a series of circles that appear randomly and change colours etc. Ive got the circles to appear, and they change location on mouse click.
What Im struggling with is, its asked me to have the circles change colour when the mouse button is pressed, where circles to the right are blue and circles to the left of the mouse pointer are yellow? I have no idea how to implement that at all.
Here's what I have so far, any help would be hugely appreciated:
//declaring the variables
float[] circleXs = new float[10];
float[] circleYs = new float[10];
float[] circleSizes = new float[10];
color[] circleColors = new color[10];
void setup() {
size(600, 600);
createCircles();
}
//creation of showCricles function
void draw() {
background(0);
showCircles();
}
//creation of circles of random size greater than 10 but less than 50 - also of white background colour
void createCircles() {
for (int i = 0; i < circleXs.length; i++) {
circleXs[i] = random(width);
circleYs[i] = random(height);
circleSizes[i] = random(10, 50);
circleColors[i] = color(255,255,255);
}
}
void showCircles() {
for (int i = 0; i < circleXs.length; i++) {
fill(circleColors[i]);
circle(circleXs[i], circleYs[i], circleSizes[i]);
}
}
//creating new circles on mouse click
void mouseClicked() {
createCircles();
}
It's not very complicated, you just miss some of the basics. Here are 2 things you have to know to do what you want to do:
You can use mouseX or mouseY to compare coordinates with the current mouse pointer's position.
This would be way cleaner using class, but I am guessing that you are not quite there as you're using a couple arrays to store coordinates instead. But here's the thing with that method: the array's index always refer to the same object. Here your objects are circles, so every array's index n refers to the same circle. If you find a circle which x coordinate is leftward compared to the mouse pointer, you can change that circle's color by modifying the item at the same index but in the circleColors array.
So I added a couple lines to your mouseClicked() method which demonstrate what I just said. Here they are:
void mouseClicked() {
createCircles();
// here is the part that I added
// for each circle's X coordinate:
for( int i = 0; i < circleXs.length; i++) {
// if the X coordinate of the mouse is lower than the circle's...
if( mouseX > circleXs[i]) {
// then set it's color to yellow
circleColors[i] = color(255, 255, 0);
} else {
// else set it's color to blue
circleColors[i] = color(0, 0, 255);
}
}
}
It should show what you described, or close enough for you to clear the gap.
Hope it helps. Have fun!

How can I show only a part of an image in Processing?

I want to compare two images (same size) fr a presentation with a shifting line. On the left side of this line the one image is should be displayed while on the right side the other picture should stay visible.
This is what I tried (bitmap and ch are the images)
PImage bitmap;
PImage ch;
int framerate = 1000;
void setup() {
size(502, 316);
bitmap = loadImage("bitmap_zentriert.jpg"); // Load an image into the program
ch = loadImage("Karte_schweiz_zentriert.jpg"); // Load an image into the program
frameRate(40); //framerate
}
void draw() {
background(255);
image(ch, 10, 10); // the one image in the back
image(bitmap, 10, 10, bitmap.width, bitmap.height, 10, 10, mouseX, bitmap.height); //show part of the second image in front
rect(mouseX, 10, 1, bitmap.height-1); //make line
}
But the image "bitmap" is the whole image distorted.
How can I do that?
I'd recommend using a PGraphics buffer, which is essentially "Another sketch" that also acts as an Image for drawing purposes, and most definitely not looping at "a thousand frames per second". Only draw something when you have something new to draw, using the redraw function in combination with mouse move events:
PImage img1, img2;
PGraphics imagebuffer;
void setup() {
size(502, 316);
imagebuffer = createGraphics(width, height);
img1 = loadImage("first-image.jpg");
img2 = loadImage("second-image.jpg");
noLoop();
}
void mouseMoved() {
redraw();
}
void draw() {
image(img1, 0, 0);
if (mouseX>0) {
imagebuffer = createGraphics(mouseX, height);
imagebuffer.beginDraw();
imagebuffer.image(img2, 0, 0);
imagebuffer.endDraw();
image(imagebuffer, 0, 0);
}
}
In our setup we load the image and turn off looping because we'll be redrawing based on redraw, and then in response to mouse move events, we generate a new buffer that is only as wide as the current x-coordinate of the mouse, draw our image, which gets cropped "for free" because the buffer is only limited width, and then we draw that buffer as if it were an image on top of the image we already have.
There are many ways to do it, one thing I suggest is to create a 3rd image with the same width and height, then you load the two images pixels and insert in your 3rd image part of image1 pixels and then second part from image2, I wrote this code to test it out, works fine:
PImage img1, img2, img3;
void setup() {
size(500, 355);
img1 = loadImage("a1.png"); // Load an image into the program
img2 = loadImage("a2.png"); // Load an image into the program
img3 = createImage(width, height, RGB); //create your third image with same width and height
img1.loadPixels(); // Load the image pixels so you can access the array pixels[]
img2.loadPixels();
frameRate(40); // frame rate
}
void draw() {
background(255);
// Copy first half from first image
for(int i = 0; i < mouseX; i++)
{
for (int j = 0; j < height ; j++) {
img3.pixels[j*width+i] = img1.pixels[j*width+i];
}
}
// Copy second half from second image
for(int i = mouseX; i < width; i++)
{
for (int j = 0; j < height ; j++) {
img3.pixels[j*width+i] = img2.pixels[j*width+i];
}
}
// Update the third image pixels
img3.updatePixels();
// Simply draw that image
image(img3, 0, 0); // The one image in the back
// Draw the separation line
rect(mouseX, 0, 0, height); // Make line
}
Result :

draw shape on input gives unexpected result how to fix?

I want to draw a shape based on the input of a slider. see the code below:
import controlP5.*;
ControlP5 cp5;
int people = 5;
int DMamt = 0;
int peoplehis;
Slider abc;
PShape vorm;
void setup() {
cp5 = new ControlP5(this);
size(displayWidth, displayHeight);
cp5.addSlider("people")
.setPosition(10,10)
.setWidth(400)
.setRange(0,20)
.setValue(0)
.setNumberOfTickMarks(20)
.setSliderMode(Slider.FIX)
;
cp5.addSlider("DMamt")
.setPosition(450,10)
.setWidth(400)
.setRange(0,255)
.setValue(0)
.setNumberOfTickMarks(5)
.setSliderMode(Slider.FIX)
;
vorm = createShape();
frameRate(10);
}
void draw(){
if(peoplehis != people){
vorm.beginShape();
vorm.fill(DMamt);
for(int i = 0; i <= people; i++){
vorm.vertex(random(500), random(500));
}
endShape();
}
peoplehis = people;
shape(vorm, 100,100);
}
the first time i set the slider value i get a shape with the desired amount of points. but when i change the slider value after the first time the value of the slider get added to the points that are already drawn. but i want a new shape. the old shape should be gone. see below for a example:
first value of slider = 5
this gives me a shape with 5 points (GREAT);
second value of silder = 12
this gives me a shape with 17 points (NOT GREAT)
i want 12 points instead of 17.
how do i do this?? i am not very experienced with code :(
A Processing PShape can consist of multiple shapes, which you can add by calling the beginShape(), vertex(), and endShape() functions multiple times.
If you just want to recreate a new shape instead of adding multiple shapes, then call the createShape() function again to start over with a new PShape instance. Also, make sure you clear out previous frames by calling the background() function.
Here is a simple example:
PShape shape;
void setup() {
size(500, 500);
shape = createShape();
frameRate(60);
}
void mousePressed(){
shape = createShape();
shape.beginShape();
for(int i = 0; i < 3; i++){
shape.vertex(random(width), random(height));
}
shape.endShape();
}
void draw(){
background(0);
shape(shape, 0,0);
}

Processing: Move centerpoint of a random Starfield to the center

I'm working on a little space simulation with processing. In the game you can zoom in & out of the solar system. To gove that a neat paralax effect, I want to zoom into the randomly renerated starsky in the background. So far I have everything working, but the starsky is zooming into the top left corner. I know I have to translate the origin point of the stars to (width/2,height/2), but I can't figure out how I do that.
Here is the code:
int starCount = 1200;
float[] xStar = new float[starCount];
float[] yStar = new float[starCount];
float starSpread;
float zoom;
void setup() {
size(1600, 900);
frameRate(30);
calcStars();
zoom = 1;
}
void draw() {
background(#000000);
for(int i=0;i<starCount;i++){
fill(#fff7e6);
noStroke();
ellipse(xStar[i]*starSpread,yStar[i]*starSpread,1,1);
}
starSpread = 1+zoom*0.001;
}
void calcStars(){
for(int i=0;i<starCount;i++){
xStar[i] = -random(0-width);
}
for(int i=0;i<starCount;i++){
yStar[i] = -random(0-height);
}
}
void mousePressed(){
zoom = zoom - 1;
}
(Click mouse to "zoom" out! <- I want the stars to move to the middle not to the upper left corner)
So, I have 2 arrays giving me 1200 random coordinates in the window. "zoom" is a simple float that's controllable with a slider. This variable controlls the spread of all the content. It's mutiplied by 0.001 to make the effect on my stars just slightly.
Now can somebody help me making the zoom happen as I intend it to?
Thanks in advance!
There are a bunch of ways to do this, but the basic approach is this:
Step 1: Calculate how far apart from the center of the screen each star is.
Step 2: Scale that distance.
Step 3: Draw each star that scaled distance away from the center point.
int starCount = 1200;
float[] xStar = new float[starCount];
float[] yStar = new float[starCount];
float zoom = 1;
void setup() {
size(1600, 900);
frameRate(30);
calcStars();
}
void draw() {
background(#000000);
for (int i=0; i<starCount; i++) {
fill(#fff7e6);
noStroke();
float centerX = width/2.0;
float centerY = height/2.0;
float xDistFromCenterX = centerX - xStar[i];
float yDistFromCenterY = centerY - yStar[i];
float scaledXDistFromCenterX = zoom * xDistFromCenterX;
float scaledYDistFromCenterY = zoom * yDistFromCenterY;
ellipse(centerX + scaledXDistFromCenterX, centerY + scaledYDistFromCenterY , 1, 1);
}
}
void calcStars() {
for (int i=0; i<starCount; i++) {
xStar[i] = -random(0-width);
}
for (int i=0; i<starCount; i++) {
yStar[i] = -random(0-height);
}
}
void mousePressed() {
zoom = zoom + .1;
}
This works, and I think it's pretty close to what you were going for, but you might also consider refactoring your code to use a Star object that keeps track of its own position. Whenever you want to zoom, just tell each Star object to move. You could also draw your starts to an image ahead of time, and then just scale that image. Like I said, there are a bunch of ways to do this.

Processing: How to split screen?

I'm trying to create a multi-player game with Processing, but can't figure out how to split screen into two to display different situation of the players?
like in c#,we have
Viewport leftViewport,rightViewport;
to solve the problem.
Thanks a lot
In processing all drawing operations like rect, eclipse etc. are done on a PGraphics element. You could create two new PGraphic objects with the renderer of your choice, draw on them and add them to your main view:
int w = 500;
int h = 300;
void setup() {
size(w, h);
leftViewport = createGraphics(w/2, h, P3D);
rightViewport = createGraphics(w/2, h, P3D);
}
void draw(){
//draw something fancy on every viewports
leftViewport.beginDraw();
leftViewport.background(102);
leftViewport.stroke(255);
leftViewport.line(40, 40, mouseX, mouseY);
leftViewport.endDraw();
rightViewport.beginDraw();
rightViewport.background(102);
rightViewport.stroke(255);
rightViewport.line(40, 40, mouseX, mouseY);
rightViewport.endDraw();
//add the two viewports to your main panel
image(leftViewport, 0, 0);
image(rightViewport, w/2, 0);
}

Resources