In these notes you will learn:

- How to represent (x, y) points using a single
`ArrayList<Point>`container. - How
`null`can be used with objects.

Lets write a program that draws a dot wherever the user clicks on the screen. Between each dot a line is drawn so that we can see the path of the clicks.

Note

Drawing connected points and lines turns out to be fairly common, and so Processing provides some built-in functions to do it for you: see the documentation for beginShape if you are curious.

Lets spend a moment thinking about the overall structure and operation of our program. Whenever we click on the screen lets have a red dot appear at the click point that is connected by a straight line to the point just before the current one.

If we keep track of the positions of all the click-points, then we can draw
the lines between them using the Processing `line` function.

So this suggests that we ought to use objects to store our (x, y) points. Lets
call the class that will create these objects `Point`:

```
class Point {
float x, y;
// constructor
Point(float a, float b) {
x = a;
y = b;
}
} // class Point
```

Now we can make `Point` objects like this:

```
Point a = new Point(0, 0); // a is (0, 0)
Point b = new Point(-2, 5); // a is (-2, 5)
```

To store multiple `Point` objects, we can use an `ArrayList`:

```
ArrayList<Point> points = new ArrayList<Point>();
```

Initially, `points` is empty, and we can add `Point`s to it like
this:

```
Point a = new Point(0, 0); // a is (0, 0)
Point b = new Point(-2, 5); // a is (-2, 5)
points.add(a);
points.add(b);
```

Points can be added directly without first creating a variable, e.g.:

```
points.add(new Point(8, 3)); // (8, 3) added to Points
points.add(new Point(0, 1)); // (0, 1) added to Points
```

With the `Point` class in hand, lets now write a high-level sketch of the
entire program:

```
ArrayList<Point> points; // initially has the value null
void setup() {
size(500, 500);
smooth();
points = new ArrayList<Point>(); // makes an empty ArrayList of Points
}
void draw() {
background(255);
// draw all the lines
// draw all the points (on top of the lines)
}
void mousePressed() {
// add (mouseX, mouseY) to points
}
```

By using comments like this, we can see the overall structure of our program without yet needing to worry about the low-level details. The next step is to replace those comments with Processing code.

Probably the easiest thing to do first is to fill in `mousePressed`:

```
void mousePressed() {
// add (mouseX, mouseY) to points
}
```

Adding (`mouseX`, `mouseY`) to `points` requires first creating a
`Point` objects, and then adding it to `points` with the `add`
function:

```
void mousePressed() {
Point p = new Point(mouseX, mouseY);
points.add(p);
}
```

Next, lets write the code for drawing all the points. This is not too hard:

```
void draw() {
background(255);
// draw all the lines
// draw all the points (on top of the lines)
for (Point p : points) {
fill(255, 0, 0);
noStroke();
ellipse(p.x, p.y, 10, 10);
}
}
```

We’ve used a for-each loop to run the code between the `{` `}` on each
`Point` object in `points` (using the variable `p` to refer to the
current object). You can read this for-each loop in English like this: “For
each Point p in points, do the following ...”.

Next, we need to draw the lines between the dots. The idea is to draw a line
between each pair of *adjacent* points, where adjacent refers to the order in
which the points were clicked on the screen. Fortunately, a for-each loop will
process the points in `points` in the order they were added

So what we can do is use a for-each loop to access every point in `points`:

```
for(Point p : points) {
// ... do something ...
}
```

Here, `p` refers to the *current* point. But to draw a line we need two
points, and so we’re going to add a new `Point` variable called `prev`
that will always refer to the point that was clicked just before `p`:

```
Point prev;
for(Point p : points) {
line(p.x, p.y, prev.x, prev.y);
prev = p; // make p refer to the same Point p refers to
}
```

This *almost* works, but their is actually major problem: `prev` has not
been given an initial value.

Handling the initial value for `prev` correctly turns out to be the
trickiest part of this program (at least for our particular solution). Since
the first point of `points` has no previous value, there is no previous
point to assign to `prev`.

So what we will do is assign `null` to `prev`. Recall that `null` is a
special value that is used with object variables to indicate they are not
referring to any object (yet). That makes sense here: there’s is no point
before the first one.

Here’s the next draft:

```
Point prev = null;
for(Point p : points) {
line(p.x, p.y, prev.x, prev.y);
prev = p; // make p refer to the same Point p refers to
}
```

