# How to add a point to a Cubic Bézier Curve In SVG

#### The anatomy of a cubic Bézier curve in SVG

To draw a cubic Bézier curve you need 4 points:
The point where the curve begins (**start**), two control points **cp1** and **cp2** and an ending point (**end**). Usually, the curve do not pass through the points **cp1** or **cp2**. These points are there only to provide directional information.

In my code, in JavaScript there is an array of points that defines a cubic Bézier curve. The first element of the array is the **start** point, the second element is the **cp1**, the third is the **cp2** and the last is the **end** point:

` ````
let points = [
[25,220], // start
[75,70], // cp1
[170,25], // cp2
[225,210] // end
];
```

In SVG you will code the curve like this:

` ````
<path d="M25,220 C75,70 170,25 225,210" ></path>
```

You have to use first the "Move To" command to move the pointer to the point where the curve begins.

<path d="M25,220 C75,70 170,25 225,210" ></path>

Next you use the "Cubic Curve" command (`C`

) to draw the curve and then you need to specify three sets of coordinates: for the control points and for the end point.

<path d="M25,220 C75,70 170,25 225,210" ></path>

#### How to find a point on a cubic Bézier

Let's say you want to find a point in the middle of the Bézier curve:

` ````
let t = .5;
```

For this you will need some helper points:

` ````
let helperPoints = [];
```

To get the helper points you will need a function that calculates the position of a point on a line. Imagine a virtual line that goes from point A to point B. ( In my code the points A and B are arrays where the first element is the x and the second element is the y coordinate of the point.)

` ````
function lerp(A, B, t) {
// A and B are arrays where the first element is the x
// and the second element is the y coordinate of the point
// if(t == .5) the function returns a point in the center of the line AB
// t is always a number between 0 and 1
// 0 <= t <= 1
return [
(B[0] - A[0]) * t + A[0], // the x coordinate
(B[1] - A[1]) * t + A[1] // the y coordinate
];
}
```

This function returns an array of 2 elements with the coordinates x and y of a point.

#### The helper points

In the next pen, the helper points are the orange ones:

The first helper point is in the middle of the virtual line that goes from **start** to the first control point **cp1**.

` ````
helperPoints[0] = lerp(points[0], points[1], t);
```

The second helper point is in the middle of the virtual line that goes from first control point **cp1** to the second control point **cp2**:

` ````
helperPoints[1] = lerp(points[1], points[2], t);
```

The third helper point is in the middle of the virtual line that goes from **cp2** to **end**:

` ````
helperPoints[2] = lerp(points[3], points[3], t);
```

The forth helper point is in the middle of the virtual line that goes from `helperPoints[0]`

to `helperPoints[1]`

.

` ````
helperPoints[3] = lerp(helperPoints[0], helperPoints[1], t);
```

The fifth helper point is in the middle of the virtual line that goes from `helperPoints[1]`

to `helperPoints[2]`

.

` ````
helperPoints[4] = lerp(helperPoints[1], helperPoints[2], t);
```

Finally (sorry if it was borring), the point in the middle of the Bézier curve, the fuchsia point, is the one in the middle of the virtual line that goes from `helperPoints[3]`

to `helperPoints[4]`

` ````
helperPoints[5] = lerp(helperPoints[3], helperPoints[4], t);
```

All this was calculated with `t = .5`

for the middle point. But the variable `t`

can take any other value between 0 and 1, between the beginning and the end of the Bézier curve.

In the following pen please move the cursor of the slider to change the value of the variable `t`

.

#### Add a point to an SVG path using javascript

Now suppose you have cubic Bézier curve, and you need to add a point to it without changing the shape. By "adding a point to a Bézier curve" I mean taking a Bezier curve and code it as 2 curves. For example this curve:

` ````
<path d="M25,220 C75,70 170,25 225,210" ></path>
```

can be rewritten like this:

` ````
<path d="M25,220 C32.5,197.5 41.0125,177.3625 50.25,160" ></path>
<path d="M50.25,160 C102.6,61.675 178.25,52.75 225,210" ></path>
```

or like this:

` ````
<path d="M25,220
C32.5,197.5 41.0125,177.3625 50.25,160
C102.6,61.675 178.25,52.75 225,210" ></path>
```

In order to do it you have to take advantage of the helper points.

As it comes out, the first Bézier curve begins at the **start** point ( `points[0]`

).

The control points for the first curve are `helperPoints[0]`

and `helperPoints[3]`

.

The end point for the first curve is the fuchsia point: `helperPoints[5]`

.

The second Bézier curve begins at the fuchsia point: `helperPoints[5]`

.

The control points for the second curve are `helperPoints[4]`

and `helperPoints[2]`

.

The end point for the second curve is the **end** point of the "parent" curve: `points[3]`

.

I've putted all this in a function:

` ````
function getBezierPoints(t) {
let helperPoints = [];
// helper points 0,1,2
for (let i = 1; i < 4; i++) {
//points.length must be 4 !!!
let p = lerp(points[i - 1], points[i], t);
helperPoints.push(p);
}
// helper points 3,4
helperPoints.push(lerp(helperPoints[0], helperPoints[1], t));
helperPoints.push(lerp(helperPoints[1], helperPoints[2], t));
// helper point 5 is where the first Bézier ends and where the second Bézier begins
helperPoints.push(lerp(helperPoints[3], helperPoints[4], t));
// points for the 2 "child" curves
let firstBezier = [
points[0],
helperPoints[0],
helperPoints[3],
helperPoints[5]
];
let secondBezier = [
helperPoints[5],
helperPoints[4],
helperPoints[2],
points[3]
];
// returns 2 array of points for the new bezier curves
return [firstBezier, secondBezier];
}
```

In the next pen I'm using this function to draw 2 Bézier curves instead of one. In the following pen please move the cursor of the slider to change the value of the variable `t`

.

#### Where would you use this?

For example when you intent to morph one SVG shape into another, you need two shapes with the same number of points. If your shapes have a different number of points, being able to add points on a curve may come in handy.

*I've written a post about Morphing in SVG - first steps and an other one about how to Prepare The Paths For Morphing*