create a sector−円弧を描画してみる

スクリプトから図形を描く場合、いろいろとgeometoricな計算がたくさん必要になります。そして、それは数学的素養をとっても要求する事です。(あ〜めんどくさい)
できれば面倒な計算は避けて通りたいタイプのものぐさな人間ですのでこういった事は苦手な部類の事象です。
しかしながら必要な機能は必要ですので、そう言った場合は重い腰を上げて取りかかる事になります。
とかなんとか言っている訳ですが、今回はそ〜んなややこしい計算はま〜ったく行わずに描画する方法です。もちろん使うのは以前紹介したbezierコントロールファンクション群です。

まあ、四の五の言ってないでからコードから

if (app.documents.length>0){
    var d = new Window (‘dialog’, ‘radius &radian’, [100,100,360,290]);
        d.mp = d.add(‘panel’, [10,20,245,115], ‘input radius and radian’);
        d.mp.st1 = d.mp.add(‘statictext’, [50,24,100,40], ‘radius = ‘);
        d.mp.et1 = d.mp.add(‘edittext’, [110,20,170,40],’100′, {multiline:false});
        d.mp.st2 = d.mp.add(‘statictext’, [50,54,100,70], ‘radian = ‘);
        d.mp.et2 = d.mp.add(‘edittext’, [110,50,170,70],’45’, {multiline:false});
        d.bp = d.add(‘panel’, [10,130,245,175], ”);
        d.bp.submitBtn = d.bp.add(‘button’, [20,10,100,25], ‘OK’, {name:’ok’});
        d.bp.cancelBtn = d.bp.add(‘button’, [120,10,200,25], ‘cancel’, {name:’cancel’});
        d.bp.submitBtn.onClick = function (){main()};
        d.show();
        }

function main(){
    var x0 = 200, y0 = -200;
    var radius = d.mp.et1.text – 0;
    var radian = d.mp.et2.text – 0;
    d.close();
    if (radian>180) alert(“We support 0 to 180 degree.”);
    var lnColor = new GrayColor;
    lnColor.gray = 100;
    
    var ln = app.activeDocument.pathItems.add();
    ln.stroke = true;
    ln.strokeColor = lnColor;
    ln.strokeWidth = 0.3;
    ln.filled =false;

    var pt0 = ln.pathPoints.add()
    pt0.anchor = Array(x0+radius, y0);
    pt0.rightDirection = Array(x0+radius, y0+(Math.sqrt (2)-1)/3*4*radius);
    var pt1 = ln.pathPoints.add();
    pt1.anchor = Array(x0, y0+radius);
    pt1.leftDirection = Array(x0+(Math.sqrt (2)-1)/3*4*radius, y0+radius);
    if (90<radian&&radian<=180) {
        pt1.rightDirection = Array(x0-(Math.sqrt (2)-1)/3*4*radius, y0+radius);
        var pt2 = ln.pathPoints.add();
        pt2.anchor = Array(x0-radius, y0);
        pt2.leftDirection = Array(x0-radius, y0+(Math.sqrt (2)-1)/3*4*radius);
        }
    if (radian<=90) {
        if (radian<90) mvPt(pt0, pt1, radian/90);
        pt0.leftDirection = pt0.anchor;
        pt1.rightDirection = pt1.anchor;
        var p2 = ln.pathPoints.add();
        p2.anchor = Array(x0, y0);
        p2.leftDirection = p2.anchor;
        p2.rightDirection = p2.anchor;
        ln.closed = true;
        } else if (90<radian&&radian<=180){
            if (radian<180) mvPt(pt1, pt2, (radian-90)/90);
            pt0.leftDirection = pt0.anchor;
            pt2.rightDirection = pt2.anchor;
            var p3 = ln.pathPoints.add();
            p3.anchor = Array(x0, y0);
            p3.leftDirection = p3.anchor;
            p3.rightDirection = p3.anchor;
            ln.closed = true;
            }
    }

