I am trying to map an image to a \"3d\" grid that simulates cloth using strokeStyle and canvas, i have the image included but it is currently acting as a background image and no
Oh my! Great question!
So let's see what we've got. A system that has a bunch of "constraints", which are sets of 2 points. Contraints themselves come in pairs, and they make two lines, forming a ┘
shape (the bottom-right of a box).
If we were to draw every constraint line individually we'd see this:
That's all horizontal red lines and vertical blue lines. Drawing a single one we'd just see that ┘
shape, and each long red line is really hundreds of little lines, the bottom of each ┘
shape, end to end. There are several hundred ┘
s here, and together they make it look like a cohesive mesh. The fact that each one is already individual makes this easy for us.
That shape is all we need to determine a sort-of bounding box. And it looks like each Point
in a Constraint
comes with original values, so we'll save those as sx
and sy
.
If we know the bounds of the boxes at their new location, and we know the original bounds beecause we've saved all the Point's values for the Contraints, then we should be golden.
Once we have the original bounding box of a Constraint and its current bounding box, why, all we have to do is call drawImage with both boxes: ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
I wrote a new Constraint.prototype.draw
routine, It looks like this:
And so on.
There are a few ways you could "patch" the holes, and its really up to you, otherwise you'll have to finagle with transformations.
Have a look at the code. I didn't change much. Look for !!!
in the code (my edits) and DEBUG:
in the code (debug code in case the image does not load or you wanna see the wireframes).
http://jsfiddle.net/simonsarris/Kuw6P/
The code is long so I don't wanna paste it all here, but here's a backup in case jsfiddle goes down: https://gist.github.com/simonsarris/5405304
And here's the most relevant part:
// !!! new super awesome draw routine! So cool we skipped naming it draw2!
Constraint.prototype.draw3 = function(otherP2) {
// NOW dear friends consider what we have. Each box is made out of two lines,
// the bottom and rightmost ones.
// From these lines we can deduce the topleft and bottom-right points
// From these points we can deduce rectangles
// From the skewed rectangle vs the original rectangle we can "stretch"
// an image, using drawImage's overloaded goodness.
// AND WE'RE OFF:
// destination rect has 2 points:
//top left: Math.min(this.p2.x, otherP2.x), Math.min(this.p2.y, otherP2.y)
//bottom right: (this.p1.x, this.p1.y)
// image destination rectangle, a rect made from the two points
var dx = Math.min(this.p1.x, Math.min(this.p2.x, otherP2.x));
var dy = Math.min(this.p1.y, Math.min(this.p2.y, otherP2.y));
var dw = Math.abs(this.p1.x - Math.min(this.p2.x, otherP2.x));
var dh = Math.abs(this.p1.y - Math.min(this.p2.y, otherP2.y));
// DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
//ctx.strokeStyle = 'lime';
//ctx.strokeRect(dx, dy, dw, dh);
// source rect 2 points:
//top left: Math.min(this.p2.sx, otherP2.sx), Math.min(this.p2.sy, otherP2.sy)
//bottom right: (this.p1.sx, this.p1.sy)
// these do NOT need to be caluclated every time,
// they never change for a given constraint
// calculate them the first time only. I could do this earlier but I'm lazy
// and its past midnight. See also: http://www.youtube.com/watch?v=FwaQxDkpcHY#t=64s
if (this.sx === undefined) {
this.sx = Math.min(this.p1.sx, Math.min(this.p2.sx, otherP2.sx));
this.sy = Math.min(this.p1.sy, Math.min(this.p2.sy, otherP2.sy));
this.sw = Math.abs(this.p1.sx - Math.min(this.p2.sx, otherP2.sx));
this.sh = Math.abs(this.p1.sy - Math.min(this.p2.sy, otherP2.sy));
}
var sx = this.sx;
var sy = this.sy;
var sw = this.sw;
var sh = this.sh;
// DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
//ctx.strokeStyle = 'red';
//ctx.strokeRect(sx, sy, sw, sh);
// IF we have a source and destination rectangle, then we can map an image
// piece using drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
// Only problem, we're not exactly dealing with rectangles....
// But we'll deal. Transformations have kooties anyways.
ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
};