AS3位图任意形变一步一步来(4)——任意形变

转载请注明出处:http://fdream.net,作者:Fdream

放着放着就忘了,多亏army同学在后面催我,要不然还真不知道什么时候会继续弄这个。今天上午又抽空捣鼓了一下,偏移总算是弄出来了,不过渲染效率很低,中间的计算过程应该还可以继续优化的。另外,弄到这里发现还是有问题,分得较细的时候会出现裂缝……误差真可怕!

先不管这个误差,我们来看看能不能形变先。由于计算形变矩阵需要初始的坐标和新的坐标,需要两个方法来计算(貌似可以合并?):

// calculate points
// 包含x坐标和y坐标,分别存储在pxs和pys数组中
// @params:
//   w: 位图宽
//   h: 位图高
//   hs: 水平分段数
//   vs: 垂直分段数
// @return:
//   void
function CalculatePoints(w:Number, h:Number, hs:Number, vs:Number):void {
    var iw:Number = w / hs;
    var ih:Number = h / vs;
    for (var h=0; h<=hs; h++) {
        pxs[h] = h * iw;
    }
    for (var v=0; v<=vs; v++) {
        pys[v] = v * ih;
    }
}

计算新的坐标,也就是形变后的坐标:

function CalculateNewPoints(p0:Point, p1:Point, p2:Point, p3:Point, hs:Number, vs:Number):void {
    var lp:Point = new Point(p0.x, p0.y);
    var rp:Point = new Point(p1.x, p1.y);

    var lxd:Number = (p2.x - p0.x)/vs;
    var lyd:Number = (p2.y - p0.y)/vs;

    var rxd:Number = (p3.x - p1.x)/vs;
    var ryd:Number = (p3.y - p1.y)/vs;
    nps = [];
    for (var v=0; v<=vs; v++) {
        lp.x = p0.x + lxd * v;
        lp.y = p0.y + lyd * v;
        rp.x = p1.x + rxd * v;
        rp.y = p1.y + ryd * v;

        nps.push(new Array());
        var xd:Number = (rp.x - lp.x)/hs;
        var yd:Number = (rp.y - lp.y)/hs;
        for (var h=0; h<=hs; h++) {
            nps[v].push(new Point(lp.x + xd * h, lp.y + yd * h));
        }
    }
}

再是计算形变矩阵的函数,由于在这里我们会对便宜进行单独处理,所以这里不需要计算偏移。

function CalculateMatrix(oa:Object, ob:Object):Matrix {
    var p1 = oa.p1, p2 = oa.p2, p3 = oa.p3;
    var pa = ob.p1, pb = ob.p2, pc = ob.p3;
    var mt:Matrix = new Matrix();
    mt.a = ((p3.y - p1.y)*(pb.x - pa.x) - (p2.y-p1.y)*(pc.x-pa.x))/((p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y));
    mt.b = ((p3.y - p1.y)*(pb.y - pa.y) - (p2.y-p1.y)*(pc.y-pa.y))/((p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y));
    mt.c = ((p3.x - p1.x)*(pb.x - pa.x) - (p2.x-p1.x)*(pc.x-pa.x))/((p2.y-p1.y)*(p3.x-p1.x)-(p3.y-p1.y)*(p2.x-p1.x));
    mt.d = ((p3.x - p1.x)*(pb.y - pa.y) - (p2.x-p1.x)*(pc.y-pa.y))/((p2.y-p1.y)*(p3.x-p1.x)-(p3.y-p1.y)*(p2.x-p1.x));
    // mt.tx = ((pb.x*p1.x - pa.x*p2.x)*(p3.y*p1.x-p1.y*p3.x)-(pc.x*p1.x-pa.x*p3.x)*(p2.y*p1.x-p1.y*p2.x))/((p1.x-p2.x)*(p3.y*p1.x-p1.y*p3.x)-(p1.x-p3.x)*(p2.y*p1.x-p1.y*p2.x));
    // mt.tx = ((pb.y*p1.x - pa.y*p2.x)*(p3.y*p1.x-p1.y*p3.x)-(pc.y*p1.x-pa.y*p3.x)*(p2.y*p1.x-p1.y*p2.x))/((p1.x-p2.x)*(p3.y*p1.x-p1.y*p3.x)-(p1.x-p3.x)*(p2.y*p1.x-p1.y*p2.x));
    return mt;
}

最后就是要对三角形进行形变,这个函数:

// 要传进来的参数是位图四个角的新坐标
function rendNew(p0:Point, p1:Point, p2:Point, p3:Point) {
    // 先计算每个点的新坐标位置
    CalculateNewPoints(p0, p1, p2, p3, hs, vs);

    var pa:Point, pb:Point, pc:Point, pd:Point;
    var m1:Matrix, m2:Matrix;
    var tid:Number = 0;
    var ps0:Point = new Point(pxs[0], pys[0]);
    var psa:Point = nps[0][0];
    for (var v=0; v<vs; v++) {
        for (var h=0; h<hs; h++) {
            p0.x = pxs[h];
            p0.y = pys[v];
            p1.x = pxs[h+1];
            p1.y = pys[v];
            p2.x = pxs[h];
            p2.y = pys[v+1];
            p3.x = pxs[h+1];
            p3.y = pys[v+1];
            pa = nps[v][h];
            pb = nps[v][h+1];
            pc = nps[v+1][h];
            pd = nps[v+1][h+1];

            tid = v*hs*2 + h*2;
            var ta = trs[tid];
            var tb = trs[tid+1];
            m1 = CalculateMatrix({p1:p0, p2:p1, p3:p2}, {p1:pa, p2:pb, p3:pc});
            if (tid > hs * 2 && h != 0) {
                m1.tx = trs[tid - hs * 2 - 1].transform.matrix.tx;
                m1.ty = trs[tid - hs * 2 - 1].transform.matrix.ty;
            } else {
                m1.tx = 0;
                m1.ty = 0;
            }
            
            m2 = CalculateMatrix({p1:p1, p2:p2, p3:p3}, {p1:pb, p2:pc, p3:pd});
            if(v > 0){
                m2.tx = trs[1].transform.matrix.tx * (h + 1) * (v + 1);
            }
            else{
                m2.tx = ((pb.x - psa.x) - (p1.x - pxs[0])) - ((pd.x - nps[v+1][0].x) - (p3.x - pxs[0]));
            }
            if(tid > 0){
                m2.ty = trs[1].transform.matrix.ty * (h + 1) * (v + 1);
            }
            else{
                m2.ty = ((pc.y - psa.y) - (p2.y - pys[0])) - ((pd.y - nps[0][h+1].y) - (p3.y - pys[0]));
                trace(m2.ty);
            }
            ta.transform.matrix = m1;
            tb.transform.matrix = m2;
        }
    }
}

嗯,这实在是太凑合了,需要合并许多计算,后面继续优化~

1 comment on “AS3位图任意形变一步一步来(4)——任意形变”

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据