Difference between revisions of "Processing Skeleton Project and Simple Exercises"
(→Challenging Exercise #9) |
|||
(34 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
<bluebox> | <bluebox> | ||
− | This is an introduction to Processing in Eclipse. A skeleton class is all that is needed to start any Processing project this way. In this tutorial you will play with very simple animation and quickly build up on more complicated features of Processing. | + | This is an introduction to Processing in Eclipse. A skeleton class is all that is needed to start any Processing project this way. In this tutorial you will play with very simple animation and quickly build up on more complicated features of Processing.<br /> |
</bluebox> | </bluebox> | ||
<br /> | <br /> | ||
+ | =Additional Information= | ||
+ | --[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 09:58, 5 July 2013 (EDT) <br /> | ||
+ | You may want to check out this video by [http://vimeo.com/user591583 Matt Parker]; another good source of information: | ||
+ | <br /> | ||
+ | <center><videoflash type="vimeo">19076476</videoflash></center> | ||
+ | <br /> | ||
+ | |||
=Setup= | =Setup= | ||
Line 16: | Line 23: | ||
* In the '''Edit''' Window, enter the following code: | * In the '''Edit''' Window, enter the following code: | ||
<br /> | <br /> | ||
− | <source lang="java"> | + | <source lang="java" enclose="div"> |
package tutorial1; | package tutorial1; | ||
Line 48: | Line 55: | ||
<br /> | <br /> | ||
* Click on the white triangle in a green circle under the top menu, and run the Applet. Notice that a circle should appear and follow the mouse. Notice also that it should change color as you click the mouse button. | * Click on the white triangle in a green circle under the top menu, and run the Applet. Notice that a circle should appear and follow the mouse. Notice also that it should change color as you click the mouse button. | ||
− | |||
=Exercises= | =Exercises= | ||
Line 106: | Line 112: | ||
* Try this new version of the program: | * Try this new version of the program: | ||
<br /> | <br /> | ||
− | <source lang="java"> | + | <source lang="java" enclose="div"> |
package tutorial1; | package tutorial1; | ||
Line 146: | Line 152: | ||
* Change it so that the circle changes direction when the mouse button is pressed. | * Change it so that the circle changes direction when the mouse button is pressed. | ||
* Change once more it so that when the button is clicked (check the mouseClicked() function) the circle changes direction and turns right at a right-angle. | * Change once more it so that when the button is clicked (check the mouseClicked() function) the circle changes direction and turns right at a right-angle. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | ::::::::::::[[Processing_Skeleton_Project_Solutions#Exercise_4| Hints & Solutions]] | ||
+ | |||
<br /><br /><br /> | <br /><br /><br /> | ||
{| style="width:100%; background:#eeeeff" | {| style="width:100%; background:#eeeeff" | ||
Line 158: | Line 169: | ||
* Analyze this new piece of code, and try it out: | * Analyze this new piece of code, and try it out: | ||
<br /> | <br /> | ||
− | <source lang="java"> | + | <source lang="java" enclose="div"> |
package tutorial1; | package tutorial1; | ||
Line 207: | Line 218: | ||
* Change the color of the circle when it has fully disappeared, before it reappears. So, for example, it will start red and completely fade away, then it will slowly reappear green, and then start disappearing again. When its fully gone, and reappears, then its color will be orange, or some new color of your choice. | * Change the color of the circle when it has fully disappeared, before it reappears. So, for example, it will start red and completely fade away, then it will slowly reappear green, and then start disappearing again. When its fully gone, and reappears, then its color will be orange, or some new color of your choice. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | :::::::::::::::[[Processing_Skeleton_Project_Solutions#Exercise_5 | Hints and Solutions]] | ||
<br /> | <br /> | ||
Line 218: | Line 233: | ||
<br /> | <br /> | ||
* Same as Exercise #5, but there should be two circles on the applet... | * Same as Exercise #5, but there should be two circles on the applet... | ||
+ | <br /><br /><br /> | ||
+ | :::::::::::::::[[Processing_Skeleton_Project_Solutions#Exercise_6 | Hints and Solutions]] | ||
<br /><br /><br /><br /> | <br /><br /><br /><br /> | ||
Line 230: | Line 247: | ||
* Create a new java class (click on the package, '''New''', '''Java Class''') and call it '''Circle''' | * Create a new java class (click on the package, '''New''', '''Java Class''') and call it '''Circle''' | ||
<br /> | <br /> | ||
− | <source lang="java"> | + | <source lang="java" enclose="div"> |
package tutorial1; | package tutorial1; | ||
Line 273: | Line 290: | ||
<source lang="java"> | <source lang="java"> | ||
package tutorial1; | package tutorial1; | ||
+ | |||
import processing.core.*; | import processing.core.*; | ||
Line 310: | Line 328: | ||
|- | |- | ||
| | | | ||
+ | |||
===Exercise #8=== | ===Exercise #8=== | ||
|} | |} | ||
− | [[Image: | + | [[Image:QuestionMark9.jpg|right|100px]] |
<br /> | <br /> | ||
* Create an '''ArrayList''' of '''Circles''' (the class you added in the previous exercise), and make your program move two circles on the applet. Their initial direction will be random, but they will move around the applet, bouncing off the sides, and change color and transparency as they go around. | * Create an '''ArrayList''' of '''Circles''' (the class you added in the previous exercise), and make your program move two circles on the applet. Their initial direction will be random, but they will move around the applet, bouncing off the sides, and change color and transparency as they go around. | ||
+ | * When it works with 2 circles, then try 20! | ||
+ | <br /><br /><br /> | ||
+ | :::::::::::::::[[Processing_Skeleton_Project_Solutions#Exercise_8 | Hints and Solutions]] | ||
+ | |||
+ | |||
+ | <br /> | ||
+ | <br /> | ||
+ | ---- | ||
+ | ---- | ||
+ | <br /> | ||
+ | <br /> | ||
+ | |||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | |||
+ | ===Challenging Problem #9=== | ||
+ | |} | ||
+ | [[Image:QuestionMark10.jpg|right|100px]] | ||
+ | <br /> | ||
+ | * The following Processing program will create a '''fractal tree''' using recursion. It starts creating the trunk of the tree, then branches splitting up from the trunk at a fixed angle (theta). The larger the angle, the wider the branches split away from the trunk the wider the tree. | ||
+ | * The process repeats for each branch, with sub-branches splitting up from the branches, and so on. | ||
+ | * The size of the branches is proportional to how close they are to the trunk. | ||
+ | |||
+ | <br /> | ||
+ | [[Image:FractalTree_Processing.png|right|250px]] | ||
+ | <source lang="java"> | ||
+ | import processing.core.PApplet; | ||
+ | |||
+ | public class FractalTree extends PApplet { | ||
+ | static int MAXWIDTH = 800; | ||
+ | static int MAXHEIGHT= 800; | ||
+ | |||
+ | private void draw_tree(int order, // the level of recursion. Starts | ||
+ | // positive. | ||
+ | float theta, // angle of new branch leaving this trunk | ||
+ | float d, // size of this branch | ||
+ | float x, float y, // coordinates of base of this branch | ||
+ | float heading) { // angle of direction of this branch | ||
+ | |||
+ | if ( order <= 0 ) | ||
+ | return; | ||
+ | |||
+ | float trunk_ratio = 0.4f; // How big is the trunk relative to whole | ||
+ | // tree? | ||
+ | float trunk = d * trunk_ratio; // length of trunk | ||
+ | |||
+ | // compute x, y of end of the current branch | ||
+ | float delta_x = (float) (trunk * Math.cos( heading )); | ||
+ | float delta_y = (float) (trunk * Math.sin( heading )); | ||
+ | float x2 = x + delta_x; | ||
+ | float y2 = y + delta_y; | ||
+ | |||
+ | // draw current branch | ||
+ | strokeWeight( order+2 ); | ||
+ | line( x, y, x2, y2 ); | ||
+ | |||
+ | // if this branch has sub-branches, then recurse | ||
+ | |||
+ | // make the recursive calls to draw the two subtrees | ||
+ | float newsz = d * (1 - trunk_ratio); | ||
+ | draw_tree(order - 1, theta, newsz, x2, y2, heading - theta); | ||
+ | draw_tree(order - 1, theta, newsz, x2, y2, heading + theta); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void setup() { | ||
+ | // define the size of the applet | ||
+ | size( MAXWIDTH, MAXHEIGHT ); | ||
+ | |||
+ | // make the graphic shapes smooth | ||
+ | smooth(); | ||
+ | |||
+ | // make the background white | ||
+ | background( 255, 255, 255 ); | ||
+ | |||
+ | // set the angle of branches departing from trunk | ||
+ | float theta = 0.68f; // use 0.02 for tall skinny trees, 0.75 for fat trees | ||
+ | |||
+ | // draw the tree recursivley | ||
+ | draw_tree( 9, theta, MAXWIDTH * 0.7f, (float) MAXWIDTH/2, | ||
+ | (float) MAXHEIGHT-50, - (float) (Math.PI/2) ); | ||
+ | } | ||
+ | |||
+ | public void draw() { | ||
+ | // nothing to do iteratively; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | <br /> | ||
+ | ;Question | ||
+ | : Modify the program so that the tree bears oranges at specific, regular, locations, as illustrated below. | ||
+ | <br /> | ||
+ | <center>[[Image:FractalDemoTreeWithOranges.png|400px]]</center> | ||
+ | <br /> | ||
+ | : The oranges must be created by the ''draw_tree()'' function. | ||
+ | :* Reminder: to generate an orange disk at coordinates '''x''', '''y''', with diameter '''20''', use this code: | ||
+ | <br /> | ||
+ | ::::<source lang="java"> | ||
+ | fill(204, 102, 0); // set color orange | ||
+ | strokeWeight( 1 ); // set weight of line to 1 pixel | ||
+ | ellipse( x, y, 20, 20 ); // draw circle of diameter 20 | ||
+ | </source> | ||
+ | <br /> | ||
+ | :* Make the oranges appear in front of the branches of the tree, so that branches are not drawn over the oranges. See the detail below. | ||
+ | <br /> | ||
+ | <center>[[Image:OrangeOverBranchesInFractalTree.png]]</center> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <onlydft> | ||
+ | ===Solution Program=== | ||
+ | <br /> | ||
+ | <source lang="java"> | ||
+ | import java.util.LinkedList; | ||
+ | import java.util.Queue; | ||
+ | |||
+ | import processing.core.PApplet; | ||
+ | |||
+ | public class FractalTree extends PApplet { | ||
+ | static int MAXWIDTH = 800; | ||
+ | static int MAXHEIGHT= 800; | ||
+ | |||
+ | Queue<Float> orangeCoordinates; | ||
+ | |||
+ | private void draw_tree(int order, // the level of recursion. Starts | ||
+ | // positive. | ||
+ | float theta, // angle of new branch leaving this trunk | ||
+ | float d, // size of this branch | ||
+ | float x, float y, // coordinates of base of this branch | ||
+ | float heading) { // angle of direction of this branch | ||
+ | |||
+ | if ( order <= 0 ) | ||
+ | return; | ||
+ | |||
+ | float trunk_ratio = 0.4f; // How big is the trunk relative to whole | ||
+ | // tree? | ||
+ | float trunk = d * trunk_ratio; // length of trunk | ||
+ | |||
+ | // compute x, y of end of the current branch | ||
+ | float delta_x = (float) (trunk * Math.cos( heading )); | ||
+ | float delta_y = (float) (trunk * Math.sin( heading )); | ||
+ | float x2 = x + delta_x; | ||
+ | float y2 = y + delta_y; | ||
+ | |||
+ | // draw current branch | ||
+ | fill( 153, 76, 0 ); | ||
+ | strokeWeight( 2 ); //order+2 ); | ||
+ | line( x, y, x2, y2 ); | ||
+ | |||
+ | // draw oranges at level 8 | ||
+ | if ( order==6 ) { | ||
+ | //fill(204, 102, 0); | ||
+ | //strokeWeight( 1 ); | ||
+ | //ellipse( x2, y2, 20, 20 ); | ||
+ | orangeCoordinates.add( x2 ); | ||
+ | orangeCoordinates.add( y2 ); | ||
+ | } | ||
+ | |||
− | < | + | // make the recursive calls to draw the two subtrees |
− | [[Category:Processing]][[Category: | + | float newsz = d * (1 - trunk_ratio); |
+ | draw_tree(order - 1, theta, newsz, x2, y2, heading - theta); | ||
+ | draw_tree(order - 1, theta, newsz, x2, y2, heading + theta); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void setup() { | ||
+ | // define the size of the applet | ||
+ | size( MAXWIDTH, MAXHEIGHT ); | ||
+ | |||
+ | // make the graphic shapes smooth | ||
+ | smooth(); | ||
+ | |||
+ | // make the background white | ||
+ | background( 255, 255, 255 ); | ||
+ | |||
+ | // set the angle of branches departing from trunk | ||
+ | float theta = 0.7f; // use 0.02 for tall skinny trees, 0.7 for fat trees | ||
+ | |||
+ | orangeCoordinates = new LinkedList<Float>(); | ||
+ | // draw the tree recursively | ||
+ | draw_tree( 11, theta, MAXWIDTH * 0.7f, (float) MAXWIDTH/2, | ||
+ | (float) MAXHEIGHT-50, - (float) (Math.PI/2) ); | ||
+ | while( ! orangeCoordinates.isEmpty() ) { | ||
+ | float x2 = orangeCoordinates.poll( ); | ||
+ | float y2 = orangeCoordinates.poll( ); | ||
+ | fill(204, 102, 0); | ||
+ | strokeWeight( 1 ); | ||
+ | ellipse( x2, y2, 20, 20 ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public void draw() { | ||
+ | // nothing to do iteratively; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | </onlydft> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | [[Category:Tutorials]][[Category:Processing]][[Category:Java]][[Category:Eclipse]][[Category:Fractal]] |
Latest revision as of 19:40, 1 November 2014
--D. Thiebaut 09:46, 16 June 2012 (EDT)
This is an introduction to Processing in Eclipse. A skeleton class is all that is needed to start any Processing project this way. In this tutorial you will play with very simple animation and quickly build up on more complicated features of Processing.
Contents
Additional Information
--D. Thiebaut (talk) 09:58, 5 July 2013 (EDT)
You may want to check out this video by Matt Parker; another good source of information:
Setup
- First follow the steps of this great tutorial for creating Processing applications with Eclipse. Remember the steps for adding the core.jar library to your Eclipse project. You will need to repeat them for every new Processing project you want to create. The other option you'll have is to copy paste the skeleton project into another new project, in which case the core library should follow automatically into your new project.
- Note: sometimes it is hard to get the Build Path option for the core.jar file. If this option does not appear, a work-around is to right click on the project, and pick Properties, Java Build Path, then click on the Libraries tab, then Add Jar, pick the core.jar file, and then click Ok.
Skeleton Class
- Create a new class in your package, and call it Main.java.
- In the Edit Window, enter the following code:
package tutorial1;
import processing.core.*;
public class Main extends PApplet {
public void setup() {
// define the window size, make graphics softer, and make
// the background white
size(600, 600);
smooth();
background(255);
}
public void draw() {
// erase screen
background(255);
// change color of circle paint depending on mouse button
if (mousePressed)
fill(0);
else
fill(255);
// draw a circle where the mouse is located
ellipse(mouseX, mouseY, 80, 80);
}
}
- Click on the white triangle in a green circle under the top menu, and run the Applet. Notice that a circle should appear and follow the mouse. Notice also that it should change color as you click the mouse button.
Exercises
Here is a collection of exercises you should go through. They will build on this simple example and get you to play with different features of Processing.
Exercise #1 |
- Change the color of circle to yellow and red, depending on whether the mouse button is clicked or not. Use the processing.org site to figure out how color works in Processing.
Exercise #2 |
- Swap the mouseX and mouseY coordinates in the ellipse() function and see what happens.
- Replace one of the mouseX or mouseY by a call to the random() function.
- You will notice that the circle change widely in the random direction every frame. It's way too busy to be interesting. Instead make the circle stay put when the mouse button is not pressed, and move only when the button is pressed.
- Figure out a way to make the circle move in a random direction, but in a smoother more attractive way...
Exercise #3 |
- Remove the call to the background() function in the draw() function and see what happens...
- Make the color random and use the new applet to paint the screen. Use the mouse button to switch between painting and erasing.
Exercise #4 |
- Try this new version of the program:
package tutorial1;
import processing.core.*;
public class Main extends PApplet {
//--- position and velocity of the circle
float directionX = 2;
float directionY = 1;
float x, y;
public void setup() {
// define the window size, make graphics softer, and make
// the background white
size(600, 600);
smooth();
background(255);
// define circle position and speed
x = width/2;
y = height/2;
directionX = 1;
directionY = 2;
}
public void draw() {
background(255);
x += directionX;
y += directionY;
fill( 255, 0, 0 ); // red
ellipse(x, y, 80, 80);
}
}
- Try it!
- Change it so that the circle changes direction when the mouse button is pressed.
- Change once more it so that when the button is clicked (check the mouseClicked() function) the circle changes direction and turns right at a right-angle.
Exercise #5 |
- Read about the fill() function in processing.org, and in particular pay attention to the notion of transparency.
- Analyze this new piece of code, and try it out:
package tutorial1;
import processing.core.*;
public class Main extends PApplet {
//--- position and velocity of the circle
float directionX = 2;
float directionY = 1;
float x, y;
int transp = 255;
public void setup() {
// define the window size, make graphics softer, and make
// the background white
size(600, 600);
smooth();
background(255);
// define circle position and speed
x = width/2;
y = height/2;
directionX = 1;
directionY = 2;
}
public void draw() {
background(255);
x += directionX;
y += directionY;
if ( x > width ) directionX = -directionX;
if ( y > height ) directionY = -directionY;
transp -= 1;
if ( transp==0 ) transp = 255;
fill( 255, 0, 0, transp ); // red
ellipse(x, y, 80, 80);
}
}
- Modify it so that the circle stays within the boundary of the applet
- Make the circle completely disappear when its transparency is maximum.
- Right now it comes back fully opaque as soon as it has disappeared. Modify the program and make the circle gradually disappear and gradually reappear as it moves around.
- Change the color of the circle when it has fully disappeared, before it reappears. So, for example, it will start red and completely fade away, then it will slowly reappear green, and then start disappearing again. When its fully gone, and reappears, then its color will be orange, or some new color of your choice.
Exercise #6 |
- Same as Exercise #5, but there should be two circles on the applet...
Exercise #7 |
- Create a new java class (click on the package, New, Java Class) and call it Circle
package tutorial1;
import processing.core.*;
public class Circle {
float x;
float y;
float dirX;
float dirY;
int color;
PApplet parent;
Circle( PApplet p, float xx, float yy, float dx, float dy ) {
parent = p;
x = xx;
y = yy;
dirX = dx;
dirY = dy;
color = parent.color( 255, 0, 0, 0 ); // red
}
public void fill( int col ) {
color = col;
}
public void draw( ) {
parent.fill( color );
parent.ellipse( x, y, 80, 80 );
}
public void move( ) {
x += dirX;
y += dirY;
}
}
- Create a new java class called Main2, with the following code
package tutorial1;
import processing.core.*;
public class Main2 extends PApplet {
Circle c;
public void setup() {
// define the window size, make graphics softer, and make
// the background white
size(600, 600);
smooth();
background(255);
// create the circle
c = new Circle( this, width/2, height/2, 1, 0.5f );
}
public void draw() {
background(255);
if (mousePressed) {
c.fill(0);
} else {
c.fill(255);
}
c.move();
c.draw();
}
}
- Check it out!
- Now, repeat all the previous exercises, but use the Circle class instead.
Exercise #8 |
- Create an ArrayList of Circles (the class you added in the previous exercise), and make your program move two circles on the applet. Their initial direction will be random, but they will move around the applet, bouncing off the sides, and change color and transparency as they go around.
- When it works with 2 circles, then try 20!
Challenging Problem #9 |
- The following Processing program will create a fractal tree using recursion. It starts creating the trunk of the tree, then branches splitting up from the trunk at a fixed angle (theta). The larger the angle, the wider the branches split away from the trunk the wider the tree.
- The process repeats for each branch, with sub-branches splitting up from the branches, and so on.
- The size of the branches is proportional to how close they are to the trunk.
import processing.core.PApplet;
public class FractalTree extends PApplet {
static int MAXWIDTH = 800;
static int MAXHEIGHT= 800;
private void draw_tree(int order, // the level of recursion. Starts
// positive.
float theta, // angle of new branch leaving this trunk
float d, // size of this branch
float x, float y, // coordinates of base of this branch
float heading) { // angle of direction of this branch
if ( order <= 0 )
return;
float trunk_ratio = 0.4f; // How big is the trunk relative to whole
// tree?
float trunk = d * trunk_ratio; // length of trunk
// compute x, y of end of the current branch
float delta_x = (float) (trunk * Math.cos( heading ));
float delta_y = (float) (trunk * Math.sin( heading ));
float x2 = x + delta_x;
float y2 = y + delta_y;
// draw current branch
strokeWeight( order+2 );
line( x, y, x2, y2 );
// if this branch has sub-branches, then recurse
// make the recursive calls to draw the two subtrees
float newsz = d * (1 - trunk_ratio);
draw_tree(order - 1, theta, newsz, x2, y2, heading - theta);
draw_tree(order - 1, theta, newsz, x2, y2, heading + theta);
}
public void setup() {
// define the size of the applet
size( MAXWIDTH, MAXHEIGHT );
// make the graphic shapes smooth
smooth();
// make the background white
background( 255, 255, 255 );
// set the angle of branches departing from trunk
float theta = 0.68f; // use 0.02 for tall skinny trees, 0.75 for fat trees
// draw the tree recursivley
draw_tree( 9, theta, MAXWIDTH * 0.7f, (float) MAXWIDTH/2,
(float) MAXHEIGHT-50, - (float) (Math.PI/2) );
}
public void draw() {
// nothing to do iteratively;
}
}
- Question
- Modify the program so that the tree bears oranges at specific, regular, locations, as illustrated below.
- The oranges must be created by the draw_tree() function.
- Reminder: to generate an orange disk at coordinates x, y, with diameter 20, use this code:
fill(204, 102, 0); // set color orange strokeWeight( 1 ); // set weight of line to 1 pixel ellipse( x, y, 20, 20 ); // draw circle of diameter 20
- Make the oranges appear in front of the branches of the tree, so that branches are not drawn over the oranges. See the detail below.