def _circle_curve_3d(n=200, r=10, theta=0.73): t = np.linspace(0, 2 * np.pi, n) x = np.cos(t) * r y = np.sin(t) * r z = np.ones_like(t) rx = np.array([ [1, 0, 0], [0, np.cos(theta), -np.sin(theta)], [0, np.sin(theta), np.cos(theta)], ]) ry = np.array([ [np.cos(theta), 0, np.sin(theta)], [0, 1, 0], [-np.sin(theta), 0, np.cos(theta)], ]) curve = Curve([x, y, z]) curve_data = np.array(curve.data) for i, p in enumerate(curve): data = rx @ p.data data = ry @ data curve_data[i] = data return Curve(curve_data)
def test_uniform_interp_grid(fill, interp_kind, extrap, extrap_kind, method, expected): interp_grid = UniformInterpolationGrid( fill=fill, kind=interp_kind, ) extrap_grid = UniformExtrapolationGrid( interp_grid, before=extrap, after=extrap, kind=extrap_kind, ) curve = Curve([(1, 3, 5)] * 2) curve_i = curve.interpolate(interp_grid, method=method) curve_e = curve.interpolate(extrap_grid, method=method) if extrap_kind == 'length': extrap_pcount = round(extrap / curve_i.chordlen.mean()) * 2 else: extrap_pcount = extrap * 2 extrap_arclen = curve_i.chordlen.mean() * extrap_pcount assert extrap_grid(curve) == pytest.approx(expected) assert curve_e.size == pytest.approx(curve_i.size + extrap_pcount) assert curve_e.arclen == pytest.approx(curve_i.arclen + extrap_arclen)
def test_concatenate(): left_curve = Curve([(1, 2), (5, 6)]) right_curve = Curve([(3, 4), (7, 8)]) expected_curve = Curve([(1, 2, 3, 4), (5, 6, 7, 8)]) assert left_curve + right_curve == expected_curve left_curve += right_curve assert left_curve == Curve([(1, 2, 3, 4), (5, 6, 7, 8)])
def test_reverse_parametric(): t = np.linspace(0, np.pi, 10) x = np.cos(t) y = np.sin(t) curve = Curve([x, y], tdata=t) reversed_curve = curve.reverse() assert reversed_curve == Curve([x[::-1], y[::-1]]) assert reversed_curve.t == pytest.approx(np.linspace(np.pi, 0, 10))
def test_extrap_kind_point(method): curve = Curve([(1, 3, 5, 7, 9)] * 2) grid = UniformExtrapolationGrid(UniformInterpolationGrid(9, kind='point'), before=3, after=3, kind='point') expected = [(-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)] * 2 assert curve.interpolate(grid, method) == Curve(expected)
def test_construct(data, size, ndim, dtype): curve = Curve(data, dtype=dtype) assert len(curve) == size assert curve.size == size assert curve.ndim == ndim assert curve.dtype == dtype
def _curve_3d(n=200): t = np.linspace(0, 2 * np.pi, n) x = np.cos(t) y = np.sin(t) z = x * y return Curve([x, y, z])
def lissajous( t_start: float = 0.0, t_stop: float = 2 * np.pi, p_count: int = 101, a_ampl: float = 1.0, b_ampl: float = 1.0, a: float = 3.0, b: float = 2.0, d: float = 0.0, ) -> Curve: """ Parameters ---------- t_start t_stop p_count a_ampl b_ampl a b d Returns ------- """ theta = np.linspace(t_start, t_stop, p_count) x = a_ampl * np.sin(a * theta + d) y = b_ampl * np.sin(b * theta) return Curve([x, y], tdata=theta)
def test_extrap_kind_length(method, denom, exlen): curve = Curve([(1, 3, 5, 7, 9)] * 2) chordlen = curve.chordlen.mean() / denom extraplen = chordlen * exlen interp_grid = UniformInterpolationGrid(fill=chordlen, kind='length') extrap_grid = UniformExtrapolationGrid(interp_grid, before=extraplen, after=extraplen, kind='length') curve_i = curve.interpolate(interp_grid, method=method) curve_e = curve.interpolate(extrap_grid, method=method) assert curve_e.arclen == pytest.approx(curve_i.arclen + extraplen * 2)
def irregular_helix(t_start: float = -4 * np.pi, t_stop: float = 4 * np.pi, z_start: float = -2.0, z_stop: float = 2.0, p_count: int = 100) -> Curve: """Produces 3-d irregular helix curve Parameters ---------- t_start t_stop z_start z_stop p_count Returns ------- """ theta = np.linspace(t_start, t_stop, p_count) z = np.linspace(z_start, z_stop, p_count) r = z**2 + 1 x = r * np.sin(theta) y = r * np.cos(theta) return Curve([x, y, z], tdata=theta)
def helix(t_start: float = -3 * np.pi, t_stop: float = 3 * np.pi, p_count: int = 100, a: float = 1.0, b: float = 1.0) -> Curve: """Produces 3-d helix curve Parameters ---------- t_start : float t_stop : float p_count : int a : float b : float Returns ------- """ theta = np.linspace(t_start, t_stop, p_count) x = np.sin(theta) * a y = np.cos(theta) * a z = theta * b return Curve([x, y, z], tdata=theta)
def lemniscate_of_bernoulli(t_start: float = 0.0, t_stop: float = np.pi * 2, p_count: int = 101, c: float = 1.0) -> Curve: """Produces Lemniscate of Bernoulli curve Parameters ---------- t_start t_stop p_count c Returns ------- """ theta = np.linspace(t_start, t_stop, p_count) c_sq2 = c * np.sqrt(2) cos_t = np.cos(theta) sin_t = np.sin(theta) denominator = sin_t**2 + 1 x = (c_sq2 * cos_t) / denominator y = (c_sq2 * cos_t * sin_t) / denominator return Curve([x, y], tdata=theta)
def archimedean_spiral(t_start: float = 0.0, t_stop: float = 5 * np.pi, p_count: int = 200, a: float = 1.5, b: float = -2.4) -> Curve: """Produces Archimedean spiral curve Parameters ---------- t_start t_stop p_count a b Returns ------- """ theta = np.linspace(t_start, t_stop, p_count) x = (a + b * theta) * np.cos(theta) y = (a + b * theta) * np.sin(theta) return Curve([x, y], tdata=theta)
def test_isplane(): t = np.linspace(0, np.pi * 2, 100) x = np.sin(t) y = t z = t curve = Curve([x, y, z]) assert curve.isplane
def test_cumarclen(): n = 5 data = np.arange(n) curve = Curve([data] * 2) expected = np.cumsum([0.0] + [1.4142135623730951] * (n - 1)) assert curve.cumarclen == pytest.approx(expected)
def test_arclen(): n = 1000 data = np.arange(n) curve = Curve([data] * 2) expected = 1.4142135623730951 * (n - 1) assert curve.arclen == pytest.approx(expected)
def test_isnotplane(): t = np.linspace(0, np.pi * 2, 100) x = np.sin(t) y = np.cos(t) z = x * y curve = Curve([x, y, z]) assert not curve.isplane
def test_chordlen(): n = 1000 data = np.arange(n) curve = Curve([data] * 3) expected = [1.7320508075688772] * (n - 1) assert curve.chordlen == pytest.approx(expected)
def test_preserved_speed_interp_grid(): x = np.logspace(0, 1, 10) y = np.logspace(0, 1, 10) curve = Curve([x, y]) grid = PreservedSpeedInterpolationGrid(pcount=10) assert grid(curve) == pytest.approx(curve.t)
def test_from_points(): """Tests creating the instance of 'Curve' class from points """ points = [ Point([1, 5, 9]), Point([2, 6, 10]), Point([3, 7, 11]), Point([4, 8, 12]), ] points_array = np.array(points) curve = Curve(points_array, axis=0) assert curve.size == 4 assert curve.ndim == 3 assert curve.data == pytest.approx(points_array)
def arc(t_start: float = 0.0, t_stop: float = np.pi * 2, p_count: int = 49, r: float = 1.0, c: float = 0.0) -> Curve: r"""Produces arc or full circle curve Produces arc using the following parametric equations: .. math:: x = cos(\theta) \dot r + c y = sin(\theta) \dot r + c By default computes full circle. Parameters ---------- t_start : float Start theta t_stop : float Stop theta p_count : int The number of points r : float Circle radius c : float Circle center Returns ------- curve : Curve Acr curve """ theta = np.linspace(t_start, t_stop, p_count) x = np.cos(theta) * r + c y = np.sin(theta) * r + c return Curve([x, y], tdata=theta)
def euler_spiral(t_start: float = -3 * np.pi / 2, t_stop: float = 3 * np.pi / 2, p_count: int = 1000) -> Curve: """Produces Euler spiral curve Parameters ---------- t_start t_stop p_count Returns ------- """ t = np.linspace(t_start, t_stop, p_count) ssa, csa = fresnel(t) return Curve([csa, ssa], tdata=t)
def test_intersect_curves(data1, data2, segments1, segments2, intersect_points): if data2: curve1 = Curve(data1) curve2 = Curve(data2) intersections = curve1.intersect(curve2) else: curve1 = Curve(data1) curve2 = curve1 intersections = curve1.intersect() assert len(intersections) == len(segments1) for i, intersection in enumerate(intersections): assert CurveSegment(curve1, index=segments1[i]) == intersection.segment1 assert CurveSegment(curve2, index=segments2[i]) == intersection.segment2 assert intersect_points[i] == intersection.intersect_point
def test_to_curve(): segment = Segment(Point([1, 1]), Point([2, 2])) assert segment.to_curve() == Curve([(1, 2), (1, 2)])
def test_tangent_3d(): curve = Curve([(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)]) expected = np.ones_like(curve.data) assert curve.tangent == pytest.approx(expected)
def test_arclen_2(): n = 10 theta = np.linspace(0, 2 * np.pi, n) curve = Curve([np.cos(theta), np.sin(theta)]) assert curve.arclen == pytest.approx(6.156362579862037)
def test_coorientplane_3d(axis1, axis2): curve = Curve([(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)]) curve_r = curve.reverse() assert curve.coorientplane(axis1, axis2) == curve_r.coorientplane(axis1, axis2)
def test_coorientplane_2d(): curve = Curve([(1, 2, 3, 4), (5, 6, 7, 8)]) curve_r = curve.reverse() assert curve.coorientplane() == curve_r.coorientplane()
def test_frenet2_warn(curve_data): curve = Curve(curve_data) with pytest.warns(DifferentialGeometryWarning): print(curve.frenet2)
def test_frenet1_warn(): curve = Curve([(1, 2, 3, 3, 3, 4), (1, 2, 3, 3, 3, 4)]) with pytest.warns(DifferentialGeometryWarning): print(curve.frenet1)