lib/sgl/sgl-spring.rb in sgl-0.4.0 vs lib/sgl/sgl-spring.rb in sgl-1.0.0

- old
+ new

@@ -1,216 +1,216 @@ -# Copyright (C) 2004-2007 Kouichirou Eto, All rights reserved. -# License: Ruby License - -$LOAD_PATH.unshift("..") if !$LOAD_PATH.include?("..") - -module SGL -=begin - # not yet. - module SpringModule - end -=end - - class Spring - EPSILON = 0.01 - - # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(target, initial, ks, kd, e=EPSILON, v=0) - @target, @initial, @ks, @kd, @e, @v = target, initial, ks, kd, e, v - @x = @initial - @moving = true - end - - attr_reader :x, :target - attr_accessor :v, :ks, :kd - - def inspect - mov = @moving ? "●" : "○" - sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) - end - - def target=(num) - @target = num - @moving = true - end - - def x=(num) - @x = num - @moving = true - end - - def move - return if ! @moving - if @x.is_a?(Vector) - l = @x - @target - diff = l.length - if diff < @e && @v.length < @e - @moving = false - return - end - #fa = -(@ks * diff + @kd * @v) - ln = l.normalize - fak = -(@ks * diff + @kd * @v.length) - fa = ln.scale(fak) - @v += fa - @x += @v - #p ['sp', fa, fak, @v, @x] - else - diff = @x - @target - if diff.abs < @e && @v.abs < @e - @moving = false - return - end - fa = -(@ks * diff + @kd * @v) - @v += fa - @x += @v - end - end - end - - class ISpring < Spring - # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(target, initial, ks, kd, e=EPSILON, v=0) - super(target, initial, 1.0/ks, 1.0/kd, e, v) # ksとkdをinverseする。 - end - end - - class NumSpring - EPSILON = 0.01 - - # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(target, initial, ks, kd, e=EPSILON, v=0) - @target, @initial, @ks, @kd, @e, @v = target, initial, ks, kd, e, v - @x = @initial - @moving = true - end - - attr_reader :x, :target - attr_accessor :v, :ks, :kd, :moving - - def inspect - mov = @moving ? "●" : "○" - sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) - end - - def target=(num) - @target = num - @moving = true - end - - def x=(num) - @x = num - @moving = true - end - - def move - return if ! @moving - diff = @target - @x - if diff.abs < @e && @v.abs < @e - @moving = false - return - end - @v += (diff / @ks) - @v *= @kd - @x += @v - end - end - - class INumSpring < NumSpring - # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(target, initial, ks, kd, e=EPSILON, v=0) - super(target, initial, ks, 1.0 - 1.0/kd, e, v) # kdだけinverseする。 - end - end -end - -=begin -class NuSpringPos - EPSILON = 0.01 - - # 初期値、目標となる値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(x, y, ks, kd, e=EPSILON) - @x, @y, @ks, @kd, @e = x, y, ks, kd, e - @vx, @vy, @tx, @ty = 0, 0, 0, 0 - @moving = true - end - - attr_reader :x, :y, :moving - - def set_target(tx, ty) - @tx, @ty = tx, ty - end - - def move - return if ! @moving - - #diff = @target - @x - diff = @tx - @x - if diff.abs < @e && @v.abs < @e - @moving = false - return - end - @v += (diff / @ks) - @v *= @kd - @x += @v - end -end - -class NuNumSpring - EPSILON = 0.01 - - # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) - def initialize(target, initial, ks, kd, e=EPSILON) - @target, @initial, @ks, @kd, @e = target, initial, ks, kd, e - @x = @initial - @v = 0 - @moving = true - end - - attr_reader :v - attr_accessor :x, :target, :moving, :ks, :kd - - def inspect - mov = @moving ? "●" : "○" - sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) - end - - def move - return if ! @moving - diff = @target - @x - if diff.abs < @e && @v.abs < @e - @moving = false - return - end - @v += (diff / @ks) - @v *= @kd - @x += @v - end - - def rel_ks_notuse(r) - @ks += r - @ks = 1 if @ks <= 0 - end -end -=end - -if $0 == __FILE__ - require "test/unit" - $__test_sgl__ = true -end - -if defined?($__test_sgl__) && $__test_sgl__ - class TestSglSpring < Test::Unit::TestCase #:nodoc: - def test_all - - s = SGL::NumSpring.new(0, 1, 0.1, 0.1) - assert_equal(1, s.x) - assert_equal(true, s.moving) - - s.move - assert_equal(0.0, s.x) - - s.move - assert_equal(-0.1, s.x) - end - end -end +# Copyright (C) 2004-2007 Kouichirou Eto, All rights reserved. +# License: Ruby License + +$LOAD_PATH.unshift("..") if !$LOAD_PATH.include?("..") + +module SGL +=begin + # not yet. + module SpringModule + end +=end + + class Spring + EPSILON = 0.01 + + # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(target, initial, ks, kd, e=EPSILON, v=0) + @target, @initial, @ks, @kd, @e, @v = target, initial, ks, kd, e, v + @x = @initial + @moving = true + end + + attr_reader :x, :target + attr_accessor :v, :ks, :kd + + def inspect + mov = @moving ? "●" : "○" + sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) + end + + def target=(num) + @target = num + @moving = true + end + + def x=(num) + @x = num + @moving = true + end + + def move + return if ! @moving + if @x.is_a?(Vector) + l = @x - @target + diff = l.length + if diff < @e && @v.length < @e + @moving = false + return + end + #fa = -(@ks * diff + @kd * @v) + ln = l.normalize + fak = -(@ks * diff + @kd * @v.length) + fa = ln.scale(fak) + @v += fa + @x += @v + #p ['sp', fa, fak, @v, @x] + else + diff = @x - @target + if diff.abs < @e && @v.abs < @e + @moving = false + return + end + fa = -(@ks * diff + @kd * @v) + @v += fa + @x += @v + end + end + end + + class ISpring < Spring + # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(target, initial, ks, kd, e=EPSILON, v=0) + super(target, initial, 1.0/ks, 1.0/kd, e, v) # ksとkdをinverseする。 + end + end + + class NumSpring + EPSILON = 0.01 + + # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(target, initial, ks, kd, e=EPSILON, v=0) + @target, @initial, @ks, @kd, @e, @v = target, initial, ks, kd, e, v + @x = @initial + @moving = true + end + + attr_reader :x, :target + attr_accessor :v, :ks, :kd, :moving + + def inspect + mov = @moving ? "●" : "○" + sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) + end + + def target=(num) + @target = num + @moving = true + end + + def x=(num) + @x = num + @moving = true + end + + def move + return if ! @moving + diff = @target - @x + if diff.abs < @e && @v.abs < @e + @moving = false + return + end + @v += (diff / @ks) + @v *= @kd + @x += @v + end + end + + class INumSpring < NumSpring + # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(target, initial, ks, kd, e=EPSILON, v=0) + super(target, initial, ks, 1.0 - 1.0/kd, e, v) # kdだけinverseする。 + end + end +end + +=begin +class NuSpringPos + EPSILON = 0.01 + + # 初期値、目標となる値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(x, y, ks, kd, e=EPSILON) + @x, @y, @ks, @kd, @e = x, y, ks, kd, e + @vx, @vy, @tx, @ty = 0, 0, 0, 0 + @moving = true + end + + attr_reader :x, :y, :moving + + def set_target(tx, ty) + @tx, @ty = tx, ty + end + + def move + return if ! @moving + + #diff = @target - @x + diff = @tx - @x + if diff.abs < @e && @v.abs < @e + @moving = false + return + end + @v += (diff / @ks) + @v *= @kd + @x += @v + end +end + +class NuNumSpring + EPSILON = 0.01 + + # 目標となる値、初期値、バネ定数、弾性定数、イプシロン(十分小さい値) + def initialize(target, initial, ks, kd, e=EPSILON) + @target, @initial, @ks, @kd, @e = target, initial, ks, kd, e + @x = @initial + @v = 0 + @moving = true + end + + attr_reader :v + attr_accessor :x, :target, :moving, :ks, :kd + + def inspect + mov = @moving ? "●" : "○" + sprintf("[%s%.1f %.1f %.1f %.1f %.1f]", mov, @target, @x, @v, @ks, @kd) + end + + def move + return if ! @moving + diff = @target - @x + if diff.abs < @e && @v.abs < @e + @moving = false + return + end + @v += (diff / @ks) + @v *= @kd + @x += @v + end + + def rel_ks_notuse(r) + @ks += r + @ks = 1 if @ks <= 0 + end +end +=end + +if $0 == __FILE__ + require "test/unit" + $__test_sgl__ = true +end + +if defined?($__test_sgl__) && $__test_sgl__ + class TestSglSpring < Test::Unit::TestCase #:nodoc: + def test_all + + s = SGL::NumSpring.new(0, 1, 0.1, 0.1) + assert_equal(1, s.x) + assert_equal(true, s.moving) + + s.move + assert_equal(0.0, s.x) + + s.move + assert_equal(-0.1, s.x) + end + end +end