Class: Charai::SplineDeceleration

Inherits:
Object
  • Object
show all
Defined in:
lib/charai/spline_deceleration.rb

Overview

ref: android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/OverScroller.java Converted using ChatGPT 4o

Usage: deceleration = SplineDeceleration.new(200) loop do

delta = deceleration.calc
sleep 0.016 # 60fps
break if delta.zero?

end

Constant Summary collapse

DECELERATION_RATE =
Math.log(0.78) / Math.log(0.9)
INFLEXION =
0.35
START_TENSION =
0.5
END_TENSION =
1.0
P1 =
START_TENSION * INFLEXION
P2 =
1.0 - END_TENSION * (1.0 - INFLEXION)
NB_SAMPLES =
100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_velocity) ⇒ SplineDeceleration

Returns a new instance of SplineDeceleration.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/charai/spline_deceleration.rb', line 24

def initialize(initial_velocity)
  @initial_velocity = initial_velocity
  @current_velocity = initial_velocity
  @physical_coeff = 1000
  @elapsed_time = 0 # 累積時間を管理
  @duration = calculate_duration
  @distance = calculate_distance
  @previous_position = 0 # 前回の位置を保持
  @current_position = 0

  # スプラインテーブルを構築
  @spline_position = Array.new(NB_SAMPLES + 1)
  @spline_time = Array.new(NB_SAMPLES + 1)
  build_spline_tables
end

Instance Attribute Details

#current_positionObject (readonly)

Returns the value of attribute current_position.



22
23
24
# File 'lib/charai/spline_deceleration.rb', line 22

def current_position
  @current_position
end

#current_velocityObject (readonly)

Returns the value of attribute current_velocity.



22
23
24
# File 'lib/charai/spline_deceleration.rb', line 22

def current_velocity
  @current_velocity
end

Instance Method Details

#calcObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/charai/spline_deceleration.rb', line 52

def calc
  @elapsed_time += 16 # 毎回16ms経過

  return 0 if @elapsed_time > @duration

  t = @elapsed_time.to_f / @duration
  distance_coef = interpolate_spline_position(t)
  @current_velocity = interpolate_spline_velocity(t)

  # 現在の位置を計算
  @current_position = (distance_coef * @distance).to_i

  # 16ms前の位置からのdeltaを計算
  delta_position = @current_position - @previous_position

  # 現在の位置を次回のために保存
  @previous_position = @current_position

  delta_position
end

#calculate_distanceObject



40
41
42
43
44
# File 'lib/charai/spline_deceleration.rb', line 40

def calculate_distance
  l = Math.log(INFLEXION * @initial_velocity.abs / @physical_coeff)
  decel_minus_one = DECELERATION_RATE - 1.0
  @physical_coeff * Math.exp(DECELERATION_RATE / decel_minus_one * l)
end

#calculate_durationObject



46
47
48
49
50
# File 'lib/charai/spline_deceleration.rb', line 46

def calculate_duration
  l = Math.log(INFLEXION * @initial_velocity.abs / @physical_coeff)
  decel_minus_one = DECELERATION_RATE - 1.0
  (1000.0 * Math.exp(l / decel_minus_one)).to_i
end