From 960c90988e0eabb2af9f00ea7701c1f41abd8817 Mon Sep 17 00:00:00 2001
From: Soeren Peters <peters@irmb.tu-bs.de>
Date: Wed, 19 Jan 2022 11:57:49 +0100
Subject: [PATCH] Add bezier solution with bernstein polynom.

---
 README.md                                     | 12 +++++++-
 .../java/irmb/flowsim/model/BezierCurve.java  | 22 ++++++++++----
 .../view/graphics/PaintableBezierCurve.java   | 29 +++++++++++++++++--
 3 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 77cc73a..68b240f 100644
--- a/README.md
+++ b/README.md
@@ -64,4 +64,14 @@ Compared to the last exercise, we now have the following folder filled with clas
 
 The task is implement BuildObjectMouseStrategy and MoveMouseStrategy.
 ### Expected behavior:
-Shapes can be painted via the menu or the toolbar. Additionally, the shapes can be moved via the mouse, the window can be panned and zoomed. A right click should remove the shape.
\ No newline at end of file
+Shapes can be painted via the menu or the toolbar. Additionally, the shapes can be moved via the mouse, the window can be panned and zoomed. A right click should remove the shape.
+
+## Exercuse 5
+This exercise is based on the eighth lecture about the bezier interpolation method.
+Compared to the last exercise, we now have the following folder filled with class stubs.
+
+    model/BezierCurve.java
+    view/graphics/PaintableBezierCurve.java
+
+### Expected behavior:
+Bezier Curve can be painted.
diff --git a/src/main/java/irmb/flowsim/model/BezierCurve.java b/src/main/java/irmb/flowsim/model/BezierCurve.java
index ac5a0b4..01b5802 100644
--- a/src/main/java/irmb/flowsim/model/BezierCurve.java
+++ b/src/main/java/irmb/flowsim/model/BezierCurve.java
@@ -12,17 +12,27 @@ public class BezierCurve extends PolyLine {
 
 
     public Point calculatePointWithBernstein(double t) {
-        //TODO
-        return new Point(0,0);
+        List<Point> pointList = getPointList();
+        int size = pointList.size();
+        double x = 0, y = 0;
+        for (int i = 0; i < size; i++) {
+            double c = binomialCoefficient(size - 1, i) * Math.pow(t, i) * Math.pow(1.0 - t, size - 1.0 - i);
+            x += c * pointList.get(i).getX();
+            y += c * pointList.get(i).getY();
+        }
+        return new Point(x, y);
     }
 
     private double binomialCoefficient(int n, int k) {
-        //TODO
-        return 0.0;
+        if (n >= k && n >= 0)
+            return factorial(n) / (double)(factorial(k) * factorial(n - k));
+        return -1;
     }
 
     private long factorial(int n) {
-        //TODO
-        return 0;
+        long sum = 1;
+        for (int i = n; i >= 1; i--)
+            sum *= i;
+        return sum;
     }
 }
diff --git a/src/main/java/irmb/flowsim/view/graphics/PaintableBezierCurve.java b/src/main/java/irmb/flowsim/view/graphics/PaintableBezierCurve.java
index d35dd07..2a0f669 100644
--- a/src/main/java/irmb/flowsim/view/graphics/PaintableBezierCurve.java
+++ b/src/main/java/irmb/flowsim/view/graphics/PaintableBezierCurve.java
@@ -23,12 +23,37 @@ public class PaintableBezierCurve extends PaintableShape {
 
     @Override
     public void paint(Painter painter) {
-        //TODO
+        List<Point> pointList = bezierCurve.getPointList();
+        int numOfPoints = 100;
+        if (pointList.size() >= 2) {
+            for (int i = 0; i < numOfPoints-1; i++) {
+                double t1 = (i) / (double) (numOfPoints - 1);
+                double t2 = (i + 1.0) / (double) (numOfPoints - 1);
+
+                Point p1 = bezierCurve.calculatePointWithBernstein(t1);
+                Point p2 = bezierCurve.calculatePointWithBernstein(t2);
+
+                painter.paintLine(new Point(p1.getX(), p1.getY()), new Point(p2.getX(), p2.getY()));
+            }
+        }
     }
 
     @Override
     public boolean isPointOnBoundary(Point point, double radius) {
-        //TODO
+        if (getDefinedPoint(point, radius) != null) 
+            return true;
+        int numPoints = 100;
+        for (int i = 0; i < numPoints - 1; i++) {
+            double t1, t2;
+            t1 = i / (double) (numPoints - 1);
+            t2 = (i + 1) / (double) (numPoints - 1);
+            first = bezierCurve.calculatePointWithBernstein(t1);
+            second = bezierCurve.calculatePointWithBernstein(t2);
+            if (isInXBounds(point)) {
+                double distanceToLine = getDistanceToLine(first, second, point);
+                if (distanceToLine <= radius) return true;
+            }
+        }
         return false;
     }
 
-- 
GitLab