diff --git a/src/01-bezierCurves/Curve.ts b/src/01-bezierCurves/Curve.ts
index 502dbb2a066db02f54dd71746d91cf256368bdcd..d5c7a8ded2f4c52a44f93e264a13775b168991fa 100644
--- a/src/01-bezierCurves/Curve.ts
+++ b/src/01-bezierCurves/Curve.ts
@@ -38,6 +38,10 @@ class Curve extends Line2d {
         this._generator = new CubicBezierCurve(this.positions, new DeCasteljauAlgorithm());
     }
 
+    public get resolution(): number {
+        return this._resolution;
+    }
+
     public update(_deltaTime: number): void {
         this._points = this._generator.evaluatePositions(this._resolution);
         this._points.forEach((point) => {
diff --git a/src/01-bezierCurves/CurveHelper.ts b/src/01-bezierCurves/CurveHelper.ts
index 0b08618caea9104672413a538bca4b78b2c7ac32..1e4496ea2d7cd2944c5572fd1bee0b3064d967a6 100644
--- a/src/01-bezierCurves/CurveHelper.ts
+++ b/src/01-bezierCurves/CurveHelper.ts
@@ -1,14 +1,16 @@
 import * as THREE from "three";
 import { Curve } from "./Curve";
-import { PipelineObserver, PipelineRenderable } from "../core/Pipeline";
-import { Line1d } from "../core/Shapes";
-import { DeCasteljauAlgorithm } from "./CubicBezierCurve";
+import { PipelineDraggable, PipelineGUI, PipelineObserver, PipelineRenderable } from "../core/Pipeline";
+import { Line1d, Point2d } from "../core/Shapes";
+import { DeCasteljauAlgorithm, BernsteinAlgorithm } from "./CubicBezierCurve";
 import dat from "dat.gui";
 
-class CurveHelper implements PipelineObserver, PipelineRenderable {
+class CurveHelper implements PipelineObserver, PipelineRenderable, PipelineGUI {
+
+    public curve: Curve;
 
     public group: THREE.Group;
-    private _curve: Curve;
+    private _point: Point2d;
     private _lines: Array<Line1d>;
     private _offset: number;
     private _speed: number = 1;
@@ -16,11 +18,16 @@ class CurveHelper implements PipelineObserver, PipelineRenderable {
     t: number = 0;
 
     constructor(curve: Curve, offset: number = 0) {
-        this._curve = curve;
+        this.curve = curve;
         this._offset = offset;
         this._lines = new Array<Line1d>();        
         this.group = new THREE.Group();
 
+        this._point = new Point2d(.03, 32, new THREE.Color(0xff00ff));
+        this._point.material = new THREE.MeshBasicMaterial({
+            color: new THREE.Color(0xff00ff)});
+        this._point._object3d.position.z = this._offset;
+
         this._lines.push(new Line1d([new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()], new THREE.Color(0xffff00)));
         this._lines.push(new Line1d([new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()], new THREE.Color(0x00ffff)));
         this._lines.push(new Line1d([new THREE.Vector3(), new THREE.Vector3()], new THREE.Color(0xff00ff)));
@@ -43,11 +50,17 @@ class CurveHelper implements PipelineObserver, PipelineRenderable {
         this._lines.forEach((line) => {
             this.group.add(line.object());
         });
+        this.group.add(this._point.object());
+    }
 
-        this.gui()
+    gui(gui: dat.GUI): void {
+        const folder = gui.addFolder('CurveHelper');
+        folder.add(this, 't', 0, 1, 0.01).listen();
+        folder.add(this, '_speed', 1, 2, 0.1).name("speed");
+        folder.closed = false;
     }
 
-    object(): THREE.Object3D<THREE.Event> {
+    object(): THREE.Object3D {
         return this.group;
     }
 
@@ -55,14 +68,9 @@ class CurveHelper implements PipelineObserver, PipelineRenderable {
         return this.group.position;
     }
 
-    gui() : void {
-        const test = new dat.GUI();
-        test.add(this, 't', 0, 1);
-    }
-
     public update(_deltaTime: number): void {
         let points = new Array<THREE.Vector3>();
-        this._curve.positions.forEach((position) => {
+        this.curve.positions.forEach((position) => {
             const p = position.clone();
             p.z = this._offset;
             points.push(p);
@@ -73,15 +81,107 @@ class CurveHelper implements PipelineObserver, PipelineRenderable {
         this._lines[1].points = points;
         points = DeCasteljauAlgorithm.iteration(points, this.t);
         this._lines[2].points = points;
+        points = DeCasteljauAlgorithm.iteration(points, this.t);
+        this._point._object3d.position.x = points[0].x;
+        this._point._object3d.position.y = points[0].y;
     }
 }
 
-class CurveHelperExtension {
+class CurveHelperBernstein implements PipelineObserver, PipelineRenderable, PipelineDraggable {
+
+    private _helperReference: CurveHelper;
+
+    private _xAxis: Line1d;
+    private _yAxis: Line1d;
+    private _graphs: Array<Line1d>;
+    private _point: Array<Point2d>;
+    private _background: THREE.Mesh;
+    private _group: THREE.Group;
+
+    constructor(helper: CurveHelper, offset: number = 0) {
+        this._helperReference = helper;
+        this._xAxis = new Line1d(
+            [new THREE.Vector3(-.5, -.5, 0), new THREE.Vector3(.5, -.5, 0)], 
+            new THREE.Color(0xff0000));
+        this._yAxis = new Line1d(
+            [new THREE.Vector3(-.5, -.5, 0), new THREE.Vector3(-.5, .5, 0)], 
+            new THREE.Color(0x00ff00));
+        this._graphs = new Array<Line1d>();
+        this._point = new Array<Point2d>();
+
+        this._background = new THREE.Mesh(
+            new THREE.PlaneGeometry(1, 1),
+            new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.5, transparent: true }));
+        this._background.position.z = offset;
+
+        const points: Array< Array<THREE.Vector3>> = new Array< Array<THREE.Vector3>>();
+        for (let i = 0; i < 4; i++) {
+            points.push(new Array<THREE.Vector3>());
+        }
+
+        const resolution = this._helperReference.curve.resolution;
+        for (let i = 0; i < resolution + 1; i++) {
+            let t = i / resolution;
+            let coefficients = BernsteinAlgorithm.calculateCoefficients(t);
+            coefficients.forEach((c, index) => {
+                points[index].push(new THREE.Vector3(t, c, 0.001).sub(new THREE.Vector3(0.5, 0.5, 0)));
+            });
+        }
+
+        for (let i = 0; i < 4; i++) {
+            this._graphs.push(new Line1d(points[i], new THREE.Color(0x0000ff)));
+        }
+
+        const material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
+        const coefficient = BernsteinAlgorithm.calculateCoefficients(this._helperReference.t);
+        for (let i = 0; i < 4; i++) {
+            this._point.push(new Point2d(.02, 32, new THREE.Color(0x0000ff)));
+            this._point[i].material = material;
+            this._point[i].position().copy(new THREE.Vector3(this._helperReference.t, coefficient[i], 0.001));
+        }
+
+        this._group = new THREE.Group();
+        this._group.add(this._xAxis.object());
+        this._group.add(this._yAxis.object());
+        this._graphs.forEach((graph) => {
+            this._group.add(graph.object());
+        });
+        this._point.forEach((point) => {
+            this._group.add(point.object());
+        });
+        this._group.add(this._background);
+
+        this._xAxis._object3d.parent = this._background;
+        this._yAxis._object3d.parent = this._background;
+        this._graphs.forEach((graph) => {
+            graph._object3d.parent = this._background;
+        });
+        this._point.forEach((point) => {
+            point._object3d.parent = this._background;
+        });
+
+    }
+
+    hitbox(): THREE.Object3D {
+        return this._background;
+    }
+
+    object(): THREE.Object3D {
+        return this._group;
+    }
+
+    position(): THREE.Vector3 {
+        return this._group.position;
+    }
 
-    constructor(helper: CurveHelper) {
-        helper.group.position.set(0, 0, 0);
+    update(_deltaTime: number): void {
+        const coefficient = BernsteinAlgorithm.calculateCoefficients(this._helperReference.t);
+        for (let i = 0; i < 4; i++) {
+            this._point.push(new Point2d(.02, 32, new THREE.Color(0x0000ff)));
+            this._point[i].position().copy(new THREE.Vector3(this._helperReference.t, coefficient[i], 0.001).sub(new THREE.Vector3(0.5, 0.5, 0)));
+        }
     }
 
 }
 
-export { CurveHelper }
+export { CurveHelper, CurveHelperBernstein }
diff --git a/src/01-bezierCurves/DemoBezier.ts b/src/01-bezierCurves/DemoBezier.ts
index cc67a5063997334b960596171b6083fb2597a728..1bb096260d4ef668301352ca14ea7297a81e2710 100644
--- a/src/01-bezierCurves/DemoBezier.ts
+++ b/src/01-bezierCurves/DemoBezier.ts
@@ -2,7 +2,7 @@ import * as THREE from 'three';
 import { PipelineData } from "../core/Pipeline";
 import { Point2d } from "../core/Shapes";
 import { Curve } from './Curve';
-import { CurveHelper } from './CurveHelper';
+import { CurveHelper, CurveHelperBernstein } from './CurveHelper';
 
 class BezierDemo extends PipelineData {
     public constructor() { super(); }
@@ -31,16 +31,30 @@ class BezierDemo extends PipelineData {
         });
 
         const curveHelper = new CurveHelper(curve, -.5);
+        const curveHelperBernstein = new CurveHelperBernstein(curveHelper, .25);
 
         this.addObject(curve);
         this.addObject(curveHelper);
-        this.addObject(pointA, true);
-        this.addObject(tangentA, true);
-        this.addObject(pointB, true);
-        this.addObject(tangentB, true);
+        this.addObject(curveHelperBernstein);
+
+        this.addDraggable(curveHelperBernstein);
 
         this.addObserver(curve);
         this.addObserver(curveHelper);
+        this.addObserver(curveHelperBernstein);
+
+        this.addGUI(curveHelper);
+
+        this.addObject(pointA);
+        this.addObject(tangentA);
+        this.addObject(pointB);
+        this.addObject(tangentB);
+
+        this.addDraggable(pointA);
+        this.addDraggable(tangentA);
+        this.addDraggable(pointB);
+        this.addDraggable(tangentB);
+
         this.addObserver(pointA);
         this.addObserver(tangentA);
         this.addObserver(pointB);
diff --git a/src/core/Pipeline.ts b/src/core/Pipeline.ts
index 6383b92e7258a7b9f3815f68f52f733091268689..f02edc8778ba6f0ac8e27255bc4c66df7a0423d8 100644
--- a/src/core/Pipeline.ts
+++ b/src/core/Pipeline.ts
@@ -1,3 +1,4 @@
+import dat from "dat.gui";
 import * as THREE from "three";
 
 import { DragControls } from "three/examples/jsm/controls/DragControls";
@@ -26,29 +27,51 @@ interface PipelineRenderable {
     position(): THREE.Vector3;
 }
 
+interface PipelineDraggable {
+
+    /**
+     * THREE.Object3d that represents a hit box for the draggable.
+     */
+    hitbox(): THREE.Object3D;
+}
+
+interface PipelineGUI {
+    /**
+     * THREE.Object3d that represents a hit box for the draggable.
+     */
+    gui(gui: dat.GUI): void;
+}
+
 abstract class PipelineData {
     observers: Array<PipelineObserver>;
+    guiElements: Array<PipelineGUI>;
     draggables: Array<THREE.Object3D>;
     scene: THREE.Scene;
 
     constructor() {
         this.observers = new Array<PipelineObserver>();
+        this.guiElements = new Array<PipelineGUI>();
         this.draggables = new Array<THREE.Object3D>();
         this.scene = new THREE.Scene();
         this.data();
     }
 
-    protected addObject(renderable: PipelineRenderable, draggable: boolean = false) {
+    protected addObject(renderable: PipelineRenderable) {
         this.scene.add(renderable.object());
-        if (draggable) {
-            this.draggables.push(renderable.object());
-        }
     } 
 
+    protected addDraggable(draggable: PipelineDraggable) {
+        this.draggables.push(draggable.hitbox());
+    }
+
     protected addObserver(observer: PipelineObserver) {
         this.observers.push(observer);
     }
 
+    protected addGUI(guiElement: PipelineGUI) {
+        this.guiElements.push(guiElement);
+    }
+
     /**
      * @brief Should define a scenario with observers, draggables and scene.
      * It initializes the scene and adds the draggables to the scene.
@@ -64,6 +87,7 @@ class Pipeline {
 
     public orbitControls: OrbitControls;
     public dragControls: DragControls;
+    public gui: dat.GUI;
 
     private scene?: THREE.Scene;
     private observer: Array<PipelineObserver>;
@@ -71,7 +95,6 @@ class Pipeline {
 
     constructor(perspective: boolean = true) {
         // CREATE CAMERA
-
         if (perspective) {
             this.camera = new THREE.PerspectiveCamera(75, 
                 window.innerWidth / window.innerHeight, 0.1, 1000);
@@ -119,6 +142,7 @@ class Pipeline {
         });
 
         // INITIALISE OTHER FIELDS
+        this.gui = new dat.GUI();
         this.observer = new Array<PipelineObserver>();
         this.startTime = performance.now();
     }
@@ -127,19 +151,13 @@ class Pipeline {
         this.setScene(data.scene);
         data.draggables.forEach(draggable => { this.addDraggable(draggable); });
         data.observers.forEach(observer => { this.addPipelineObserver(observer); });
+        data.guiElements.forEach(guiElement => { this.addGUI(guiElement); });
     }
 
     public addPipelineObserver(object: PipelineObserver): void {
         this.observer.push(object);
     }
 
-    public removePipelineObserver(object: PipelineObserver): void {
-        let index = this.observer.indexOf(object);
-        if (index > -1) {
-            this.observer.splice(index, 1);
-        }
-    }
-
     public addDraggable(object: THREE.Object3D): void {
         if (object instanceof THREE.Line) {
             console.warn('Cannot add draggable to line');
@@ -148,6 +166,10 @@ class Pipeline {
         this.dragControls.getObjects().push(object);
     }
 
+    public addGUI(object: PipelineGUI): void {
+        object.gui(this.gui);
+    }
+
     public setScene(scene: THREE.Scene): void {
         this.scene = scene;
     }
@@ -176,4 +198,4 @@ class Pipeline {
 }
 
 export { Pipeline, PipelineData };
-export type { PipelineObserver, PipelineRenderable };
+export type { PipelineObserver, PipelineRenderable, PipelineDraggable, PipelineGUI };
diff --git a/src/core/Shapes.ts b/src/core/Shapes.ts
index 3c3306ddc72ce217f9c2a08b488be253cf563e7c..9530680a9e337ed3310c51c7b0367840b721a274 100644
--- a/src/core/Shapes.ts
+++ b/src/core/Shapes.ts
@@ -1,5 +1,5 @@
 import * as THREE from "three";
-import { PipelineObserver, PipelineRenderable } from "./Pipeline";
+import { PipelineDraggable, PipelineObserver, PipelineRenderable } from "./Pipeline";
 
 import { LineMaterial } from "three/examples/jsm/lines/LineMaterial";
 import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
@@ -12,7 +12,7 @@ abstract class Shape implements PipelineObserver, PipelineRenderable {
      * It is not enforced through the construct as initalization of other fields
      * become uncomfortable.
      */
-    protected _object3d!: THREE.Object3D;
+    public _object3d!: THREE.Object3D;
 
     public object(): THREE.Object3D {
         return this._object3d!;
@@ -25,7 +25,7 @@ abstract class Shape implements PipelineObserver, PipelineRenderable {
     update(_deltaTime: number): void {/* INTENTIONAL */ }
 }
 
-abstract class Point extends Shape {
+abstract class Point extends Shape implements PipelineDraggable {
     private _geometry: THREE.BufferGeometry;
     private _material: THREE.MeshBasicMaterial | THREE.MeshLambertMaterial;
 
@@ -69,6 +69,10 @@ abstract class Point extends Shape {
         this._material.color = this._color;
         (this._object3d as THREE.Mesh).material = material;
     }
+
+    hitbox(): THREE.Object3D<THREE.Event> {
+        return this._object3d;
+    }
     
 }
 
@@ -224,7 +228,7 @@ class Line2d extends Line {
     }
 }
 
-class Mesh extends Shape {
+class Mesh extends Shape implements PipelineDraggable {
 
     protected _material: THREE.MeshBasicMaterial | THREE.MeshLambertMaterial;
     protected _color: THREE.Color;
@@ -271,6 +275,10 @@ class Mesh extends Shape {
             }
         });
     }
+
+    hitbox(): THREE.Object3D<THREE.Event> {
+        return this._object3d;
+    }
 }