布料模拟+图像转换

时间:2015-03-30 17:57:30

标签: javascript html5 canvas html5-canvas skew

我正在使用 verlet.js 插件,以便在画布上使用纹理图像创建布料模拟。

我没有到达的唯一(也是最重要的BTW)部分是我需要倾斜drawImage以使其适合正确的位置。

jsfiddle with the progress

//Drawing the rectangle
ctx.save();
ctx.beginPath();

ctx.moveTo(cloth.particles[i1].pos.x, cloth.particles[i1].pos.y);
ctx.lineTo(cloth.particles[i1+1].pos.x, cloth.particles[i1+1].pos.y);
ctx.lineTo(cloth.particles[i2].pos.x, cloth.particles[i2].pos.y);
ctx.lineTo(cloth.particles[i2-1].pos.x, cloth.particles[i2-1].pos.y);
ctx.lineTo(cloth.particles[i1].pos.x, cloth.particles[i1].pos.y);

ctx.strokeStyle = "#fff";
ctx.stroke();
ctx.restore();

//Wrapping the image
ctx.save();
var off = cloth.particles[i2].pos.x - cloth.particles[i1].pos.x;

//THIS IS WHAT I TRY TO SOLVE TO FIT TO THE RECTANGLES
//ctx.transform(1,0.5,0,1,0,0);
ctx.drawImage(img, cloth.particles[i1].pos.x,cloth.particles[i1].pos.y, off, off, cloth.particles[i1].pos.x,cloth.particles[i1].pos.y, off ,off);
ctx.restore();
}

我试图改编其他布料模拟,但没有成功。有什么线索可以找到一些信息来实现吗?

1 个答案:

答案 0 :(得分:1)

使用倾斜(或倾向剪切)填充切片仅在单元格为平行四边形时才有效,因为2D仿射变换仅支持此形状。

这是一种方法:

  • 计算上线角度
  • 计算左线的角度
  • 计算单元格的宽度和高度

在平行四边形中,底线将等于上线,当然右线等于左线。

然后将这些角度设置为变换的倾斜参数,并将其转换为左上角。

然后重复每个细胞。

实施例



var img = new Image;
img.onload = function() {

  var ctx = document.querySelector("canvas").getContext("2d"),
      tile1 = [
        {x: 10, y: 10},    // upper left corner
        {x: 210, y: 50},   // upper right
        {x: 230, y: 150},  // bottom right
        {x: 30, y: 110}    // bottom left
      ],
      tile2 = [
        {x: 210, y: 50},
        {x: 410, y: 5},
        {x: 430, y: 105},
        {x: 230, y: 150}
      ];
  
  renderTile(this, tile1);
  renderTile(this, tile2);
  
  function renderTile(img, tile) {
    var dx, dy, a1, a2, w, h, i = 1;

    // reference shape (remove this section):
    ctx.setTransform(1,0,0,1,0,0);
    ctx.moveTo(tile[0].x, tile[0].y);
    while(i < 4) ctx.lineTo(tile[i].x, tile[i++].y);
    ctx.closePath();
    ctx.strokeStyle = "#0c0";
    ctx.lineWidth = 2;
    ctx.stroke();
    
    // calc horizontal angle 
    dx = tile[1].x - tile[0].x;     // horizontal diff.
    dy = tile[1].y - tile[0].y;     // vertical diff.
    a1 = Math.atan2(dy, dx);        // angle, note dy,dx order here
    w = dx|0;                       // width based on diff for x

    // calc vertical angle 
    dx = tile[3].x - tile[0].x;
    dy = tile[3].y - tile[0].y;
    a2 = Math.atan2(dx, dy);        // note dx,dy order here
    h = dy|0;
    
    // draw image to fit parallelogram
    ctx.setTransform(1, a1, a2, 1, tile[0].x, tile[0].y);
    ctx.drawImage(img, 0, 0, w, h);
  }
};

img.src = "http://i.imgur.com/rUeQDjE.png";
&#13;
<canvas width=500 height=160/>
&#13;
&#13;
&#13;

注意:如果您的布料模拟产生的其他形状不是平行四边形(即四边形),这很可能是因为这是物理模拟,这种方法不会很好。在这种情况下,您需要不同的技术,这些技术更重要。因此,WebGL更适合。只是我的两分钱..