Commit 6b861b24 authored by lars.quentin's avatar lars.quentin 💬
Browse files


parent 5c7d151e
# For local documentation generation
# Created by,python
Multiple Bézier curve implementations with different computations.
The _Bézier curve_ is one of the most infamous functions in Computer Aided Geometric Design (CAGD) as well as other topics
of computer graphics.
# Definition
Although there are many ways to define a bezier curve, the most common ones are as follows:
## 1. Bézier curve with _Bernstein polynomial_ basis
Let the \(i\)-th Bernstein polynomial of Degree \(n\) defined on the unit interval \([0,1]\) as
B_i^n(t) := \\binom{n}{i} t^i (1-t)^{n-i}
where the binomial coefficients are given by
\\binom{n}{i} =
\\frac{n!}{i!(n-i)!} & \\text{if } & 0 \\leq i \\leq n \\\\
0 & \\text{else}
Further let \(b_i\), \(0 \\leq i \\leq n\) denote the _Bézier points_.
Then the Bézier curve is defined as
b(t) := \\sum_{i=0}^n b_i B_i^n(t)
## 2. Bézier curve recursion
A Bézier curve can also be defined through the following recursion:
Let \(b_0,\\dots,b_n \in \\mathbb{E}^3, t \in \\mathbb{R} \), and
b_i^0(t) &:= b_i\\\\
b_i^r(t) &:= (1-t) b_i^{r-1}(t) + t b_{i+1}^{r-1}(t)
# Properties
The properties of a Bézier curve are explained [here](./tests/property_based_tests/test_bezier_curve.html).
import numpy as np
import sympy as sy
import matplotlib.pyplot as plt
import threading as th
import shapely.geometry as sg
from abc import ABC, abstractmethod
from scipy.special import comb
from typing import Tuple, Callable, Union, Any
from curvepy.utilities import csv_read
from typing import Tuple, Callable, Union
class Tholder:
class _Tholder:
Class holds Array with equidistant ts in [0,1] of length n
Helper for scheduling n equidistant values in the unit interval [0,1].
......@@ -56,7 +101,7 @@ class CasteljauThread(th.Thread):
ts_holder: Tholder
ts_holder: _Tholder
Class which yields all ts
c: np.ndarray
Array with control points
......@@ -65,7 +110,7 @@ class CasteljauThread(th.Thread):
_ts_holder : Tholder
_ts_holder : _Tholder
instance of class Tholder so thread can get the ts for calculating the de Casteljau algorithm
_coords: np.ndarray
original control points
......@@ -75,14 +120,14 @@ class CasteljauThread(th.Thread):
function for transforming t
def __init__(self, ts_holder: Tholder, c: np.ndarray, f: Callable[[float], float] = lambda x: x) -> None:
def __init__(self, ts_holder: _Tholder, c: np.ndarray, f: Callable[[float], float] = lambda x: x) -> None:
self._ts_holder = ts_holder
self._coords = c
self.res = []
self._func = f
def de_caes(self, t: float, n: int) -> None:
def _de_caes(self, t: float, n: int) -> None:
Method implementing the the De Casteljau algorithm
......@@ -110,7 +155,7 @@ class CasteljauThread(th.Thread):
if t == -1:
self.de_caes(t, n)
self._de_caes(t, n)
class AbstractBezierCurve(ABC):
......@@ -133,7 +178,7 @@ class AbstractBezierCurve(ABC):
dimension of the bezier points, therefore of the curve as well
_cnt_ts: int
numbers of equidistant ts to calculate
func: Callable
_func: Callable
function computing the Bezier Curve for a single point
_curve: list
list containing points belonging to actual curve
......@@ -145,7 +190,7 @@ class AbstractBezierCurve(ABC):
self._bezier_points = m
self._dimension = self._bezier_points.shape[0]
self._cnt_ts = cnt_ts
self.func = self.init_func(m)
self._func = self.init_func(m)
self._curve = None = []
......@@ -177,7 +222,7 @@ class AbstractBezierCurve(ABC):
if self._curve is None:
ts = np.linspace(0, 1, self._cnt_ts)
self._curve = self.func(ts)
self._curve = self._func(ts)
return self._curve
......@@ -214,9 +259,9 @@ class AbstractBezierCurve(ABC):
true if intersect otherwise false
return t2[0] <= t1[0] <= t2[1] \
or t2[0] <= t1[1] <= t2[1] \
or t1[0] <= t2[0] <= t1[1] \
or t1[0] <= t2[1] <= t1[1]
or t2[0] <= t1[1] <= t2[1] \
or t1[0] <= t2[0] <= t1[1] \
or t1[0] <= t2[1] <= t1[1]
def min_max_box(self) -> None:
......@@ -278,7 +323,7 @@ class AbstractBezierCurve(ABC):
other_curve: Union[BezierCurve2D, BezierCurve3D] # TODO: check whether same type as everywhere
other_curve: Union[BezierCurve2D, BezierCurve3D]
curve to check
......@@ -317,10 +362,6 @@ class AbstractBezierCurve(ABC):
list_of_curves = []
# TODO: debate whether the if below should be thrown away
# this is possible since we would just iterate through an empty list
# This shouldn't be that much faster since we check if the list is empty anyways
# but it would reduce noise
if not list_of_curves:
......@@ -427,7 +468,7 @@ class BezierCurveThreaded(AbstractBezierCurve):
array containing all ts used to calculate points
ts = Tholder(ts)
ts = _Tholder(ts)
threads = []
curve = []
......@@ -443,15 +484,3 @@ class BezierCurveThreaded(AbstractBezierCurve):
curve = curve + tmp
return curve
def init() -> None:
m = csv_read('test.csv') # reads csv file with bezier points
b1 = BezierCurve(m)
m = csv_read('test2.csv') # reads csv file with bezier points
b2 = BezierCurve(m)
if __name__ == "__main__":
Here will be all unit tests for bezier curves
Here will be all unit tests for the ``.
Each test documents its use case.
Note: You have to install pytest yourself, it is not part of the requirements.txt.
import curvepy.bezier_curve # noqa: F401
import pytest
from curvepy.bezier_curve import *
# TODO: check intersection
# TODO: check curve property for good values
# TODO: check curve property for good dimensions
# TODO: Check min-max-box
# TODO: Check everywhere with permutations of the same values
# TODO: Check collision-check (all 3 Functions, whether collision_check calls the appropriate one)
# TODO: Check everywhere untyped whether it is safe against wrong types
# TODO: Check whether plot works for both dimensions
# TODO: CHeck everywhere if too big dimensions are a problem
# TODO: Try to check show_func
# TODO: Check __str__ and __repr__ with regex
# TODO: Check if the different BezierCurves have the same values
def test_intersect():
TODO: Absprechen
\ No newline at end of file
......@@ -6,7 +6,7 @@ from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QWidget, QTa
QGridLayout, QSlider, QGroupBox, QLabel, QFileDialog, QFrame
from PyQt5.QtCore import Qt, pyqtSlot
from PyQt5 import QtGui
import utilities as u
import curvepy.utilities as u
class MyMainApp(QMainWindow):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment