## Draw a Triangle on the Screen, Part I

This function draws a triangle on the screen. It becomes the core of an applet that allows the user to pick the three endpoints by clicking three times on the screen, which will be completed in the next example.

The algorithm assumes that the three points are ordered by x coordinate. It fills the triangle by drawing a series of vertical lines, 1 pixel wide. To do this, it splits the triangle into a "left" and "right" half; that is, the part from the x coordinate of the first point to the x coordinate of the second point, and the part from the x coordinate of the second point to the x coordinate of the third point. This algorithm won't work well with triangles that are extremely tall and thin, so to cover those cases, the function also draws a line between each pair of endpoints.

Applets draw to the screen by overriding a member method called
`paint()`. This method is passed a `Graphics` class, which
supports two methods that are used here: `fillOval()` (used to draw a
circle) and `drawLine()`. The meaning of the parameters can be inferred
from their use (assume that they are passed in the correct order).

In the declaration of the `Triangle` class, it specifies that it
implements the `MouseListener` interface. This is explained in the next
program.

### Source Code

1.import java.awt.event.*;2.import java.awt.*;3.4.public class Triangle extends java.applet.Applet5.implements MouseListener {6.7.// The rest of the applet will be in the next8.// example.9.10.Point[] pt = new Point[3];11.int ptCount = 0;12.13.public void paint(Graphics g) {14.15.int i;16.17.// Draw the points that have been selected18.19.for (i = 0; i < ptCount; i++) {20.g.fillOval(pt[i].x - 10, pt[i].y - 10,21.20, 20);22.}23.24.if (ptCount == 3) {25.26.// Connect the endpoints to handle27.// tall thin triangles.28.29.g.drawLine(pt[0].x, pt[0].y,30.pt[1].x, pt[1].y);31.g.drawLine(pt[1].x, pt[1].y,32.pt[2].x, pt[2].y);33.g.drawLine(pt[0].x, pt[0].y,34.pt[2].x, pt[2].y);35.36.// Calculate x and y diffs between points.37.38.int x0to1 = pt[1].x - pt[0].x;39.int x0to2 = pt[2].x - pt[0].x;40.int x1to2 = pt[2].x - pt[1].x;41.int y0to1 = pt[1].y - pt[0].y;42.int y0to2 = pt[2].y - pt[0].y;43.int y1to2 = pt[2].y - pt[1].y;44.45.// Left part of the triangle.46.47.if (x0to1 > 0) {48.for (i = pt[0].x; i <= pt[1].x; i++) {49.g.drawLine(50.i,51.pt[0].y +52.((y0to1 * (i - pt[0].x)) / x0to1),53.i,54.pt[0].y +55.((y0to2 * (i - pt[0].x)) / x0to2)56.);57.}58.}59.60.// Right part of the triangle.61.62.for (i = pt[1].x+1; i <= pt[2].x; i++) {63.g.drawLine(64.i,65.pt[1].y +66.((y1to2 * (i - pt[1].x)) / x1to2),67.i,68.pt[1].y +69.((y0to2 * (i - pt[0].x)) / x0to2)70.);71.}72.}73.}74.}

### Suggestions

There are several places with repetitive statements, such as lines 29–34 and 38–43. Check these lines carefully to ensure that they are correct.

Although the points are ordered by x coordinate, it's possible that two or three of them will have the same x coordinate. As a result,

`x0to1`,`x0to2`, or`x1to2`could be`0`. Examine the code to ensure that the division operations on lines 52, 55, 66, and 69 would never result in an`ArithmeticException`due to divide by zero.Look at the loops on lines 48–57 and lines 62–71. Determine what values will be passed to

`g.drawLine()`on the first and last iteration of each of these loops to make sure that they seem reasonable. Remember how the values are related; for example, the expression`pt[0].y + y0to1`is equal to`pt[1].y`.

### Hints

Walk through the function with `ptCount == 3` and the points as
follows:

- A triangle with nothing unusual:
pt[0].x == 0; pt[0].y == 20; pt[1].x == 2; pt[1].y == 18; pt[2].x == 4; pt[2].y == 28;

- A triangle with points that are the same in the x or y
coordinate:
pt[0].x == 0; pt[0].y == 10; pt[1].x == 4; pt[1].y == 10; pt[2].x == 4; pt[2].y == 0;

### Explanation of the Bug

A **B.variable** error exists in the calculation of the second y
coordinate in the call to `g.drawLine()` in the second loop. Lines
68–69, which read as follows

pt[1].y + ((y0to2 * (i - pt[0].x)) / x0to2)

should be

pt[0].y + ((y0to2 * (i - pt[0].x)) / x0to2)

The problem can be spotted by considering the last iteration of the loop,
when `i` is equal to `pt[2].x`. In this situation, the expression
as initially written becomes

pt[1].y + ((y0to2 * (pt[2].x - pt[0].x)) / x0to2)

which, because `pt[2].x – pt[0].x` is equal to `x0to2`,
becomes

pt[1].y + y0to2

This does not make any particular sense because `pt[1].y` and
`y0to2` are not related. With the fix, the expression is instead

pt[0].y + y0to2

This equals `pt[2].y`, a reasonable y coordinate for the second
endpoint of the last vertical line (in fact, the y coordinate of the first
endpoint of the line also evaluates to `pt[2].y`, so the "line"
is actually just a single pixel drawn at the point `pt[2]`).