パットシミュレーター

stimpmeter 9 ft — 俯瞰図(真上から)

t = 0.00 s
ボール(直径 42.67 mm)
カップ(直径 108 mm)
各秒の位置
時刻 (s)位置 (m)

計算方法(Python)

import math

# ボールがカップで止まるような速度で転がり始めた場合の、n秒後のボールの位置を計算する。
# 空気抵抗は考慮しない。
# 
# stimpmeter_feet: ゴルフ場に書いてあるスティンプメーター値
# distance_to_cup_meter: カップまでの距離
#
# 戻り値は
# ([1秒ごとのボールの位置(m)]、ボールが止まるまでの秒数)
def ball_at(stimpmeter_feet: float, distance_to_cup_meter: float):
    g = 9.8

    # フィート -> メートルに変換
    stimpmeter_meter = stimpmeter_feet * 0.3048

    # スティンプメーターから転がした球の初速
    stimpmeter_initial_v = math.sqrt(2 * g * 0.1715) # 0.1715はスティンプメーターの高さ (m)

    # スティンプメーターの計測値を使った転がり抵抗係数の計算
    rolling_resistance_factor = (stimpmeter_initial_v ** 2) / (2 * g * stimpmeter_meter)

    # グリーン上のボール減速度 (m/s^2)
    a = rolling_resistance_factor * g

    # カップまでの距離をDとすると、
    # カップで止まらなければいけないので、Dm地点での速度が0になるから、
    # v(T) = v0 - a * T = 0
    # -> T = v0 / a
    # また、D = v0 * T + 1/2 * a * T^2 なので、
    # D = v0 * (v0 / a) + 1/2 * a * (v0 / a)^2
    #   = (v0^2 / a) + (v0^2 / 2a)
    #   = v0^2 / 2a
    # 求めたいのはv0なので、
    # v0 = sqrt(2a * D)
    v0 = math.sqrt(2 * a * distance_to_cup_meter)

    def x(t):
        # T秒後のボールの位置は
        # D = v0 * T + 1/2 * a * T^2
        # ただし減速なので
        xT = (v0 * t) - ((1/2) * a * (t ** 2))
        return xT

    xts = []
    T_stop = v0 / a
    for T in range(0, int(T_stop)):
        # ボールが1秒以内に止まるケースを考慮する
        # ボールが止まるまでの時間は
        # v(T) = v0 - a * T
        # このときの速度が0なので
        # v0 - a * T_stop = 0
        xT = x(T+1)
        xts.append(xT)
    return (xts, T_stop)

stimpmeter_feet = 9
meters = [0.5] + list(range(1, 21))
print(f"{stimpmeter_feet}フィートグリーンの場合:")
for m in meters:
    ball_positions_m, total_s = ball_at(9, m)
    print(f"  カップまで{m}m: 止まるまでの時間: {total_s:.2f}秒")
    print("\n".join([f"    {i+1}秒後のボール位置: {pos:.5f}m\t" for i, pos in enumerate(ball_positions_m)]))