function mvPt(p0,p1,ratio){
    var pt = new Array();
    var nwPt = new Array();

    pt[0] = p0.anchor;
    pt[1] = p0.rightDirection;
    pt[2] = p1.leftDirection;
    pt[3] = p1.anchor;
       
    p0.rightDirection = linearSprit(pt[0], pt[1], ratio);
    p1.anchor = nwAnchor (pt[0], pt[1], pt[2], pt[3], ratio);
    p1.leftDirection = nwDirection (pt[0], pt[1], pt[2], ratio);
    return true;
    }

function linearSprit (p0, p1, t) { //linear bezier
    var dirPt = new Array();
    for (var i=0;i<2;i++){
        dirPt[i] = p1[i] * t + p0[i] * (1 – t);
        }
    return dirPt;
    }

function nwDirection(p0, p1, p2, t){ //quadratic bezier
    var dirPt = new Array()
    for (var i=0;i<2;i++){
        dirPt[i] = (Math.pow ((1 – t), 2) )* p0[i]
                    + 2 * (1 – t) * t * p1[i]
                    + t * t * p2[i] ;
        }
    return dirPt;
    }

function nwAnchor(p0,p1,p2,p3, t){ //cublic bezier
    var spPt = new Array()
    for (var i=0;i<2;i++){
        spPt[i] = (Math.pow ((1 – t), 3)) * p0[i]
                    + 3 * (Math.pow ((1 – t), 2)) * t * p1[i]
                    + 3 * (Math.pow (t, 2)) * (1 – t) * p2[i]
                    + Math.pow (t, 3) * p3[i] ;
        }
    return spPt;
    }<radian&&radian<=180) {="" pt1.rightdirection="Array(x0-(Math.sqrt" (2)-1)="" 3*4*radius,="" y0+radius);="" var="" pt2="ln.pathPoints.add();" pt2.anchor="Array(x0-radius," y0);="" pt2.leftdirection="Array(x0-radius," y0+(math.sqrt="" 3*4*radius);="" }="" if="" (radian<="90)" (radian<90)="" mvpt(pt0,="" pt1,="" radian="" 90);="" pt0.leftdirection="pt0.anchor;" p2="ln.pathPoints.add();" p2.anchor="Array(x0," p2.leftdirection="p2.anchor;" p2.rightdirection="p2.anchor;" ln.closed="true;" else="" (90<radian&&radian<="180){" (radian<180)="" mvpt(pt1,="" pt2,="" (radian-90)="" pt2.rightdirection="pt2.anchor;" p3="ln.pathPoints.add();" p3.anchor="Array(x0," p3.leftdirection="p3.anchor;" p3.rightdirection="p3.anchor;" function="" mvpt(p0,p1,ratio){="" pt="new" array();="" nwpt="new" pt[0]="p0.anchor;" pt[1]="p0.rightDirection;" pt[2]="p1.leftDirection;" pt[3]="p1.anchor;" p0.rightdirection="linearSprit(pt[0]," pt[1],="" ratio);="" p1.anchor="nwAnchor" (pt[0],="" pt[2],="" pt[3],="" p1.leftdirection="nwDirection" return="" true;="" linearsprit="" (p0,="" p1,="" t)="" linear="" bezier="" dirpt="new" for="" (var="" i="0;i<2;i++){" dirpt[i]="p1[i]" *="" t="" +="" p0[i]="" (1="" -="" t);="" dirpt;="" nwdirection(p0,="" p2,="" t){="" quadratic="" array()="" ((1="" t),="" 2)="" )*="" 2="" p1[i]="" p2[i]="" ;="" nwanchor(p0,p1,p2,p3,="" cublic="" sppt="new" sppt[i]="(Math.pow" 3))="" 3="" (math.pow="" 2
))="" (t,="" math.pow="" 3)="" p3[i]="" sppt;="" }
</radian&&radian

非常にシンプルです。通常は必須の三角関数すら使っていません。以前紹介した通り中心角が90°の扇形は例のファンクション群で描画出来る訳です。さらに、パスを好きな比率に分割する事も出来ます。
もうお判りでしょう。90°単位で扇形を描いてそこから角度の比率に応じてアンカーを移動しています。
コードを追っかけると分かると思いますが、面倒なので180°までになっていますが、同様に継ぎ足していくと360°まで簡単に対応出来ます。

ten_a

Graphic Designer, Scripter and Coder. Adobe Community Professional.

シェアする

コメントを残す