2015-03-30 88 views
0

變換,以創建與紋理圖像帆布布料模擬我使用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(); 
} 

我試圖去適應其他布料模擬,但沒有成功。任何線索,我可以找到一些信息來完成?

+0

我認爲你會發現布料模擬工程通過將每個原始矩形分成2個三角形 - 而不是傾斜原始矩形;-) – markE 2015-03-30 18:36:54

+0

是@markE,我也嘗試過,但我是在同一個問題,drawImage設置一個矩形,我會需要傾斜它。 – 2015-03-30 19:14:52

回答

2

使用偏斜(或更確切地說剪切)來填充瓷磚僅當細胞是平行四邊形,如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";
<canvas width=500 height=160/>

注:如果你的布料模擬產生其他形狀除平行四邊形(即四邊形),這是很有可能,因爲這是一個物理模擬,這種方法將無法正常工作。在這種情況下,你需要不同的技術,計算量更大。出於這個原因,WebGL更適合。只是我的兩分錢..

+0

它看起來不錯,我明白你對四邊形的意思,我的數學不是那麼重,所以我會試着用你的代碼,WebGL無疑是一種探索這種方式,謝謝。 – 2015-03-31 12:18:03