Example #1
0
def test_sliding_ball_collision(pool_physics, plot_motion_timelapse,
                                plot_energy, gl_rendering):
    physics = pool_physics
    ball_positions = physics.eval_positions(0.0)
    ball_positions[1] = ball_positions[0]
    ball_positions[1, 2] -= 8 * physics.ball_radius
    physics.reset(balls_on_table=[0, 1], ball_positions=ball_positions)
    start_event = BallSlidingEvent(0,
                                   0,
                                   r_0=ball_positions[0],
                                   v_0=np.array((0.0, 0.0, -2.0)),
                                   omega_0=np.zeros(3, dtype=np.float64))
    events = physics.add_event_sequence(start_event)
    _logger.debug('%d events added:\n\n%s\n', len(events),
                  PhysicsEvent.events_str(events=events))
Example #2
0
def test_corner_collision(pool_physics, gl_rendering, plot_motion_timelapse,
                          plot_energy):
    physics = pool_physics
    ball_positions = physics.eval_positions(0.0)
    physics.reset(balls_on_table=[0], ball_positions=ball_positions)
    r_c = physics._r_cp[0, 0]
    r_0c = r_c - ball_positions[0]
    v_0 = 3.0 * r_0c / np.sqrt(np.dot(r_0c, r_0c))
    start_event = BallSlidingEvent(0,
                                   0,
                                   r_0=ball_positions[0],
                                   v_0=v_0,
                                   omega_0=np.zeros(3, dtype=np.float64))
    events = physics.add_event_sequence(start_event)
    _logger.debug('%d events added:\n\n%s\n', len(events),
                  PhysicsEvent.events_str(events=events))
Example #3
0
def test_angled_ball_collision(pool_physics, plot_motion_timelapse,
                               plot_energy, gl_rendering):
    physics = pool_physics
    ball_positions = physics.eval_positions(0.0)
    ball_positions[1] = ball_positions[0]
    ball_positions[1, 0] -= 8 / np.sqrt(2) * physics.ball_radius
    ball_positions[1, 2] -= 8 / np.sqrt(2) * physics.ball_radius
    physics.reset(balls_on_table=[0, 1], ball_positions=ball_positions)
    r_ij = ball_positions[1] - ball_positions[0]
    r_ij[0] += physics.ball_radius
    e_ij = r_ij / np.linalg.norm(r_ij)
    v_0 = 0.9 * e_ij
    start_event = BallSlidingEvent(0,
                                   0,
                                   r_0=ball_positions[0],
                                   v_0=v_0,
                                   omega_0=np.zeros(3, dtype=np.float64))
    events = physics.add_event_sequence(start_event)
    _logger.debug('%d events added:\n\n%s\n', len(events),
                  PhysicsEvent.events_str(events=events))
Example #4
0
def test_corner_collision(pool_physics, gl_rendering, plot_motion_timelapse,
                          plot_energy, side, i_c):
    physics = pool_physics
    ball_positions = physics.eval_positions(0.0)
    ball_positions[0, ::2] = 0
    physics.reset(balls_on_table=[0], ball_positions=ball_positions)
    R = physics.ball_radius
    r_c = physics._r_cp[side, i_c]
    r_i = r_c + R * np.array([
        np.sign(r_c[0]) * np.cos(10 * DEG2RAD), 0.0,
        np.sign(r_c[2]) * np.sin(10 * DEG2RAD)
    ])
    r_0i = r_i - ball_positions[0]
    v_0 = 3.0 * r_0i / np.sqrt(np.dot(r_0i, r_0i))
    start_event = BallSlidingEvent(0,
                                   0,
                                   r_0=ball_positions[0],
                                   v_0=v_0,
                                   omega_0=np.zeros(3, dtype=np.float64))
    events = physics.add_event_sequence(start_event)
    assert any(isinstance(e, CornerCollisionEvent) for e in events)
    _logger.debug('%d events added:\n\n%s\n', len(events),
                  PhysicsEvent.events_str(events=events))
