A
download sgl-spring.rb
Language: Ruby
Copyright: (C) 2004-2005 Kouichirou Eto, All rights reserved.
LOC: 166
Project Info
etocom project(etocom)
Server: RubyForge (SVN)
Type: svn
...s\REL‑start_newgem\sgl\sgl\
   cocoa-app.rb
   cocoa-color.rb
   cocoa-draw.rb
   cocoa-event.rb
   cocoa-media.rb
   cocoa-notuse.rb
   cocoa-window.rb
   cocoa.rb
   make-release.rb
   opengl-app.rb
   opengl-color.rb
   opengl-draw.rb
   opengl-event.rb
   opengl-modules.rb
   opengl-window.rb
   opengl.rb
   qp.rb
   sgl-bass.rb
   sgl-button.rb
   sgl-spring.rb
   test-cocoa-app.rb
   test-opengl-app.rb

# Copyright (C) 2004-2005 Kouichirou Eto, All rights reserved.

$LOAD_PATH.unshift("..") if !$LOAD_PATH.include?("..")

module SGL
  # not yet.
  module SpringModule
  end

  class Spring
    EPSILON = 0.01

    # ڕWƂȂlAlAol萔Ae萔ACvV(\l)
    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
    # ڕWƂȂlAlAol萔Ae萔ACvV(\l)
    def initialize(target, initial, ks, kd, e=EPSILON, v=0)
      super(target, initial, 1.0/ks, 1.0/kd, e, v) # kskdinverseB
    end
  end

  class NumSpring
    EPSILON = 0.01

    # ڕWƂȂlAlAol萔Ae萔ACvV(\l)
    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
    # ڕWƂȂlAlAol萔Ae萔ACvV(\l)
    def initialize(target, initial, ks, kd, e=EPSILON, v=0)
      super(target, initial, ks, 1.0 - 1.0/kd, e, v) # kdinverseB
    end
  end
end

class NuSpringPos
  EPSILON = 0.01

  # lAڕWƂȂlAol萔Ae萔ACvV(\l)
  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

  # ڕWƂȂlAlAol萔Ae萔ACvV(\l)
  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

if $0 == __FILE__
  require "test/unit"
  $test = true
end

if defined?($test) && $test
  class TestSglSpring < Test::Unit::TestCase
    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
83

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us