## Creating string art parabolic curves in Processing

One of the fascinating things about string art is how straight lines can appear to form various curves. The simplest examples are parabolic curves (aka quadratic curves). These can be described by an equation of the form:

```
y = a*x^2
```

## How it works

To create a parabolic curve using pins and thread, we first create two lines of pins, equally spaced. In the picture we have created a horizontal lines of pins (numbered 1 to 5), and s second vertical line of pins (also numbered 1 to 5).

To create the curve, we join horizontal pin 1 to vertical pin 5, pin 2 to pin 4, pin 3 to pin 3 etc. In other words, we work along the horizontal row from start in increasing order, and work along the vertical row from the end in decreasing order, joining the pairs of pins.

## Example

We will look at an example first, then look at the code used to create it.

## The code

To draw the shape above, we need to write a couple of functions:

`linePoints`

creates a line of (x, y) points`joinPoints`

takes two lines of points and joins each pair of points with a line

### linePoints

Here is the code:

```
PVector[] linePoints(float ax, float ay, float bx, float by, int count)
{
PVector[] points = new PVector[count];
for (int i = 0; i < count; i++)
{
float x = ax + (bx - ax)*i/(count -1);
float y = ay + (by - ay)*i/(count -1);
points[i] = new PVector(x, y);
}
return points;
}
```

This takes five parameters:

- the start point
`(ax, ay)`

- the end point
`(bx, by)`

`count`

- the total number of points

We will use the Processing class `PVector`

to represent the points (or pins) in the image. A `PVector`

stores an `x`

and a `y`

value.

In the code, first we create an array of `PVector`

items, of length `count`

. We then loop `count`

times, calculating the `x`

and `y`

values for each point. We create a new `PVector`

and place it in the array.

Finally we return the full array of points.

Notice that the calculation ensures that the first and last point are in the correct positions, with the other points equally spaced between then. Whatever values you choose for the start and end points, the remaining points will be equally distributed between them.

### joinPoints

Here is the code:

```
void joinPoints(PVector[] p1, PVector[] p2)
{
int count = p1.length;
for (int i = 0; i < count; i++)
{
line(p1[i].x, p1[i].y, p2[i].x, p2[i].y);
}
}
```

This function accepts two lists of points, `p1`

and `p2`

. It draws a line from the first point in `p1`

to the first point in `p2`

, then draws a line from the second point in `p1`

to the second point in `p2`

, and so on.

### Main draw function

Here is the main `draw`

function:

```
void draw()
{
clear();
background(255);
noFill();
strokeWeight(1);
stroke(255, 0, 0);
PVector[] p1 = linePoints(50, 50, 550, 50, 30);
PVector[] p2 = linePoints(50, 550, 50, 50, 30);
joinPoints(p1, p2);
}
```

The corner of the image is at (50, 50).

We create `p1`

, list of 30 points on a horizontal line from (50, 50) to (550, 50).

We then create `p2`

, list of 30 points on a vertical line from (50, 550) back to (50, 50). This line is going in the opposite direct to the first line - it ends (50, 50) whereas the first line starts at (50, 50).

Finally we use `joinPoints`

to join the points in the two lists.