稲妻を描いてみた。

手前味噌ですが。sp.dllを使って稲妻を描けないかやってみた。

zigzag.lua

-- zigzag.lua
do
	local int = math.floor
	local sin = math.sin
	local cos = math.cos
	local sqr = math.sqrt
	local pi  = math.pi
	local dice = math.random

	-- 2点間の距離を計算する。
	local distance = function(sp, ep)
		local res = {}
		for i, v in ipairs(sp) do res[i] = v - ep[i] end
		for i, v in ipairs(res) do res[i] = v * v end
		local ret = 0
		for i, v in ipairs(res) do ret = ret + res[i] end
		return sqr(ret)
	end

	-- 2点間の中間点を計算する。
	local middle = function(sp, ep)
		local res = {}
		for i, v in ipairs(sp) do res[i] = (v + ep[i])/2 end
		return res
	end
	
	function zigzag(res, param, max_depth, depth)
		param = param or 50 -- どれくらいよれるか、デフォルトは50%
		depth = depth or 0 -- 深さの指定がなければ0
		-- これで最後なら、何もせずに終わる。
		if depth == max_depth then return res end
		-- そうでなければ計算する。
		local end_point = table.remove(res) -- このループでの終点を取得。
		local start_point = res[#res] -- このループでの始点を取得。
		-- 仮の中間点を作成
		local middle_point = middle(start_point, end_point)
		-- 中間点と始点との距離を計算する。
		local dis = distance(start_point, middle_point)
		-- 中間点をどれだけずらすか計算する。
		local rad = dice()*pi*2 -- 角度
		local length = dice(0, int(dis*param/2))
		-- 中間点をずらす。
		middle_point[1] = int(middle_point[1] + cos(rad)*length/100)
		middle_point[2] = int(middle_point[2] + sin(rad)*length/100)
		
		-- 後処理
		res[1+#res] = middle_point
		if max_depth>depth then zigzag(res, param, max_depth, depth+1) end
		res[1+#res] = end_point
		if max_depth>depth then zigzag(res, param, max_depth, depth+1) end
		return res
	end
end

このスクリプトをsystem.luaから読み込んでおく。

system.lua

-- system.lua
NL_dofile("zigzag.lua")

NSExec("luasub zigzag")
function NSCOM_zigzag()
	local ret = NSPopStrRef()
	NSPopComma()
	local x1 = NSPopInt()
	NSPopComma()
	local y1 = NSPopInt()
	NSPopComma()
	local x2 = NSPopInt()
	NSPopComma()
	local y2 = NSPopInt()
	NSPopComma()
	local param = NSPopInt()
	NSPopComma()
	local depth = NSPopInt()

	local res = zigzag({
			{x1, y1},
			{x2, y2}
		},
		param,
		depth
	)
	local str = ""
	for i, v in ipairs(res) do
		str = str .. ","
		str = str .. tostring(v[1])
		str = str .. ","
		str = str .. tostring(v[2])
	end
	NSSetStrValue(ret , str)
end

zigzag命令が、NScripter側に作られる。

00.txt

*define
deletemenu
game

*start
lsp 0,":m>640,480,#FFFFFF;>640,480,#00FFFF",0,0
for %0=1 to 10
	itoa $0,%0
	zigzag $1,20,20,620,460,50,%0
	exec_dll "sp.dll/fill,0,0,1,255,255,255"
	exec_dll "sp.dll/line,0,0,1,0,0,0"+$1
	exec_dll "sp.dll/burst,0,0,1,20,20,2,2"
	repaint
	print 1
	getscreenshot 640,480
	savescreenshot "lightning"+$0+".bmp"
next
end

使い方

zigzag命令は下記の書式

zigzag $結果を受け取る文字列変数,(始点x),(始点y),(終点x),(終点y),(ぶれの大きさ),(折れ回数)

始点と終点の間をゴキゴキ折れながらつないでいく点の座標をまとめて文字列にして返します。
サンプルを見ればわかるとおり、作られた文字列は、sp.dllのline/polylineに渡すことができます。
ちなみに折れ回数が10を超えると、文字列が長すぎるエラーが出る可能性があります。
折れ回数は10にすると10回折れるのかと言えばそうではなく、2^10回折れるの意味になります。

ぶれの大きさについて

折れ回数を8に固定して、ぶれの大きさが10、95、150、200の時に比較してみました。

10の時


ほとんど直線。

95の時

150の時

200の時


ちょっとやりすぎ?