線形グラデスクリプト
https://scrapbox.io/files/661b3659ad10220024063715.png
線分と点の距離
$ \vec{a},\vec{b}から成る線分と、位置ベクトル$ \vec{P}の距離は以下のようになります。
$ \begin{aligned}\vec{v}&=\dfrac{1}{|\vec{b}-\vec{a}|}(\vec{b}-\vec{a})\\\vec{r}&=\vec{P}-\vec{a}\\\vec{n}&=\vec{v}(\vec{r}\cdot\vec{v})+\vec{a}\\d&=|\vec{n}-\vec{P}|\end{aligned}
$ \vec{v}は線分のベクトル方向、
$ \vec{n}は位置ベクトル$ \vec{P}と一番近い線分の位置、
$ dは線分と点の距離です。
「線分と点の距離」のように調べるといろいろでてきます。 スクリプト
2点から成る線分からの距離で重みを付けるグラデーションスクリプトです。
code:線形グラデ_M.lua
--[[
線形グラデ_M.anm
グラデーションスクリプトです。
]]
--track0:a0,0,100,100,0.01
--track1:a1,0,100,100,0.01
--track2:a2,0,100,100,0.01
--track3:a3,0,100,100,0.01
--dialog:set_anchor,pos={-200,-200,-100,-100,-200,200,-100,100,200,200,100,100,200,-200,100,-100};色1/col,local ca=0x79f6f6;色2/col,local cb=0xa4ffa4;色3/col,local cc=0xfaff4f;色4/col,local cd=0x5191dd;
local function norm(x,y)
return math.sqrt(x*x+y*y)
end
local function setup(x0,y0,x1,y1)
if(x0>x1)then x1,y1,x0,y0=x0,y0,x1,y1 end
local r={x0,y0,x1,y1}
local v={x1-x0,y1-y0}
if(v1==0 and v2==0)then return {r=r,v={0,0}} end return {r=r,v={v1/d,v2/d}} end
local function compute(x,y,s)
local dot=(x-s.r1)*s.v1+(y-s.r2)*s.v2 local dx,dy=s.v1*dot+s.r1,s.v2*dot+s.r2 if(dx<s.r1)then dx,dy=s.r1,s.r2 elseif(dx>s.r3)then dx,dy=s.r3,s.r4 end
if(s.r2>s.r4)then s.r3,s.r4,s.r1,s.r2=s.r1,s.r2,s.r3,s.r4 end if(dy<s.r2)then dx,dy=s.r1,s.r2 elseif(dy>s.r4)then dx,dy=s.r3,s.r4 end
end
local d=norm(dx-x,dy-y)
if(d<=0.001)then return 1000000
else return 1/(d*d)
end
end
local function fade(a,b,t)
return (b-a)*t
end
local function ceil(d)
return math.min(math.max(math.floor(d+0.5),0),255)
end
obj.setanchor("pos",8)
for i=0,7 do
end
local s0,s1,s2,s3
s0=setup(pos1,pos2,pos3,pos4) s1=setup(pos5,pos6,pos7,pos8) local a0,a1,a2,a3=obj.track0/100,obj.track1/100,obj.track2/100,obj.track3/100
local car,cag,cab=RGB(ca)
local cbr,cbg,cbb=RGB(cb)
local ccr,ccg,ccb=RGB(cc)
local cdr,cdg,cdb=RGB(cd)
local data,w,h=obj.getpixeldata()
local ffi=require("ffi")
pcall(ffi.cdef,typedef struct Pixel_ {uint8_t b,g,r,a;} Pixel;)
local cdata=ffi.cast("Pixel*",data)
for y=0,h-1 do
for x=0,w-1 do
local len={compute(x,y,s0),compute(x,y,s1),compute(x,y,s2),compute(x,y,s3)}
local total=len1+len2+len3+len4 len1,len2,len3,len4=a0*len1/total,a1*len2/total,a2*len3/total,a3*len4/total cdata.r=ceil(cdata.r+fade(cdata.r,car,len1)+fade(cdata.r,cbr,len2)+fade(cdata.r,ccr,len3)+fade(cdata.r,cdr,len4)) cdata.g=ceil(cdata.g+fade(cdata.g,cag,len1)+fade(cdata.g,cbg,len2)+fade(cdata.g,ccg,len3)+fade(cdata.g,cdg,len4)) cdata.b=ceil(cdata.b+fade(cdata.b,cab,len1)+fade(cdata.b,cbb,len2)+fade(cdata.b,ccb,len3)+fade(cdata.b,cdb,len4)) cdata=cdata+1
end
end
obj.putpixeldata(data)
2024/12/04 アンカーが同じ座標にある場合の処理を追加
by metaphysical bard