Old/sampou.org/ICFP2008
ICFP2008
sqsum x y = x^2 + y^2
- 中心座標 (x1,y1) 半径 r1 進行角度 th1 進行速度 v1 の物体ともう一つの物体が時間 t までの間にぶつかるかの判定関数。(t > 0 が前提)
- 軌跡は直線じゃないので役に立たなそう。直線じゃないと積分使わないとダメかな。
f ((x1,y1),r1,th1,v1) ((x2,y2),r2,th2,v2) t = distance2 t' <= (r1+r2)^2 where
vx = v1 * cos th1 - v2 * cos th2
vy = v1 * sin th1 - v2 * sin th2
distance2 u = sqsum (x1+u*vx-x2) (y1+u*vy-y2)
vv = sqsum vx vy
t' = if (vv == 0) then 0 else max 0 (min t s)
- ハンドル角度一定のときの軌跡
toRad x = x / 180 * pi
-- f 座標 速度 加速度 向き ハンドル角度
maxSpeed = 20.0
accel = 2.0
k = accel / maxSpeed^2
n = 10 -- 1秒の分割数
-- シンプソンを使ってみた
foo (x,y) s a dir th = iterate f ((x,y),s,dir) where
dt = 0.5 / n
f ((x,y),s,dir) = ((x',y'),s',dir') where
g (s,dir) = (max 0 $ s + dt*(a - k*s^2), dir + th * dt)
[email protected](_:_:(s',dir'):[]) = take 3 $ iterate g (s,dir)
h (s,dir) = let rad = toRad dir in (s * cos rad, s * sin rad)
[(x0,y0),(x1,y1),(x2,y2)] = map h sdirs
x' = x + (x0 + 4*x1 + x2) / 3 * dt
y' = y + (y0 + 4*y1 + y2) / 3 * dt
{-
-- Hard Right でスピード加速
> take 10 $ foo (-24.96,25.04) 0.2 2.0 (-60.0)
-- Hard Left でブレーキング
> take 10 $ foo (-0.804,-6.552) 15.342 (-3.0) (-4.5) 60.0
-}
- 加速0のときのt秒後のスピード
c = 1 / s(0) -- 初速の逆数
s(t) = 1 / (k*t + c)
- 加速a > 0 のときのt秒後のスピード
- ds/dt = a - k*s^2 を解いたつもり
- 検証あまりしてない
a2 = sqrt(a)
k2 = sqrt(k)
s0 = s(0)
c = log |(a2+k2*s0)/(a2-k2*s0)| / (2*a2*k2)
s(t) = a2/k2 * tanh(2*a2*k2*(t+c))
- 加速a < 0 のときのt秒後のスピード
- 検証あまりしてない
a2 = sqrt(-a)
k2 = sqrt(k)
s0 = s(0)
c = atan(s0*k2/a2) / (a2*k2)
s(t) = -a2/k2 * tan(a2*k2*(t+c))
Last modified : 2008/07/23 21:26:33 JST