TI-Nspire & Lua / スクリプティングのヒント / 自作の描画函数も出来合いの描画函数と同じように実行できるようにする

参考: http://adriweb.free.fr/t3/2013/Powerpoint_Advanced_TI-Nspire_Lua_Programming.pptx, p.25

--[[普通の方法
function drawCircle(centerX, centerY, radius, gc) -- 中心座標で円を描くための自作函数
   local diameter = radius + radius
   gc:drawArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
end
function fillCircle(centerX, centerY, radius, gc) -- 中心座標で円を塗りつぶすための自作函数
   local diameter = radius + radius
   gc:fillArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
end

function on.paint(gc) -- 出来合いの描画函数と実行方法が揃わない。
   drawCircle(10,10,10,gc)
   fillCircle(50,50,10,gc)
   gc:drawRect(20,20,20,20)
   gc:fillRect(120,120,20,20)
end
--]]

---[[特殊な方法
function drawCircle(gc, centerX, centerY, radius) -- 中心座標で円を描くための自作函数
   local diameter = radius + radius
   gc:drawArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
end
function fillCircle(gc, centerX, centerY, radius) -- 中心座標で円を塗りつぶすための自作函数
   local diameter = radius + radius
   gc:fillArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
end

platform.withGC(getmetatable)["drawCircle"] = drawCircle
platform.withGC(getmetatable)["fillCircle"] = fillCircle

function on.paint(gc) -- 出来合いの描画函数と同じように実行できる。
   gc:drawCircle(10,10,10)
   gc:fillCircle(50,50,10)
   gc:drawRect(20,20,20,20)
   gc:fillRect(120,120,20,20)
end
--]]

--[[だから自作描画函数は最初から次のように定義しておけば見づらくとも手間が省ける。
platform.withGC(getmetatable)["drawCircle"] = function(gc, centerX, centerY, radius)
                                                 local diameter = radius + radius
                                                 gc:drawArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
                                              end
platform.withGC(getmetatable)["fillCircle"] = function(gc, centerX, centerY, radius)
                                                 local diameter = radius + radius
                                                 gc:fillArc(centerX - radius, centerY - radius, diameter, diameter, 0, 360)
                                              end
--]]

f:id:ti-nspire:20170224120718p:plain:h315

TI-Nspire & Lua / スクリプティングのヒント / Nspire 側の変数を Lua に呼ぶときは on.timer() 内で var.recall() を使うのではなく var.monitor() と on.varChange() とを使う

参考:




.lua

--[[方法 1. on.timer() 内で var.recall() を使う
local slider1 = nil
function on.construction()
   on.timer() -- 最初に Nspire 側の変数の初期値を呼んでから
   timer.start(0.1) -- タイマーをスタートする。
end
function on.timer()
   slider1 = var.recall("slider1") -- タイマーの tick するたびに Nspire 側の変数の現在の値を lua に呼ぶ。
end
function on.paint(gc)
   gc:fillRect(0, 25, slider1, 10) 
end
--]]


---[[方法 2. var.monitor() と on.varChange() とを使う
local slider1 = nil
function on.construction()
   on.varChange() -- 最初に Nspire 側の変数の初期値を呼んでから
   var.monitor("slider1") -- その変数を監視対象にする。
end
function on.varChange()
   slider1 = var.recall("slider1") -- 監視対象の Nspire 側変数が変化したら lua に呼ぶ。
end
function on.paint(gc)
   gc:fillRect(0, 25, slider1, 10) 
end
--]]


.tns
slider1.tns - Google ドライブ

TI-Nspire & Lua / スクリプティングのヒント / メタテーブルを使う 9 of 9 / メモ化する

参考:

-- 竹内函数を定義する。これをメモ化してみる。
function tarai(x, y, z)
   if x <= y then
      return y
   else
      return tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y))
   end
end 

-- メモ化函数を定義する。
function memorize(func)
   local mem = {} -- 計算結果を記憶しておくためのテーブルを用意する。
   setmetatable(mem, {__mode = "v"}) -- そのテーブルを「(値の) 弱いテーブル」にする。弱いテーブルにする意味は今回はあまりない。
   return function(...)
              -- 引数をキーとして過去の計算結果を参照し、
              -- 計算結果が見つかればそれを返す。
              -- 見つからなければ新たに計算して返すとともに記憶しておく。
             local key = table.concat({...}, ",") 
             local result = mem[key]
             if result == nil then
                result = func(...)
                mem[key] = result
             end
             return result
          end
end

------------------
-- 確かめてみる --
------------------
-- メモ化しない場合:
do
local startTime = timer.getMilliSecCounter()
local a = tarai(12,6,0)
local stopTime = timer.getMilliSecCounter()
local elapsedTime = stopTime - startTime
print("case 1. output: "..a..", elapsed time: "..elapsedTime.." msec")
end

-- メモ化した場合:
tarai = memorize(tarai)
do
local startTime = timer.getMilliSecCounter()
local a = tarai(12,6,0)
local stopTime = timer.getMilliSecCounter()
local elapsedTime = stopTime - startTime
print("case 2. output: "..a..", elapsed time: "..elapsedTime.." msec")
end

-- メモ化した竹内函数をもう一度同じ初期値で計算した場合:
do
local startTime = timer.getMilliSecCounter()
local a = tarai(12,6,0)
local stopTime = timer.getMilliSecCounter()
local elapsedTime = stopTime - startTime
print("case 3. output: "..a..", elapsed time: "..elapsedTime.." msec")
end

f:id:ti-nspire:20170219103427p:plain