Exemple #1
0
def test_trig_invariance(angle: float, n: int):
    """Test that cos(θ), sin(θ) ≃ cos(θ + n*360°), sin(θ + n*360°)"""
    r_cos, r_sin = Vector._trig(angle)
    n_cos, n_sin = Vector._trig(angle + 360 * n)

    note(f"δcos: {r_cos - n_cos}")
    assert isclose(r_cos, n_cos, rel_to=[n / 1e9])
    note(f"δsin: {r_sin - n_sin}")
    assert isclose(r_sin, n_sin, rel_to=[n / 1e9])
Exemple #2
0
def test_trig_stability(angle):
    """cos² + sin² == 1

    We are testing that this equation holds, as otherwise rotations
    would (slightly) change the length of vectors they are applied to.
    """
    r_cos, r_sin = Vector._trig(angle)

    # Don't use exponents here. Multiplication is generally more stable.
    assert math.isclose(r_cos * r_cos + r_sin * r_sin, 1, rel_tol=1e-18)
Exemple #3
0
def test_remarkable_angles(angle, trig):
    """Test that our table of remarkable angles agrees with Vector._trig.

    This is useful both as a consistency test of the table,
    and as a test of Vector._trig (which Vector.rotate uses).
    """
    cos_t, sin_t = trig
    cos_m, sin_m = Vector._trig(angle)

    assert isclose(sin_t, sin_m, abs_tol=0, rel_tol=1e-14)
    assert isclose(cos_t, cos_m, abs_tol=0, rel_tol=1e-14)
Exemple #4
0
def test_dot_rotational_invariance(x: Vector, y: Vector, angle: float):
    """Test that rotating vectors doesn't change their dot product."""
    t = x.angle(y)
    cos_t, _ = Vector._trig(t)
    note(f"θ: {t}")
    note(f"cos θ: {cos_t}")

    # Exclude near-orthogonal test inputs
    assume(abs(cos_t) > 1e-6)
    assert isclose(x * y,
                   x.rotate(angle) * y.rotate(angle),
                   rel_to=(x, y),
                   rel_exp=2)
Exemple #5
0
def test_dot_from_angle(x: Vector, y: Vector):
    """Test x · y == |x| · |y| · cos(θ)"""
    t = x.angle(y)
    cos_t, _ = Vector._trig(t)

    # Dismiss near-othogonal test inputs
    assume(abs(cos_t) > 1e-6)

    min_len, max_len = sorted((x.length, y.length))
    geometric = min_len * (max_len * cos_t)

    note(f"θ: {t}")
    note(f"cos θ: {cos_t}")
    note(f"algebraic: {x * y}")
    note(f"geometric: {geometric}")
    assert isclose(x * y, geometric, rel_to=(x, y), rel_exp=2)
Exemple #6
0
def test_trig_stability(angle):
    """cos² + sin² == 1

    We are testing that this equation holds, as otherwise rotations
    would (slightly) change the length of vectors they are applied to.

    Moreover, Vector._trig should get closer to fulfilling it than
    math.{cos,sin}.
    """
    r_cos, r_sin = Vector._trig(angle)
    r_len = r_cos * r_cos + r_sin * r_sin

    # Don't use exponents here. Multiplication is generally more stable.
    assert math.isclose(r_len, 1, rel_tol=1e-18)

    t_cos, t_sin = cos(radians(angle)), sin(radians(angle))
    t_len = t_cos * t_cos + t_sin * t_sin
    assert fabs(1 - r_len) <= fabs(1 - t_len)