【Aegisub】上篇代碼

????????因為現(xiàn)在b站評論顯示不出""引號和大于小于符號,所以就把上一篇專欄對應的代碼發(fā)在這里,同時也是這個視頻對應的代碼
function?Xshape.isZero(d)
????return?(d>-1e-6?and?d<1e-6)
end
function?Xshape.cuberoot(x)
????return?(x>0)?and?math.pow(x,(1/3))?or?-math.pow(math.abs(x),(1/3))
end
function?Xshape.solveQuadric(c0,c1,c2)
????if?Xshape.isZero(c0)?then
????????if?Xshape.isZero(c1)?then
????????????return?nil
????????else
????????????return?-c2/c1
????????end
????end
????local?p,q=c1/(2*c0),c2/c0?local?D=p^2-q
????if?Xshape.isZero(D)?then
????????return?-p
????elseif?D<0?then
????????return
????else
????????local?sqrt_D=math.sqrt(D)
????????return?sqrt_D-p,-sqrt_D-p
????end
end
function?Xshape.solveCubic(c0,c1,c2,c3)
????if?Xshape.isZero(c0)?then
????????return?Xshape.solveQuadric(c1,c2,c3)
????end
????local?s0,s1,s2
????local?A,B,C=c1/c0,c2/c0,c3/c0
????local?p,q=(1/3)*(-(1/3)*A^2+B),0.5*((2/27)*A^3-(1/3)*A*B+C)
????local?D=q^2+p^3?local?sub=(1/3)*A?local?n,a,b,c=c0*1000,c1*1000,c2*1000,c3*1000
????local?is_pZero=b==a^2/(n*3)?local?is_qZero=9*n*a*b-2*a^3==27*n*c?local?isDZero=is_qZero?and?is_pZero
????if?isDZero?then
????????if?is_qZero?then
????????????s0=-sub
????????else
????????????local?u=Xshape.cuberoot(-q)
????????????s0=2*u-sub?s1=-u-sub
????????end
????elseif?D<0?then
????????local?phi=(1/3)*math.acos(-q/math.sqrt(-p^3))
????????local?t=2*math.sqrt(-p)
????????local?n1,n2=-t*math.cos(phi+math.pi/3)-sub,-t*math.cos(phi-math.pi/3)-sub
????????s0=t*math.cos(phi)-sub
????????if?math.round(n1,5)~=math.round(s0,5)?then
????????????s1=n1
????????end
????????if?s1?then
????????????if?math.round(n2,5)~=math.round(s0,5)?and?math.round(n2,5)~=math.round(s1,5)?then
????????????????s2=n2
????????????end
????????else
????????????if?math.round(n2,5)~=math.round(s0,5)?then
????????????????s2=n2
????????????end
????????end
????else
????????local?sqrt_D=math.sqrt(D)
????????local?u=Xshape.cuberoot(sqrt_D-q)
????????local?v=-Xshape.cuberoot(sqrt_D+q)
????????s0=u+v-sub
????????if?math.round(s0,5)~=0?and?math.round(s0,5)~=1?then
????????????if?Xshape.isZero(c0+c1+c2+c3)?then
????????????????s1=1
????????????elseif?Xshape.isZero(c3)?then
????????????????s1=0
????????????end
????????end
????end
????return?s0,s1,s2
end
繪圖轉(zhuǎn)像素:
function?Xshape.get_px(ass_shape,d)
????local?_,T,_,B=Xshape.bounding(ass_shape)?local?px,each,iscet={},{}?local?step=d?and?0.5?or?1
????local?function?line(x1,y1,x2,y2,y)
????????local?top,bottom=math.min(y1,y2),math.max(y1,y2)
????????if?y>=top?and?y<bottom?and?bottom-top>1e-4?then
????????????iscet[#iscet+1]={x1+((x2-x1)/(y2-y1))*(y-y1),Xshape.sgn(y2-y1)}
????????end
????end
????local?function?isTop(y1,y2,y3,y4)
????????local?y={y1,y2,y3,y4}
????????for?i=1,3?do
????????????if?y[i]<y[i+1]?then
????????????????return?1
????????????elseif?y[i]>y[i+1]?then
????????????????return?0
????????????end
????????end
????????return?0
????end
????local?function?ignore_max_extreme_pt(x1,y1,y2,y3,x4,y4,t)
????????if?t==0?then
????????????iscet[#iscet+1]={x1,isTop(y1,y2,y3,y4)}
????????elseif?t==1?then
????????????iscet[#iscet+1]={x4,-isTop(y4,y3,y2,y1)}
????????end
????end
????local?function?count(x1,y1,x2,y2,x3,y3,x4,y4,t)
????????if?t?then
????????????t=math.round(t,5)
????????????if?t<1?and?t>0?then
????????????????local?ang=-Xshape.angle_at(t,x1,y1,x2,y2,x3,y3,x4,y4)
????????????????iscet[#iscet+1]={Xshape.cubic_bezier(x1,x2,x3,x4,t),Xshape.sgn(ang%180==0?and?0?or?ang)}
????????????else?ignore_max_extreme_pt(x1,y1,y2,y3,x4,y4,t)
????????????end
????????end
????end
????local?function?bezier(x1,y1,x2,y2,x3,y3,x4,y4,y)
????????local?top,bottom=math.min(y1,y2,y3,y4),math.max(y1,y2,y3,y4)
????????local?left,right=math.min(x1,x2,x3,x4),math.max(x1,x2,x3,x4)
????????if?right-left<1e-4?then
????????????line(x1,y1,x4,y4,y)
????????else
????????????if?y>=top?and?y<=bottom?and?bottom-top>1e-4?then
????????????????local?a,b,c,d=math.round(3*y2+y4-3*y3-y1,5),math.round(3*y1-6*y2+3*y3,5),math.round(3*y2-3*y1,5),math.round(y1,5)
????????????????local?t1,t2,t3=Xshape.solveCubic(a,b,c,d-y)
????????????????count(x1,y1,x2,y2,x3,y3,x4,y4,t1)?count(x1,y1,x2,y2,x3,y3,x4,y4,t2)?count(x1,y1,x2,y2,x3,y3,x4,y4,t3)
????????????end
????????end
????end
????for?m?in?ass_shape:gmatch('m[^m]+')?do
????????local?cmd={}
????????for?mlb?in?m:gmatch('[mlb][-.?%d]+')?do
????????????local?pt={}
????????????for?num?in?mlb:gmatch('([-.%d]+)')?do
????????????????pt[#pt+1]=num*1
????????????end
????????????cmd[#cmd+1]=pt
????????end
????????if?cmd[1][1]~=cmd[#cmd][#cmd[#cmd]-1]?or?cmd[1][2]~=cmd[#cmd][#cmd[#cmd]]?then
????????????cmd[#cmd+1]={cmd[1][1],cmd[1][2]}
????????end
????????for?i=1,#cmd-1?do
????????????if?#cmd[i+1]==2?then
????????????????each[#each+1]={cmd[i][#cmd[i]-1],cmd[i][#cmd[i]],cmd[i+1][1],cmd[i+1][2]}
????????????else
????????????????each[#each+1]={cmd[i][#cmd[i]-1],cmd[i][#cmd[i]],cmd[i+1][1],cmd[i+1][2],cmd[i+1][3],cmd[i+1][4],cmd[i+1][5],cmd[i+1][6]}
????????????end
????????end
????end
????for?y=T,B,step?do
????????iscet={}?local?cnt=0
????????for?i=1,#each?do
????????????if?#each[i]==4?then
????????????????line(each[i][1],each[i][2],each[i][3],each[i][4],math.round(y*1,3))
????????????else?bezier(each[i][1],each[i][2],each[i][3],each[i][4],each[i][5],each[i][6],each[i][7],each[i][8],math.round(y*1,3))
????????????end
????????end
????????table.sort(iscet,function?(a,b)?return?a[1]<b[1]?end)
????????for?i=1,#iscet-1?do
????????????cnt=cnt+iscet[i][2]
????????????if?cnt~=0?then
????????????????for?x=math.round(iscet[i][1]),math.round(iscet[i+1][1])-1?do
????????????????????px[#px+1]={x=x,y=math.round(y)}
????????????????end
????????????end
????????end
????end
????return?px
end
判斷點包含:
function?Xshape.contains_pt(ass_shape,pt_x,pt_y)
????local?cnt=0?local?pt_x,pt_y=math.round(pt_x*1,3),math.round(pt_y*1,3)
????local?function?line_isect_cnt(x1,y1,x2,y2,y)
????????local?top,bottom=math.min(y1,y2),math.max(y1,y2)
????????if?y>=top?and?y<bottom?and?bottom-top>1e-4?then
????????????local?x=x1+((x2-x1)/(y2-y1))*(y-y1)
????????????if?x?and?x<=pt_x?then
????????????????cnt=cnt+Xshape.sgn(y2-y1)
????????????end
????????end
????end
????local?function?isTop(y1,y2,y3,y4)
????????local?y={y1,y2,y3,y4}
????????for?i=1,3?do
????????????if?y[i]<y[i+1]?then
????????????????return?1
????????????elseif?y[i]>y[i+1]?then
????????????????return?0
????????????end
????????end
????????return?0
????end
????local?function?ignore_max_extreme_pt(x1,y1,y2,y3,x4,y4,t,x)
????????if?t==0?and?x1<=x?then
????????????cnt=cnt+isTop(y1,y2,y3,y4)
????????elseif?t==1?and?x4<=x?then
????????????cnt=cnt-isTop(y4,y3,y2,y1)
????????end
????end
????local?function?count(x1,y1,x2,y2,x3,y3,x4,y4,t)
????????if?t?then
????????????t=math.round(t,5)
????????????if?t<1?and?t>0?then
????????????????if?Xshape.cubic_bezier(x1,x2,x3,x4,t)<=pt_x?then
????????????????????local?ang=-Xshape.angle_at(t,x1,y1,x2,y2,x3,y3,x4,y4)
????????????????????cnt=cnt+Xshape.sgn(ang%180==0?and?0?or?ang)
????????????????end
????????????else?ignore_max_extreme_pt(x1,y1,y2,y3,x4,y4,t,pt_x)
????????????end
????????end
????end
????local?function?bezier_isect_cnt(x1,y1,x2,y2,x3,y3,x4,y4,y)
????????local?top,bottom=math.min(y1,y2,y3,y4),math.max(y1,y2,y3,y4)
????????local?left,right=math.min(x1,x2,x3,x4),math.max(x1,x2,x3,x4)
????????if?right-left<1e-4?then
????????????line_isect_cnt(x1,y1,x4,y4,y)
????????else
????????????if?y>=top?and?y<=bottom?and?bottom-top>1e-4?then
????????????????local?a,b,c,d=math.round(3*y2+y4-3*y3-y1,5),math.round(3*y1-6*y2+3*y3,5),math.round(3*y2-3*y1,5),math.round(y1,5)
????????????????local?t1,t2,t3=Xshape.solveCubic(a,b,c,d-y)
????????????????count(x1,y1,x2,y2,x3,y3,x4,y4,t1)?count(x1,y1,x2,y2,x3,y3,x4,y4,t2)?count(x1,y1,x2,y2,x3,y3,x4,y4,t3)
????????????end
????????end
????end
????for?m?in?ass_shape:gmatch('m[^m]+')?do
????????local?cmd={}
????????for?mlb?in?m:gmatch('[mlb][-.?%d]+')?do
????????????local?pt={}
????????????for?num?in?mlb:gmatch('([-.%d]+)')?do
????????????????pt[#pt+1]=num*1
????????????end
????????????cmd[#cmd+1]=pt
????????end
????????if?cmd[1][1]~=cmd[#cmd][#cmd[#cmd]-1]?or?cmd[1][2]~=cmd[#cmd][#cmd[#cmd]]?then
????????????cmd[#cmd+1]={cmd[1][1],cmd[1][2]}
????????end
????????for?i=1,#cmd-1?do
????????????if?#cmd[i+1]==2?then
????????????????line_isect_cnt(cmd[i][#cmd[i]-1],cmd[i][#cmd[i]],cmd[i+1][1],cmd[i+1][2],pt_y)
????????????else
????????????????bezier_isect_cnt(cmd[i][#cmd[i]-1],cmd[i][#cmd[i]],cmd[i+1][1],cmd[i+1][2],cmd[i+1][3],cmd[i+1][4],cmd[i+1][5],cmd[i+1][6],pt_y)
????????????end
????????end
????end
????return?cnt~=0
end