private static void r_rebound(PhysicActor actor, Rectangle rect, double dt) {
    /*
     * Employ a heuristic
     * ------------
     * |    0     |
     * | 1 RECT 3 |
     * |    2     |
     * ------------
     */
    actor.set_last_obstacle_collided(rect);

    Vector actor_pos = actor.get_position().add(actor.get_velocity().multiply(dt));
    Rectangle actor_mbr = actor.get().get_mbr();
    double h[] = {
      actor_pos.y + actor_mbr.y1 - rect.y2,
      actor_pos.y + actor_mbr.y2 - rect.y1,
      actor_pos.x + actor_mbr.x2 - rect.x1,
      actor_pos.x + actor_mbr.x1 - rect.x2
    };

    for (int i = 0; i < 4; i++) h[i] = Math.abs(h[i]);

    // now the question is - which of those is the smallest?

    double smallest_val = Double.POSITIVE_INFINITY;
    int smallest_index = -1;

    for (int i = 0; i < 4; i++)
      if (smallest_val > h[i]) {
        smallest_val = h[i];
        smallest_index = i;
      }

    assert (smallest_index != -1);

    // ok, smallest_index is that

    if (smallest_index == 0) // colliding with floor
    Rebound.actor_hit_floor(actor, rect.y2, dt);

    if (smallest_index == 1) // colliding with roof
    Rebound.actor_hit_roof(actor, rect.y1, dt);

    if (smallest_index == 2) {
      Rebound.actor_hit_rightside(actor, rect.x1, dt);
      if (actor.get_last_obstacle_collided() != rect) {
        actor.set_v_braked(true);
        actor.set_last_obstacle_collided(rect);
      }
    }

    if (smallest_index == 3) {
      Rebound.actor_hit_leftside(actor, rect.x2, dt);
      if (actor.get_last_obstacle_collided() != rect) {
        actor.set_v_braked(true);
        actor.set_last_obstacle_collided(rect);
      }
    }
  }
  /**
   * Rebound an actor by a platform. Actor must collide with platform.
   *
   * <p>Can mutate both actor position and velocity. Will not touch anchor nor flags.
   *
   * @param actor actor (can be mutated)
   * @param hs platform
   * @param dt time delta
   */
  public static void rebound(PhysicActor actor, HorizSegment hs, double dt) {

    actor.set_v_braked(true).on_vbrake(actor.get_h_moving());

    double actor_x = actor.get_position().x;
    double actor_y = hs.y - actor.get().get_mbr().y1 + Rebound.GRAVITY_EPSILON;

    actor.set_position(new Vector(actor_x, actor_y));
    actor.set_velocity(actor.get_velocity().force_y(0));

    // Friction??
    if (actor.get_h_moving()) return; // Actor wants to move, no friction

    Vector vel = actor.get_velocity();

    if (Math.abs(vel.x) < Rebound.FRICTION * dt) vel.x = 0;
    else vel.x += -Math.abs(vel.x) / vel.x * Rebound.FRICTION * dt;

    actor.set_velocity(vel);
  }
  /** Modify the actor, as it has hit the floor */
  private static void actor_hit_floor(PhysicActor actor, double fy, double dt) {
    actor.on_vbrake(actor.get_h_moving());
    actor.set_v_braked(true).set_velocity(actor.get_velocity().force_y(0));

    actor.set_position(
        actor.get_position().force_y(fy - actor.get().get_mbr().y1 + Rebound.GRAVITY_EPSILON));

    if (!actor.get_h_moving()) { // consider friction
      if (Math.abs(actor.get_velocity().x) < Rebound.FRICTION * dt) {
        actor.set_velocity(actor.get_velocity().force_x(0));
        actor.on_hbrake();
      } else {
        actor.set_velocity(
            actor
                .get_velocity()
                .add_x(
                    -Math.abs(actor.get_velocity().x)
                        / actor.get_velocity().x
                        * Rebound.FRICTION
                        * dt));
      }
    }
  }