Você está na página 1de 5

Tutorial Processing: bezierVertex, class, mouse actions,

rotate
Classes can be used to re-use codeto do similar things in slightly different ways. The
use of classes to implement buttons described in another tutorial on this page makes more
use of classes than this example. In particular, the MButton class puts together data and
procedures. However, these very simple examples may be instructive.

In the first sketch, clicking on the display screen produces a flower-shape. The color
varies randomly among red, yellow, blue and mauve. The number of petals varies
between 3 and 7.

The coding consists of definitions for setup, draw and mousePressed plus the definition
of a class called Flower.

The setup definition is fairly standard


void setup()
{
size (600,400);
background(255);
}

The draw method is empty BUT it is necessary. If you omit it, the mousePressed action
does not happen.
void draw () {
}

Before showing the mousePressed definition, I explain the Flower class. This is because
mousePressed will contain a call to Flower.

A class definition can include variables and multiple methods. This class just has one
method, the so-called constructor method. [Again, see the other tutorials for examples
that more fully demonstrate the power of classes.] This method is the one with the same
name as the class.

In this example, the Flower method first does a translation to the x and y positions
specified by the first two parameters. It then has a loop based on the number of petals as
specified by the last parameter. In the loop, rotate is called with value based on a
calculation using the number of petals. The input to rotate is in radians, there are 2*PI
radians for a full circle, so my code divides 2*PI by the number of petals to determine the
amount of rotation for each petal. Keep in mind that rotations are cumulative, so each call
to rotate means that much more rotation. Each petal is produced using the beginShape
and endShape facility [See the draw Bezier curve example.] Within the beginShape and
the endShape, the code invokes a vertex and then bezierVertex. The parameters for the
vertex call are 0,0. This makes sense because the coordinate system has been translated
already based on the sx and sy parameters to Flower. Bezier curves are based on anchor
points and control points. In this case, the first anchor point is set by the call to vertex.
The call to bezierVertex sets 2 control points and the ending anchor point, 3,3, just a few
pixels over from 0,0. Experiment with the values for different shapes. The last thing done
in the Flower method is a translate that undoes the effects of the first call to translate.

class Flower {

Flower (float sx, float sy, float wdx, float wdy, int npetals) {

translate(sx,sy);
for (int p=0; p<=npetals; p++) {
rotate (2*PI/npetals);
beginShape();
vertex(0,0);
bezierVertex(wdx,-wdy, 2*wdx, 3*wdy, 3,3);
endShape();
}
translate(-sx,-sy);
}
}

There are many ways to get random colors, for example calling on random to set each of
the red, green and blue values. I take another approach here. To avoid what I see as
muddy colors, I decide on 4 sets of RGB values and assign the corresponding ones to 3
arrays and set them up in global variables:

int[] rcols = {250,250,255,0};


int[] gcols = {0,0,255,0};
int[] bcols = {0,100,0,250};

So, if the code uses an index value of 0 for each of these arrays, the color 250,0,0 is used,
producing a bright red. If the code uses an index value of 3, the color 0,0,250 is used for a
bright blue.

Now the definition of mousePressed can be given. Before making the call to Flower, my
code generates an index into the 3 color arrays. This is done using random and then int.
Similarly, the code calls random and int again to get a random number held in variable np
for the number of petals. Having set the fill, the code invokes Flower using the mouse
coordinates, fixed numbers for the x and y values that control the shape of the curve, and
np.

void mousePressed() {
int nc = int(random(4));

fill(rcols[nc],gcols[nc],bcols[nc]);
int np = int(random(3,8));
Flower f = new Flower(mouseX,mouseY,40,50,np);

An improvement to this code would be to substitute the 4 in the first statement with code
that references the length of the color arrays:
int nc = int(random(rcols.length));

Of course, it is up to the programmer to make sure that all 3 arrays have the same length.

The second sketch provides a way to make the user/player control the size of the flowers.
I also tried a new way to get the different colors. This sketch also demonstrates
successive calls to bezierVertex for more complicated curves. The player pressed down
on the mouse, drags and then releases to produce different sized flowers.
For this sketch, the setup and the draw are the same as before. There are 2 global
variables:

int firstmousex;
int firstmousey;

The mousePressed method sets these two values:

void mousePressed() {
firstmousex = mouseX;
firstmousey = mouseY;
}

The mouseReleased method is more like the mousePressed in the first sketch. To set the
colors, I use a nested if statement. The intent is to set the colors to be reddish 35% of the
time, and for the rest, set it to shades of purple half the time and shades of yellow/orange,
the rest. I'm not sure I quite achieved that effect, but that was my intent. Setting np, the
number of petals variable is as before, but I made it 3 through 9 by making the call
random(3,10). The middle variables, called wdx and wdy in the code, are set by taking
the differences of the current mouse variables with the ones stored in the global variables.

void mouseReleased() {

if (random(1)<.35) {
fill(random(200,255),0,0);}
else if (random(1)<.5) {
fill(random(150,255),0,random(200,255));
}
else {
fill(random(200,255), random(200,255), 0);}
int np = int(random(3,10));
int wdx = mouseX-firstmousex;
int wdy = mouseY-firstmousey;
Flower f = new Flower(firstmousex,firstmousey,wdx,wdy,np);

The Flower class is pretty much as before except I added a bezierVertex line.

class Flower {

Flower (float sx, float sy, float wdx, float wdy, int npetals) {

translate(sx,sy);
for (int p=0; p<=npetals; p++) {
rotate (2*PI/npetals);
beginShape();
vertex(0,0);
bezierVertex(wdx,-2*wdy, 2*wdx, -1*wdy, 3*wdx,1*wdy);
bezierVertex(2*wdx,2*wdy, -1*wdx, -1*wdy, 3,3);
endShape();
}
translate(-sx,-sy);
}
}

Feel free to experiment yourself!

Você também pode gostar