diff --git a/Main.cpp b/Main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8cd88549e46e520ed4bda6da171999bc59d39e3c
--- /dev/null
+++ b/Main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+int main(void)
+{
+    for (double i{0}; i < 1; i += 0.1)
+    {
+        std::cout << i << ", " << i * i << std::endl;
+    }
+}
\ No newline at end of file
diff --git a/Main.exe b/Main.exe
new file mode 100644
index 0000000000000000000000000000000000000000..f5db5197ebcace1de7c5f69736fc43a7ea4c3d11
Binary files /dev/null and b/Main.exe differ
diff --git a/Main.obj b/Main.obj
new file mode 100644
index 0000000000000000000000000000000000000000..8d5677a173b968ede47ecb0936090869b70444f4
Binary files /dev/null and b/Main.obj differ
diff --git a/src/main.ts b/src/main.ts
index 02481fb426df2cb6cf13f1c27f9d282ee26df86c..502c7c2bcd8d26ab77384ab47577007b509a3c2b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,29 +1,29 @@
 import * as CG from "./uitls/rendering";
 import * as THREE from "three";
 import { UI } from "./uitls/ui";
-import { Vector3 } from "three";
 import * as Interpolation from "./uitls/bezierCurve";
 
 const render = new CG.RenderManager('#canvas', { near: 0.1, far: 1000, fov: 45, height: 1 });
 const ui = new UI();
 
-// create a cube
-let geometry = new THREE.BoxGeometry(1, 1, 1);
-let material = new THREE.MeshBasicMaterial({ color: 0xfffffff });
-let cube = new THREE.Mesh(geometry, material);
-// render.add(cube);
-
 const startPoint = new THREE.Vector2(-1, -1);
 const endPoint = new THREE.Vector2(1, 1);
 const startControlPoint = new THREE.Vector2(-1, 1);
 const endControlPoint = new THREE.Vector2(1, -1);
 