Example #5
0
def test_collide_balls(request):
    """Reproduce results of Mathavan et al, 2014 - Table 1"""
    show_plots = request.config.getoption('--show-plots')
    e = 0.89
    mu_s = 0.21
    mu_b = 0.05
    M = 0.1406
    R = 0.02625
    r_i = np.zeros(3)
    rd = np.array([1.0, 0.0, 0.0])
    r_c = np.array([R, 0.0, 0.0])
    r_j = r_i + 2 * R * rd
    v_j = np.zeros(3, dtype=np.float64)
    omega_j = np.zeros(3, dtype=np.float64)
    expected = [
        # Table 1       # Table 2
        (0.914, 0.831, 31.93, 32.20),
        (0.520, 0.599, 32.45, 25.07),
        (0.917, 0.676, 29.91, 38.62),
        (1.28, 0.780, 27.32, 44.38),
        (0.383, 0.579, 29.47, 17.15)
    ]
    for i_cond, (cue_ball_velocity, topspin,
                 cut_angle) in enumerate([(1.539, 58.63, 33.83),
                                          (1.032, 39.31, 26.36),
                                          (1.364, 51.96, 40.52),
                                          (1.731, 65.94, 46.5),
                                          (0.942, 35.89, 18.05)]):
        c, s = np.cos(cut_angle * DEG2RAD), np.sin(cut_angle * DEG2RAD)
        v_i, omega_i = np.array(
            ((cue_ball_velocity * c, 0.0, cue_ball_velocity * s),
             (topspin * s, 0.0, -topspin * c)))
        v_i[1:] = v_i[:0:-1]
        v_j[1:] = v_j[:0:-1]
        omega_i[1:] = omega_i[:0:-1]
        omega_j[1:] = omega_j[:0:-1]
        deltaP = (1 + e) * M * cue_ball_velocity / 8000
        v_is, omega_is, v_js, omega_js = collide_balls(r_c,
                                                       r_i,
                                                       v_i,
                                                       omega_i,
                                                       r_j,
                                                       v_j,
                                                       omega_j,
                                                       e,
                                                       mu_s,
                                                       mu_b,
                                                       M,
                                                       R,
                                                       9.81,
                                                       deltaP=deltaP,
                                                       return_all=True)
        if show_plots:
            plot_collision(deltaP * np.arange(len(v_is)), v_is, v_js, omega_is,
                           omega_js)
        v_is[:, 1:] = v_is[:, :0:-1]
        v_js[:, 1:] = v_js[:, :0:-1]
        omega_is[:, 1:] = omega_is[:, :0:-1]
        omega_js[:, 1:] = omega_js[:, :0:-1]
        v_i1 = v_is[-1]
        omega_i1 = omega_is[-1]
        v_j1 = v_js[-1]
        omega_j1 = omega_js[-1]
        from poolvr.physics.events import PhysicsEvent, BallSlidingEvent
        PhysicsEvent.ball_radius = R
        PhysicsEvent.ball_diameter = 2 * R
        PhysicsEvent.ball_mass = M
        PhysicsEvent.ball_I = 2.0 / 5 * M * R**2
        PhysicsEvent.mu_s = mu_s
        PhysicsEvent.mu_b = mu_b
        e_i, e_j = BallSlidingEvent(0.0, 0, r_i, v_i1, omega_i1), \
                   BallSlidingEvent(0.0, 1, r_j, v_j1, omega_j1)
        v_iS = e_i.next_motion_event.eval_velocity(0.0)
        v_jS = e_j.next_motion_event.eval_velocity(0.0)
        v_iS_mag = np.sqrt(np.dot(v_iS, v_iS))
        v_jS_mag = np.sqrt(np.dot(v_jS, v_jS))
        lambda_i = np.arctan(v_iS[2] / v_iS[0]) * RAD2DEG
        lambda_j = np.arctan(-v_jS[2] / v_jS[0]) * RAD2DEG
        theta_i = abs(lambda_i - cut_angle)
        theta_j = abs(lambda_j - cut_angle)
        v_iS_mag_ex, v_jS_mag_ex, theta_i_ex, theta_j_ex = expected[i_cond]
        v_0 = np.sqrt(np.dot(v_i, v_i))
        _logger.info(
            '''
    |v_0|: %s
    topspin: %s
    cut_angle: %s

                 |v_iS| = %s
        expected |v_iS| = %s
                 |v_jS| = %s
        expected |v_jS| = %s
        abs(|v_iS| - expected) / |expected| = %s
        abs(|v_jS| - expected) / |expected| = %s

                 theta_i = %s
        expected theta_i = %s
                 theta_j = %s
        expected theta_j = %s
        abs(theta_i - expected) / |expected| = %s
        abs(theta_j - expected) / |expected| = %s
        ''', v_0, topspin, cut_angle, v_iS_mag, v_iS_mag_ex, v_jS_mag,
            v_jS_mag_ex,
            abs(v_iS_mag - v_iS_mag_ex) / abs(v_iS_mag_ex),
            abs(v_jS_mag - v_jS_mag_ex) / abs(v_jS_mag_ex), theta_i,
            theta_i_ex, theta_j, theta_j_ex,
            abs(theta_i - theta_i_ex) / abs(theta_i_ex),
            abs(theta_j - theta_j_ex) / abs(theta_j_ex))