**GM Version**: 2.3.0

**Target Platform**: ALL

**Download**: N/A

**Links**: Formula for Bezier curve, My source code (may drift), Vectors, Vector valued functions, Combinations, Pascal's Triangle and Combinations

**:**

__Summary__A fast bezier curve generator. Takes any amount of focus points and returns a list of points on the curve.

__:__

**Tutorial**Hello! This is the code that I wrote that quickly generates a bezier curve of any degree. The main function is the bezier function. The foci argument is a two dimensional array of the focus points in order: for example, foci=[[0, 0], [1, 1], [0, 1]] would make the function generate a bezier curve with focus points (0, 0), (1, 1), and (0, 1). Sharpness is the amount of line segments that the algorithm will generate: for example, if sharpness is 3, then the function will return a list of 4 points. The return is a list of points on the curve, in the same format as the foci argument. If you're just interested in the code, follow the github link above. Otherwise, here is a quick rundown:

First, check out the first link. It has the explicit definition of a bezier curve. I included a screenshot below for easy access. It's a lot of notation, so let's break it down. Note that 0 <= t <= 1 for this formula

First,

**B**(t). This is a mathematical function like any other, and the

**bold**letter means that it's a vector-valued function. A vector in this case represents an (x, y) point on the plane. If you're not familiar with vectors, check out the third link above. If you're not familiar with VVFs, check out the fourth link above. Basically, it means that it takes in a vector (in this case

**P_**i) and returns a new vector for each value of t.

Now let's go across the equals sign and check out the next fun symbol, the summation sign. This is also known as a capital sigma, or as that funny looking E thing. Essentially, it means "Sum from i = 0 to i = n". It's very similar to a for loop, so it may be helpful to think of it that way. In this case, n is the amount of focus points that are given for the curve.

Next, the weird parentheses. This is a combination operation, it's the same saying as nCi, or n choose i. You may be familiar with this if you've taken a statistics or probability class before. If you're not familiar with them, check out the fifth link above.

Finally, we're in the home stretch. The next two statements are simple exponents and

**P**_i is the ith focus given.

Okay, let's write some code. The hardest thing to write will be the combination, so let's start there. If you know the formula for combinations, you know it involves a lot of factorials, so let's write a quick factorial function. This isn't very technical and there are many ways to do it, but here is my version:

GML:

```
// num >= 0
// Returns num!
function factorial(num) {
var fac = 1;
for(var n = 2; n <= num; n++) {
fac *= n;
}
return fac;
}
```

GML:

```
// Returns a horizontal row from pascal's triangle for coefficient use in bezier curve.
// level 0 = [1]
// level 1 = [1, 1]
// level 2 = [1, 2, 1] and so on
function pascal_vals(level) {}
```

GML:

```
// Returns a horizontal row from pascal's triangle for coefficient use in bezier curve.
// level 0 = [1]
// level 1 = [1, 1]
// level 2 = [1, 2, 1] and so on
function pascal_vals(level) {
var vals = [];
var fac_level = factorial(level)
return vals;
}
```

GML:

```
function pascal_vals(level) {
var vals = [];
var fac_level = factorial(level);
for(var k = 0; k <= level; k++) {
var fac_col = factorial(k);
var fac_opp = factorial(level - k);
vals[k] = fac_level / (fac_col * fac_opp);
}
return vals;
}
```

GML:

```
function pascal_vals(level) {
var vals = [];
var fac_level = factorial(level);
for(var k = 0; k <= level; k++) {
if(k <= level / 2) {
var fac_col = factorial(k);
var fac_opp = factorial(level - k);
vals[k] = fac_level / (fac_col * fac_opp);
} else {
vals[k] = vals[level - k];
}
}
return vals;
}
```

GML:

```
// foci is a list of px points, sharpness is the integer amount of line segments generated (num points generated - 1).
// Returns a list of points in format [[x1, y1], [x2, y2], ... , [xn, yn]]
function bezier(foci, sharpness){
var points = [];
var num_foci = array_length(foci);
var coeffs = pascal_vals(num_foci - 1);
return points;
}
```

GML:

```
function bezier(foci, sharpness){
var points = [];
var num_foci = array_length(foci);
var coeffs = pascal_vals(num_foci - 1);
for(var i = 0; i <= sharpness; i++) {}
return points;
}
```

GML:

```
function bezier(foci, sharpness){
var points = [];
var num_foci = array_length(foci);
var coeffs = pascal_vals(num_foci - 1);
for(var i = 0; i <= sharpness; i++) {
var t = i / sharpness;
var u = 1 - t;
points[i] = [0, 0];
}
return points;
}
```

GML:

```
function bezier(foci, sharpness){
var points = [];
var num_foci = array_length(foci);
var coeffs = pascal_vals(num_foci - 1);
for(var i = 0; i <= sharpness; i++) {
var t = i / sharpness;
var u = 1 - t;
points[i] = [0, 0];
for(var j = 0; j < num_foci; j++) {
var coefficient = coeffs[j] * power(t, j) * power(u, num_foci - j - 1);
points[i][0] += coefficient * foci[j][0];
points[i][1] += coefficient * foci[j][1];
}
}
return points;
}
```