转载请注明出处: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;
}
}
}
嗯,这实在是太凑合了,需要合并许多计算,后面继续优化~
我太爱你了,占楼明天研究。