-const curve = new Interpolation.BezierCurveTest(
+// const curve = new Interpolation.BezierCurveTest(
+//   startPoint,
+//   startControlPoint,
+//   endControlPoint,
+//   endPoint
+// )
+const curve = new Interpolation.BezierCurve(
   startPoint,
   endPoint,
   startControlPoint,
   endControlPoint
 )
+
 const line = curve.createLine();
 
 render.add(line);
diff --git a/src/uitls/bezierCurve.ts b/src/uitls/bezierCurve.ts
index bb9c912fe583281309828f3136dd7a8a3d39ee40..40465d9a8f4529e9deb26a865fce99253cc326c2 100644
--- a/src/uitls/bezierCurve.ts
+++ b/src/uitls/bezierCurve.ts
@@ -9,13 +9,17 @@ import {
 } from "three";
 import { GUI } from "dat.gui";
 
+function lerp(a: Vector2, b: Vector2, t: number): Vector2 {
+    return new Vector2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
+}
+
 
 export abstract class AbstractBezierCurve implements Modifiable, Updatable {
     constructor(startPoint: Vector2, endPoint: Vector2, startControlPoint: Vector2, endControlPoint: Vector2) {
-        this._startPoint = startPoint;
-        this._endPoint = endPoint;
-        this._startControlPoint = startControlPoint;
-        this._endControlPoint = endControlPoint;
+        this.startPoint = startPoint;
+        this.endPoint = endPoint;
+        this.startControlPoint = startControlPoint;
+        this.endControlPoint = endControlPoint;
 
         this._geomBuffer = new BufferGeometry();
     }
@@ -44,22 +48,24 @@ export abstract class AbstractBezierCurve implements Modifiable, Updatable {
 
     createElement(gui: GUI): void {
         const folder = gui.addFolder('Bezier Curve');
-        UI.addVector(folder, this, this._startPoint, 'Start Point');
-        UI.addVector(folder, this, this._endPoint, 'End Point');
-        UI.addVector(folder, this, this._startControlPoint, 'Start Control Point');
-        UI.addVector(folder, this, this._endControlPoint, 'End Control Point');
+        UI.addVector(folder, this, this.startPoint, 'Start Point');
+        UI.addVector(folder, this, this.endPoint, 'End Point');
+        UI.addVector(folder, this, this.startControlPoint, 'Start Control Point');
+        UI.addVector(folder, this, this.endControlPoint, 'End Control Point');
         folder.add(this, "_numPoints", 10, 100).step(1).name("Points").onChange(() => { this.update(); });
 
     }
 
-    public _startPoint: Vector2;
-    public _endPoint: Vector2;
-    public _startControlPoint: Vector2;
-    public _endControlPoint: Vector2;
-    public _numPoints: number = 100;
-    public _line?: Line;
-    public _curvePoints: Vector2[] = [];
-    public _geomBuffer: BufferGeometry;
+    public startPoint: Vector2;
+    public endPoint: Vector2;
+    public startControlPoint: Vector2;
+    public endControlPoint: Vector2;
+
+    protected _numPoints: number = 100;
+
+    private _line?: Line;
+    private _curvePoints: Vector2[] = [];
+    private _geomBuffer: BufferGeometry;
 }
 
 // TODO: Handles for the control points
@@ -81,16 +87,16 @@ export class BezierCurveTest extends AbstractBezierCurve {
 
     generateCurvePoints(): Vector2[] {
         const curve = new CubicBezierCurve3(
-          new Vector3(this._startPoint.x, this._startPoint.y, 0),
-          new Vector3(this._startControlPoint.x, this._startControlPoint.y, 0),
-          new Vector3(this._endPoint.x, this._endPoint.y, 0),
-          new Vector3(this._endControlPoint.x, this._endControlPoint.y, 0)
+            new Vector3(this.startPoint.x, this.startPoint.y, 0),
+            new Vector3(this.startControlPoint.x, this.startControlPoint.y, 0),
+            new Vector3(this.endPoint.x, this.endPoint.y, 0),
+            new Vector3(this.endControlPoint.x, this.endControlPoint.y, 0)
         );
-    
+
         let curvePoints: Vector2[] = [];
 
         curve.getPoints(this._numPoints).forEach(point => {
-          curvePoints.push(new Vector2(point.x, point.y));
+            curvePoints.push(new Vector2(point.x, point.y));
         });
 
         return curvePoints;
@@ -99,12 +105,79 @@ export class BezierCurveTest extends AbstractBezierCurve {
 
 
 export class BezierCurve extends AbstractBezierCurve {
-    
-        generateCurvePoints(): Vector2[] {
-            let curvePoints: Vector2[] = [];
-    
-            // TODO: implement bezier curves
 
-            return curvePoints;
+
+    bernstain(s: number): [Vector2, number[]] {
+
+        // p(t) = (1-t)³ * p0 + 3 * (1-t)² * t * p1 + 
+        //        3 * (1-t) * t² * p2 + t³ * p3
+        // => subtitute: 1 - t = s
+        // p(t) = k³ * p0 + 3 * k² * t * p1 + 
+        //        3 * k * t² * p2 + t³ * p3
+
+        const p0 = this.startPoint;
+        const p1 = this.startControlPoint;
+        const p2 = this.endControlPoint;
+        const p3 = this.endPoint;
+
+        // set k = 1 - s => substitution
+        const t = s;
+        const k = 1 - s;
+
+        // calculate the coefficients
+        const u0 = 1 * Math.pow(k, 3) * Math.pow(t, 0);
+        const u1 = 3 * Math.pow(k, 2) * Math.pow(t, 1);
+        const u2 = 3 * Math.pow(k, 1) * Math.pow(t, 2);
+        const u3 = 1 * Math.pow(k, 0) * Math.pow(t, 3);
+
+        // calculate the point
+        const p = new Vector2(
+            u0 * p0.x + u1 * p1.x + u2 * p2.x + u3 * p3.x,
+            u0 * p0.y + u1 * p1.y + u2 * p2.y + u3 * p3.y
+        );
+
+        return [p, [u0, u1, u2, u3]];
+    }
+
+
+    deCasteljau(t: number): Vector2 {
+
+        const p0 = this.startPoint;
+        const p1 = this.startControlPoint;
+        const p2 = this.endControlPoint;
+        const p3 = this.endPoint;
+
+        // iterative implementation of deCasteljau
+        let points: Vector2[] = [p0, p1, p2, p3];
+        let temporary: Vector2[] = [];
+        while (points.length > 1) {
+            temporary = [];
+            for (let i = 0; i < points.length - 1; i++)
+                temporary.push(lerp(points[i], points[i + 1], t));
+            points = temporary;
         }
+
+        return points[0];
+    }
+
+
+    generateCurvePoints(): Vector2[] {
+        const curvePoints: Vector2[] = [];
+        const sampleSize = 1 / this._numPoints;
+
+        if (true)
+            for (let t = 0; t < 1; t += sampleSize) {
+                t = Math.round(t * 10000) / 10000;
+                curvePoints.push(this.deCasteljau(t));
+            }
+        else
+            for (let s = 0; s < 1; s += sampleSize) {
+                s = Math.round(s * 10000) / 10000;
+                const [point, coefficient] = this.bernstain(s);
+                curvePoints.push(point);
+            }
+
+
+        return curvePoints;
+    }
 }
\ No newline at end of file