1# Copyright (c) 2020, Manfred Moitzi
2# License: MIT License
3from typing import Iterable
4from ezdxf.math import Vec3
5from .construct2d import linspace
6
7
8class CSpline:
9    """
10    In numerical analysis, a cubic Hermite spline or cubic Hermite interpolator is a spline where each piece is a
11    third-degree polynomial specified in Hermite form, that is, by its values and first derivatives at the end points
12    of the corresponding domain interval.
13
14    Source: https://en.wikipedia.org/wiki/Cubic_Hermite_spline
15    """
16    # https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline
17    def __init__(self, p0: Vec3, p1: Vec3, m0: Vec3, m1: Vec3):
18        self.p0 = p0
19        self.p1 = p1
20        self.m0 = m0
21        self.m1 = m1
22
23    def point(self, t: float) -> Vec3:
24        t2 = t * t
25        t3 = t2 * t
26        h00 = t3 * 2.0 - t2 * 3.0 + 1.0
27        h10 = -t3 * 2.0 + t2 * 3.0
28        h01 = t3 - t2 * 2.0 + t
29        h11 = t3 - t2
30        return self.p0 * h00 + self.p1 * h10 + self.m0 * h01 + self.m1 * h11
31
32
33def approximate(csplines: Iterable[CSpline], count) -> Iterable[Vec3]:
34    for cspline in csplines:
35        for t in linspace(0.0, 1.0, count):
36            yield cspline.point(t)
37