Unfortunately, this doesn’t work. When `prev` has the value `null`, you
can’t call `prev.x` and `prev.y` because `null` doesn’t have an `x` or
`y` value. So we’re going to have to check to see if `prev` is `null`
before drawing a line:

```
Point prev = null;
for (Point p : points) {
if (prev == null) {
prev = p;
} else {
stroke(0);
line(prev.x, prev.y, p.x, p.y);
prev = p;
}
}
```

The only time `prev` is `null` is for the first value of `p` in the
loop. That makes sense: there is no line to draw when have only a single
point. So when `prev` is `null`, we don’t draw a line and just set `prev
= p`.

For the rest of the points in `points`, `prev` will not be `null`, and
so we do draw the line (and also set `prev` to `p`).

As a fun example, lets write a new program that is a variation of the above one that allows the points to fall down and bounce on the bottom of the screen. While not terribly practical, it is a nice-looking effect that might give you ideas for other kinds of animation.

We want this new program to work just like the previous one, except that when you press any key suddenly gravity is turned on and the dots all begin to fall downwards.

We saw in *earlier notes* how to make a ball fall down
and bounce on the screen. The basic idea is add two new variables:
`gravity`, to control how fast the ball falls downwards, and `elasticity`
to control how high it bounces:

```
// ...
float gravity;
float elasticity;
void setup() {
// ...
gravity = 0;
elasticity = 0;
}
```

These variables are both initially 0 because we don’t want the dots to move until a key pressed:

```
void keyPressed() {
gravity = 0.1;
elasticity = 0.8;
}
```

`keyPressed` is automatically called whenever the user presses a key on the
keyboard. The particular values for `gravity` and `elasticity` were chosen
after some experimentation — feel free to change them to get different
effects.

Since our points are now going to move, we’re also going to need to add `dx`
and `dy` to `Point`:

```
class Point {
float x, y;
float dx, dy;
// constructor
Point(float a, float b) {
x = a;
y = b;
dx = 0;
dy = 0;
}
} // class Point
```

Finally, we need to modify `draw()` to change the position of the points:

```
void draw() {
// ...
// update the dot positions
for(Point p : points) {
p.x += p.dx; // move the point
p.y += p.dy;
p.dy += gravity; // increase acceleration according to gravity
if (p.y >= 500) { // check if ball has hit the bottom edge
p.dy = -(p.dy * elasticity);
p.y = 499;
}
}
}
```

This is very similar to what we did in the *earlier notes on gravity*. The main difference is that we are applying gravity to
*every* object in an `ArrayList`.

```
class Point {
float x, y;
// constructor
Point(float a, float b) {
x = a;
y = b;
}
} // class Point
ArrayList<Point> points;
void setup() {
size(500, 500);
smooth();
points = new ArrayList<Point>();
}
void draw() {
background(255);
// draw the lines
Point prev = null;
for (Point p : points) {
if (prev == null) {
prev = p;
} else {
stroke(0);
line(prev.x, prev.y, p.x, p.y);
prev = p;
}
}
// draw the points
for (Point p : points) {
fill(255, 0, 0);
noStroke();
ellipse(p.x, p.y, 10, 10);
}
} // draw
void mousePressed() {
Point p = new Point(mouseX, mouseY);
points.add(p);
}
```

```
class Point {
float x;
float y;
float dx;
float dy;
// constructor
Point(float a, float b) {
x = a;
y = b;
dx = 0;
dy = 0;
}
} // class Point
ArrayList<Point> points; // initially null
float gravity;
float elasticity;
void setup() {
size(500, 500);
smooth();
points = new ArrayList<Point>();
gravity = 0;
elasticity = 0;
}
void draw() {
background(255);
// draw the lines
Point prev = null;
for (Point p : points) {
if (prev == null) {
prev = p;
}
else {
stroke(0);
line(prev.x, prev.y, p.x, p.y);
prev = p;
}
}
// draw the points
for (Point p : points) {
fill(255, 0, 0);
noStroke();
ellipse(p.x, p.y, 10, 10);
}
// update the dot positions
for (Point p : points) {
p.x += p.dx; // move the point
p.y += p.dy;
p.dy += gravity; // increase acceleration according to gravity
if (p.y >= 500) { // check if ball has hit the bottom edge
p.dy = -(p.dy * elasticity);
p.y = 499;
}
}
} // draw
void mousePressed() {
Point p = new Point(mouseX, mouseY);
points.add(p);
}
void keyPressed() {
gravity = 0.1;
elasticity = 0.8;
}
```