mdiapp(+)/コミラボ(+) には「楕円フレーム」が無いので……2014/03/17 00:00:00

mdiapp(+)/コミラボ(+) で “楕円フレーム” ライクなブラシスクリプトを使ってる所

mdiapp(+)/コミラボ(+)” には「楕円フレーム」が無い為、個人差はありますが少し困る事が有るかもしれません

円の方は、スナップで円定規を指定して、筆圧無効で描画すれば何とかなりますが、楕円は駄目……

 

仕方ないので、ブラシスクリプトで何とかならないかと足掻いた結果、「ベジェ曲線」を使えば近似ではあるもののなんとかなる事が判明

 

■ 参考にしたページ は →こちら [wordpress.com]

 

問題は、これをブラシスクリプトに落としこむと言う無茶をしなければならないこと

どう考えても本来はブラシでやる事じゃないんですよ、これ

 

初めての lua スクリプト + ブラシスクリプトだったので、バグで “コミラボ+” をハングさせたりしながら、何とか形になりました

汚いソースコードですが、必要な方が居るかもしれないので公開しておきます

3つのソースコードすべての共通仕様は、ブラシの最大径が線の太さになる事と、ブラシ濃度が有効という 2点ですが、タブレットで使用している時には筆圧濃度が反映される場合があるので、登録時に「筆圧透明度」にチェックを入れないで下さい (ディフォルトでは、チェックは入っていません)

また、“mdiapp(+)/コミラボ(+)” のプログラムブラシは、クリックでは描画されないみたいなので、少しだけカーソルを動かして下さい

 

※ circle.bs

function use_base()
return true
end

function main( x, y, p )
if not firstDraw then
if (bs_ms() - lastTime) < 800 then
return 0
end
end

local x0,y0 = bs_base();
if x0 == -1 then
x0 = bs_canvas_width() / 2;
end
if y0 == -1 then
y0 = bs_canvas_height() / 2;
end

local bw = bs_width_max() / 2;
local dist = bs_distance( x - x0, y - y0 );
if (dist - bw) < 1 then
return 0;
end;

local x1 = x0 - dist - bw;
local y1 = y0 - dist - bw;
local x2 = x0 + dist + bw;
local y2 = y0 + dist + bw;

local cw = 4.0 * 0.41421356 * (dist + bw) / 3.0;
local ch = 4.0 * 0.41421356 * (dist + bw) / 3.0;

bs_bezier_begin( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

x1 = x0 + bw - dist;
y1 = y0 + bw - dist;
x2 = x0 + dist - bw;
y2 = y0 + dist - bw;
cw = 4.0 * 0.41421356 * (dist - bw) / 3.0;
ch = 4.0 * 0.41421356 * (dist - bw) / 3.0;

bs_bezier_m( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

local r,g,b = bs_fore();
bs_fill( r, g, b, 255 * bs_opaque() );

lastTime = bs_ms();
firstDraw = false;

return 1;
end

lastTime = 0;
firstDraw = true;

・ 基点(基準点) を中心にして、指定したポイント迄の距離を半径とした円を描きます

 

※ ellipse1.bs

function use_base()
return true
end

function main( x, y, p )
if not firstDraw then
if (bs_ms() - lastTime) < 800 then
return 0;
end
end

local x0,y0 = bs_base();
if x0 == -1 then
x0 = bs_canvas_width() / 2;
end
if y0 == -1 then
y0 = bs_canvas_height() / 2;
end

local bw = bs_width_max() / 2;
if (bs_distance( x - x0, y - y0 ) - bw) < 2 then
return 0;
end;

ry = y - y0;
rx = x - x0;
if rx<0 then
rx = -rx;
end
if ry<0 then
ry = -ry;
end

local x1 = x0 - rx - bw;
local y1 = y0 - ry - bw;
local x2 = x0 + rx + bw;
local y2 = y0 + ry + bw;

local cw = 4.0 * 0.41421356 * (rx + bw) / 3.0;
local ch = 4.0 * 0.41421356 * (ry + bw) / 3.0;

bs_bezier_begin( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

x1 = x0 + bw - rx;
y1 = y0 + bw - ry;
x2 = x0 + rx - bw;
y2 = y0 + ry - bw;
cw = 4.0 * 0.41421356 * (rx - bw) / 3.0;
ch = 4.0 * 0.41421356 * (ry - bw) / 3.0;

bs_bezier_m( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

local r,g,b = bs_fore();
bs_fill( r, g, b, 255 * bs_opaque() );

lastTime = bs_ms();
firstDraw = false;

return 1;
end

lastTime = 0;
Toggle = 0;
rx = 0;
ry = 0;
firstDraw = true;

・ 基点(基準点) を中心にして、指定したポイント迄の x,y 座標それぞれの距離を考慮した楕円を描きます

 

※ ellipse2.bs

function use_base()
return true
end

function main( x, y, p )
if not firstDraw then
if (bs_ms() - lastTime) < 800 then
return 0;
end
end

local x3,y3 = bs_base();
if x3 == -1 then
x3 = bs_canvas_width() / 2;
end
if y3 == -1 then
y3 = bs_canvas_height() / 2;
end

local x4 = x;
local y4 = y;

local bw = bs_width_max() / 2;
if (bs_distance( x3 - x4, y3 - y4 ) - bw) < 2 then
return 0;
end;

local i = 0;
if x4<x3 then
i = x3;
x3 = x4;
x4 = i;
end
if y4<y3 then
i = y3;
y3 = y4;
y4 = i;
end

local rx = (x4 - x3) / 2;
local ry = (y4 - y3) / 2;
local x0 = (x3 + x4) / 2;
local y0 = (y3 + y4) / 2;

local x1 = x3 - bw;
local y1 = y3 - bw;
local x2 = x4 + bw;
local y2 = y4 + bw;

local cw = 4.0 * 0.41421356 * (rx + bw) / 3.0;
local ch = 4.0 * 0.41421356 * (ry + bw) / 3.0;

bs_bezier_begin( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

x1 = x3 + bw;
y1 = y3 + bw;
x2 = x4 - bw;
y2 = y4 - bw;
cw = 4.0 * 0.41421356 * (rx - bw) / 3.0;
ch = 4.0 * 0.41421356 * (ry - bw) / 3.0;

bs_bezier_m( x0, y1 );
bs_bezier_c(x0 + cw, y1, x2, y0 - ch, x2, y0);
bs_bezier_c(x2, y0 + ch, x0 + cw, y2, x0, y2);
bs_bezier_c(x0 - cw, y2, x1, y0 + ch, x1, y0);
bs_bezier_c(x1, y0 - ch, x0 - cw, y1, x0, y1);

local r,g,b = bs_fore();
bs_fill( r, g, b, 255 * bs_opaque() );

lastTime = bs_ms();
firstDraw = false;

return 1;
end

lastTime = 0;
rx = 0;
ry = 0;
firstDraw = true;

・ 基点(基準点) と指定したポイントで出来る矩形に中心線が内接する楕円を描きます

 

 

無理をしているので、使いやすいとは言いがたいのですが、塗りつぶされた楕円を描いて、それを選択範囲にした後、「選択範囲の収縮」 を行った後削除という手順を踏まなくても済むのが便利かもしれません

 

mdiapp(+)/コミラボ(+)” に「楕円フレーム」が実装されれば無用になりますが、どうも実装されそうにないのですよね