insuaaaaa 发表于 2025-3-13 05:06:06

萌新请教\pos与\an关联性的问题

本帖最后由 insuaaaaa 于 2025-3-13 05:07 编辑

对于已经通过\pos和\an固定好的字符,如何得到在另一种\an之下与其位置完全重合的\pos数值

比如先有了一个\an7的蛤,然后增加一个\an5的蛤,除了手工瞄准,可不可以通过算法计算\pos得出一个与其完全重合的\an5的蛤https://free4.yunpng.top/2025/03/13/67d1f352a063d.jpg

tmdtmdtmdqq 发表于 2025-3-13 09:48:07

本帖最后由 tmdtmdtmdqq 于 2025-3-13 10:30 编辑

以前写的,在我修的某个字幕中有用过来作特效。
已经考虑过\an标签、\pos标签、margin_l、margin_r、margin_v设置的情况(\move标签不适用),非特殊情况下使用按理说没问题。
注意设置好字幕文件中的PlayResX、PlayResY属性,否则要在函数调用中传入字幕空间的长、宽。

用法:
!line_screen_pos_xy_tag(7)!    则输出   \an7\pos(xxx1, yyy1)
!line_screen_pos_xy_tag(3, 1920, 1080)!    则输出   \an3\pos(xxx2, yyy2)

附加功能
!line_screen_pos_xy(7)!    则输出两个值   xxx, yyy
!line_screen_ltrb_pos()!   则输出四个值left, top, right, bottom(计算内联坐标\pos后的四个边的值,不带边界阴影)
!line_screen_ltrb_pos_with_bord_shad()!   则输出四个值left, top, right, bottom(计算内联坐标\pos后的四个边的值,带边界阴影。这个函数没写在测试文件中,仅在下面列出)
其它的例子就看测试文件(注释掉样式为fx且层为1的行,就能看到原始行,也就能检查是否重合)。

function pos_map_vector(src_an, src_x, src_y, trg_an, trg_x, trg_y, width, height)
local src_left, src_top, trg_left, trg_top;

src_left = src_x - (src_an%3==1 and 0 or (src_an%3==2 and width/2 or width));
src_top = src_y - (src_an<=3 and height or (src_an<=6 and height/2 or 0));

trg_left = trg_x - (trg_an%3==1 and 0 or (trg_an%3==2 and width/2 or width));
trg_top = trg_y - (trg_an<=3 and height or (trg_an<=6 and height/2 or 0));

return trg_left - src_left, trg_top - src_top;
end

function line_screen_ltrb_pos(screen_width, screen_height)
local vline = orgline;
screen_width = screen_width or meta.res_x;
screen_height = screen_height or meta.res_y;
local src_an = vline.styleref.align;
local trg_an = _G.tonumber(string.match(vline.text, "\\an%s*(%d)")) or src_an;
local trg_x, trg_y = string.match(vline.text, "\\pos%(%s*(%-?[%d.]+)%s*,%s*(-?[%d.]+)%s*%)");
if trg_x == nil or trg_y == nil then
    if trg_an == src_an then
      trg_x, trg_y = vline.x, vline.y;
    else
      trg_x = (trg_an%3==1 and vline.eff_margin_l or (trg_an%3==2 and (screen_width+vline.eff_margin_l-vline.eff_margin_r)/2 or screen_width-vline.eff_margin_r));
      trg_y = (trg_an<=3 and screen_height-line.eff_margin_v or (trg_an<=6 and screen_height/2 or line.eff_margin_v));
    end
else
    trg_x, trg_y = _G.tonumber(trg_x), _G.tonumber(trg_y);
end

local dx, dy = pos_map_vector(src_an, vline.x, vline.y, trg_an, trg_x, trg_y, vline.right-vline.left, vline.bottom-vline.top);
return vline.left + dx, vline.top + dy, vline.right + dx, vline.bottom + dy;
end

function line_screen_pos_xy(an, screen_width, screen_height)
local vline = orgline;
local left, top, right, bottom = line_screen_ltrb_pos(screen_width, screen_height);
an = an or _G.tonumber(string.match(vline.text, "\\an%s*(%d)")) or vline.styleref.align;
local x = (an%3==1 and left or (an%3==2 and (left+right)/2 or right));
local y = (an<=3 and bottom or (an<=6 and (top+bottom)/2 or top));
return x, y;
end

function line_screen_pos_xy_tag(an, screen_width, screen_height, precision)
precision = precision or 2;
local vline = orgline;
local an_str = an and "\\an"..an or _G.table.concat({string.match(vline.text, "(\\an)%s*(%d)")}, "");
local pfmt = string.format("%s\\pos(%%.%df,%%.%df)", an_str, precision, precision);
return pfmt:format(line_screen_pos_xy(an, screen_width, screen_height));
end

-- ;附送方法
function line_screen_ltrb_pos_with_bord_shad(screen_width, screen_height)
local vline = orgline;
local left, top, right, bottom = line_screen_ltrb_pos(screen_width, screen_height);
local bord = _G.tonumber(string.match(vline.text, "\\bord%s*(%-?[%d.]+)")) or vline.styleref.outline;
local xshad = _G.tonumber(string.match(vline.text, "\\x?shad%s*(%-?[%d.]+)")) or vline.styleref.shadow;
local yshad = _G.tonumber(string.match(vline.text, "\\y?shad%s*(%-?[%d.]+)")) or vline.styleref.shadow;
left = left - bord - (xshad<0 and -xshad or 0);
top = top - bord - (yshad<0 and -yshad or 0);
right = right + bord + (xshad>0 and xshad or 0);
bottom = bottom + bord + (yshad>0 and yshad or 0);
return left, top, right, bottom;
end






页: [1]
查看完整版本: 萌新请教\pos与\an关联性的问题