2015-03-30 4 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

+0

Да @markE, я тоже пробовал, но я был в той же самой проблеме, drawImage задал прямоугольник, и мне все равно придется его перекосить. –

ответ

2

Использование перекоса (или, скорее, сдвига) для заполнения плиток работает только в том случае, если ячейка является параллелограммом, поскольку двумерные аффинные преобразования поддерживают только эту форму.

Вот один подход:

  • Вычислить угол верхней линии
  • Вычислить угол левой линии
  • ширин Рассчитать и высоту ячейки

В параллелограмме нижней строки будут равны верхняя строка и, конечно, правая линия равна левой линии.

Затем установите эти углы в виде косых аргументов для преобразования, соединенного с переходом в верхний левый угол.

Затем просто повторяйте для каждой ячейки.

Пример

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, несомненно, способ изучить это, благодаря обоим. –

Смежные вопросы