Source code for being.curve

"""Curve set. Spline-like which can contain multiple splines."""
from typing import List

import numpy as np

from being.constants import INF
from being.math import clip
from being.spline import spline_dimensions
from being.typing import Spline


[docs]class Curve: """Curve container aka. curve set. Contains multiple curves as splines.""" def __init__(self, splines: List[Spline]): """ Args: splines: List of splines. """ self.splines: List[Spline] = splines @property def start(self) -> float: """Start time.""" return min(s.x[0] for s in self.splines) @property def end(self) -> float: """End time.""" return max(s.x[-1] for s in self.splines) @property def duration(self) -> float: """Maximum duration of motion.""" #return max((spline.x[-1] for spline in self.splines), default=0.0) return self.end @property def n_splines(self) -> int: """Number of splines.""" return len(self.splines) @property def n_channels(self) -> int: """Number of channels. Sum of all spline dimensions. Tip: This is not the same as number of splines :meth:`Curve.n_splines`. """ return sum( spline_dimensions(s) for s in self.splines )
[docs] def sample(self, timestamp: float, loop: bool = False) -> List[float]: """Sample curve. Returns :attr:`Curve.n_channels` many samples. Subsequent child splines get clamped. Args: timestamp: Time value to sample for. loop (optional): Loop curve playback. False by default. Returns: Curve samples. """ if loop: period = self.duration else: period = INF samples = [] for spline in self.splines: # Subtracting a small epsilon from upper clipping border. Non # extrapolating splines *can* return NaN when on the edge # (spline(spline.x[-1])). But not always :( samples.extend(spline(clip(timestamp % period, spline.x[0], spline.x[-1] - 1e-15))) #return np.array(samples) return samples
def __call__(self, x, nu=0, extrapolate=None) -> np.ndarray: return np.concatenate([ s(x, nu, extrapolate) for s in self.splines ], axis=-1) def __str__(self): return f'{type(self).__name__}({self.n_channels} curves)'