This post deals with implementing an evenly curved line using SVG and
JavaScript. SVG supports quadratic and cubic bezier curves using the `C`

, `S`

and `Q`

path commands but those leave you with the calculation of the control
points.

## Calculating the control points

To obtain a consistent and even curve one needs to place the control points like the following figure illustrates.

Given are the outer control points *A* and *D*, as the line starting and ending
points, as well as the curviness expressed by the degree *a*.

```
function curvedLine(Ax, Ay, Dx, Dy, a) {
```

*d* is the calculated distance between the outer control points.

```
const d = Math.sqrt(Math.pow(Ax-Dx, 2) + Math.pow(Ay-Dy, 2));
```

*rad* is the radian measure of the degree *a*.

```
const rad = a / 180.0 * 2.0 * Math.PI;
```

*r* is the distance from the outer to the inner control points.

```
const r = (0.3 * d) / Math.cos(rad);
```

*theta* is the calculated angle of the line passing through both outer control
points in radian.

```
const theta = Math.atan2(Ay - Dy, Ax - Dx);
```

*aO* and *aD* are two angles in radian that are required to calculate the inner
control points.

```
const aO = theta - rad + Math.PI,
aD = theta + rad;
```

The inner control points *B* and *C*, respectively, are calculated based on the
line connecting the outer control points using the angle *a* and *r* as illustrated in the figure.

```
const Bx = Ax + r*Math.cos(aO),
By = Ay + r*Math.sin(aO),
Cx = Dx + r*Math.cos(aD),
Cy = Dy + r*Math.sin(aD);
```

Last but not least, the SVG path is built from the control points.

```
return `M${Ax},${Ay} C${Bx},${By} ${Cx},${Cy} ${Dx},${Dy}`
}
```

## Using the function

You can use an SVG library like D3.js to use the function result in an SVG path.

```
let svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 200);
svg.append('path')
.attr('stroke', '#000')
.attr('fill', 'none')
.attr('d', curvedLine(30, 160, 470, 160, 20));
```