https://github.com/akicho8/equation
2つの範囲を相互変換するライブラリ
https://github.com/akicho8/equation
bezier-curves math math-library ruby
Last synced: 26 days ago
JSON representation
2つの範囲を相互変換するライブラリ
- Host: GitHub
- URL: https://github.com/akicho8/equation
- Owner: akicho8
- License: mit
- Created: 2013-11-16T09:54:56.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2017-01-13T10:46:22.000Z (over 9 years ago)
- Last Synced: 2025-03-02T05:41:15.491Z (over 1 year ago)
- Topics: bezier-curves, math, math-library, ruby
- Language: Ruby
- Homepage:
- Size: 236 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE.txt
Awesome Lists containing this project
README
#+OPTIONS: toc:nil num:nil author:nil creator:nil \n:nil |:t
#+OPTIONS: @:t ::t ^:t -:t f:t *:t <:t
* 2つの範囲を相互変換するライブラリ
- [[https://travis-ci.org/akicho8/equation][Travis]]: [[https://travis-ci.org/akicho8/equation.png]]
- [[https://gemnasium.com/akicho8/equation/][Gemnasium]]: [[https://gemnasium.com/akicho8/equation.png]]
- [[https://codeclimate.com/github/akicho8/equation][Code Climate]]: [[https://codeclimate.com/github/akicho8/equation.png]]
[[https://raw.github.com/akicho8/equation/master/examples/all_curve.png]]
[[https://raw.github.com/akicho8/equation/master/examples/linear_curve.png]]
[[https://raw.github.com/akicho8/equation/master/examples/parabola_curve.png]]
[[https://raw.github.com/akicho8/equation/master/examples/bezier_curve.png]]
[[https://raw.github.com/akicho8/equation/master/examples/bezier_curve_pull2.png]]
[[https://raw.github.com/akicho8/equation/master/examples/mix_curve.png]]
** 使用例
レベルの範囲が 1..99 で強さが 0..9999 の範囲を取るとき、直線の関係にある場合の、レベル30のときの強さは? またその値からレベルを求めるには?
#+BEGIN_SRC ruby
curve = Equation.create(type: :linear, x_range: 1..99, y_range: 0..9999)
v = curve.y_by_x(30) # => 2958.887755102041
curve.x_by_y(v) # => 30.0
#+END_SRC
レベルの範囲が 1..99 で経験値が 0..9999 の範囲を取るとき、放物線の関係にある場合の、レベル30のときの経験値は? またその値からレベルを求めるには?
#+BEGIN_SRC ruby
curve = Equation.create(type: :parabola, x_range: 1..99, y_range: 0..9999)
v = curve.y_by_x(30) # => 875.5892336526447
curve.x_by_y(v) # => 29.999999999999996
#+END_SRC
レベルの範囲が 1..99 で強さが 0..9999 の範囲を取るとき、左下(0,0)右上(1,1)を結ぶベジェ曲線の中央の制御点を左上に0.25移動させた曲線の関係にある場合の、レベル30のときの強さは? またその値からレベルを求めるには?
#+BEGIN_SRC ruby
curve = Equation.create(type: :bezier, x_range: 1..99, y_range: 0..9999, pull: 0.25)
v = curve.y_by_x(30) # => 6958.219471218414
curve.x_by_y(v) # => 29.99999999999998
#+END_SRC
** 間違えやすい所
*** 1. どれだけ経験値を足せば次のレベルになるかを求めるとき
#+BEGIN_SRC ruby
curve = Equation.create(type: :parabola, x_range: 1..99, y_range: 0..9999)
#+END_SRC
まず現在がレベル2でレベル3に移行したいのでそれぞれの必要経験値を求める。
#+BEGIN_SRC ruby
curve.y_by_x(2) # => 1.0411286963765098
curve.y_by_x(3) # => 4.164514785506039
#+END_SRC
両方を round してみると
#+BEGIN_SRC ruby
a = curve.y_by_x(2).round # => 1
b = curve.y_by_x(3).round # => 4
diff = b - a # => 3
(curve.y_by_x(2) + diff) # => 4.04112869637651
#+END_SRC
4.04 はレベル3のときの 4.16 を越えていない。
なお、truncate しても ceil しても diff が3になる時点でだめ。
同じメソッドで小数を削ってしまうのがだめ。
対策1
#+BEGIN_SRC ruby
a = curve.y_by_x(2).floor # => 1
b = curve.y_by_x(3).ceil # => 5
diff = b - a # => 4
(curve.y_by_x(2) + diff) # => 5.04112869637651
#+END_SRC
対策2
#+BEGIN_SRC ruby
a = curve.y_by_x(2) # => 1.0411286963765098
b = curve.y_by_x(3) # => 4.164514785506039
diff = (b - a).ceil # => 4
(curve.y_by_x(2) + diff) # => 5.04112869637651
#+END_SRC
対策3
#+BEGIN_SRC ruby
a = curve.y_by_x(2).ceil # => 2
b = curve.y_by_x(3).ceil # => 5
diff = b - a # => 3
(a + diff) # => 5
#+END_SRC
*** 2. 現在の経験値だとレベルはいくつか求めるとき
現在の経験値 1000 に対応するのはレベル32
#+BEGIN_SRC ruby
curve.x_by_y(1000).round # => 32
#+END_SRC
レベル32から経験値を確認すると、
#+BEGIN_SRC ruby
curve.y_by_x(32) # => 1000.5246772178259
#+END_SRC
現在の経験値 1000 が 1000.52 を越えていない。
正しい方法
#+BEGIN_SRC ruby
curve.x_by_y(1000).truncate # => 31
curve.y_by_x(31) # => 937.0158267388588
#+END_SRC
現在の経験値 1000 が 937.0 を越えている。
*** 【重要】まとめると──
- レベルから経験値を求める場合の y_by_x の結果は ceil
- 経験値からレベルを求める場合の x_by_y の結果は floor
これを使う側でいちいち補正するのも大変なのでモジュールにまとめてある。
Equation::Base に Equation::LevelSupport を include すれば lv_by_exp と exp_by_lv が使えるようになる。
(lv_by_exp と exp_by_lv は、それぞれ lv_by_value と value_by_lv にエイリアスしている)
#+BEGIN_SRC ruby
require 'equation/level_support'
Equation::Base.include(Equation::LevelSupport)
curve = Equation.create(type: :parabola, x_range: 1..99, y_range: 0..9999)
curve.lv_by_exp(1000) # => 31
curve.exp_by_lv(31) # => 938
curve.lv_by_exp(938) # => 31
#+END_SRC
経験値 1000 のときのレベルは 31 で、その 31 になるために必要な経験値は 938 で、938 あればレベル 31 になる。
** 不具合
- ベジェ曲線の pull が -0.3 のとき、垂直の直線との交点が取れない
NUTSU » [as]ベジェ曲線と直線の交点 http://nutsu.com/blog/2007/101701_as_bezjesegment3.html
の as で確認しても同様の現象になる。
とりあえず -0.3 を少しずらして -0.30001 などにすると交点が出てくる。