Introduction

stayCollision Detection :TriangleTriangle collision detection from another way of thinking, so far the introduction of static detection, and then look at the dynamic collision detection.

The following examples are not checked for compatibility and are recommended to be viewed in the latest chrome browsers.

Transformation

This isSample page

Canvas basedtranslaterotatescaleThree transformations form the animation to see how to carry out dynamic collision detection.

The animation principle based on canvas is to redraw every period of time, so the static collision detection is actually carried out at a specific time during the detection. Therefore, the method introduced before is also applicable, which is used uniformly herePolygon/PolygonMethods in. With the detection method, the next step is to obtain the dynamic coordinates of the relevant points on the screen. The following is a description of the situation.

translate

When drawing on canvas, positioning is based on the coordinate system. The top left corner of the canvas is the origin of the coordinate system, the horizontal right is the positive direction of X axis, and the vertical downward is the positive direction of Y axis. Draw a rectanglerect(20, 20, 40, 40)In the coordinate system, it looks like this:

Collision detection: Transformation

If you want to move 60 pixels horizontally to the right and 80 pixels down vertically, you can add coordinates directlyrect(20 + 60, 20 + 80, 40, 40)

Collision detection: Transformation

But there is another, more interesting way:Move the entire axis。 If you move the entire axis horizontally to the right by 60 pixels and vertically downward by 80 pixels, it is exactly the same visually.translateThe method is to use this method.

Collision detection: Transformation

From the above figure, it can be found that this method does not need to consider the coordinate changes of the rectangle, so it will be much more convenient when dealing with complex graphics.

It should be noted that thetranslateAfter that, you need to reset the axis, because there may be other graphics, and the original axis is still used as a reference. Reset axis usesetTransformmethod:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.translate(50, 50);
ctx.fillRect(0,0,100,100);

//Reset
ctx.setTransform(1, 0, 0, 1, 0, 0);

//Other treatment

For the changed coordinates, the translated pixels are added or subtracted directly.

/**
 *Suppose that point a (x, y) reaches B (m, n) after translating (x1, Y1)
 */
 const m = x + x1;
 const n = y + y1;

rotate

rotateMethods and methodstranslateThe method is similar, by rotating the coordinate axis.

Collision detection: Transformation

For the changed coordinates, some calculations are needed.

Collision detection: Transformation

/**
 *
 *The coordinates of the center of the circle O (0, 0), assuming that point a (x, y), and the angle formed by X axis is α
 *Rotate the angle β clockwise to reach point B (m, n). Next, we will deduce the coordinates of point B
 *
 *Distance from a to center: dist1 = | OA | = Y / sin (α) = x / cos (α)
 *The distance from B to the center of the circle: dist2 = | ob | = n / sin (α - β) = m / cos (α - β)
 *
 *It's just rotation, so dist1 = dist2, and the radius of construction rotation is R:
 * r = y/sin(α)=x/cos(α)=n/sin(α-β)=m/cons(α-β)
 * y = r * sin(α)  x = r * cos(α)
 *
 *According to the trigonometric function formula:
 * sin(α+β)=sin(α)cos(β)+cos(α)sin(β)
 * sin(α-β)=sin(α)cos(β)-cos(α)sin(β)
 * cos(α+β)=cos(α)cos(β)-sin(α)sin(β)
 * cos(α-β)=cos(α)cos(β)+sin(α)sin(β)
 *
 *Insert the following formula:
 * m = r*cos(α-β) = r * cos(α)cos(β) + r * sin(α)sin(β) =  x * cos(β) + y * sin(β)
 * n = r*sin(α-β) = r * sin(α)cos(β) - r * cos(α)sin(β) =  y * cos(β) - x * sin(β)
 *
 *Counter clockwise is the opposite
 * m =  x * cos(β) - y * sin(β)
 * n =  y * cos(β) + x * sin(β)
 *
 */

scale

scalemethodtranslateThe method is similar, by scaling the axis.

For the changed coordinates, it is directly multiplied by the corresponding scaling multiple.

/**
 *Suppose that point a (x, y) reaches B (m, n) after scale (num1, num2)
 */
const m = x * num1;
const n = y * num2;

Transformation Order

When several different transformations are carried out continuously, the order is different, and the results may be different. This isExamples

This is because the continuous transformation is based on the state after the last transformation, and then the transformation is carried out again. In the calculation, we need to consider many aspects. be based ontransformIt will be more convenient for calculation,translaterotatescaleCan be converted totransformForm.

/**
 * canvas.transform(sx, ry, rx, sy, tx, ty)
 *SX horizontal scale, ry vertical tilt, RX horizontal tilt, sy vertical scale, TX horizontal move, ty vertical move
 *
 */
function Transform() {
  this.reset();
}

Transform.prototype.reset = function() {
  this.transformData = [1,0,0,1,0,0];
};

Transform.prototype.translate = function(x, y) {
  let [sx,ry,rx,sy,tx,ty] = this.transformData;
  const newTX = sx * x + rx * y;
  const newTY = ry * x + sy * y;
  this.transformData = [sx,ry,rx,sy,newTX,newTY];
};

Transform.prototype.rotate = function(angle) {
  let c = Math.cos(angle);
  let s = Math.sin(angle);
  let [sx,ry,rx,sy,tx,ty] = this.transformData;
  let newSX = sx * c + rx * s;
  let newRY = ry * c + sy * s;
  let newRX = sx * -s + rx * c;
  let newSY = ry * -s + sy * c;
  this.transformData = [newSX,newRY,newRX,newSY,tx,ty];
};

Transform.prototype.scale = function(x, y) {
  let [sx,ry,rx,sy,tx,ty] = this.transformData;
  let newSX = sx * x;
  let newRY = ry * x;
  let newRX = rx * y;
  let newSY = sy * y;
  this.transformData = [newSX,newRY,newRX,newSY,tx,ty];
};

Transform.prototype.getCoordinate = function(x, y) {
  let [sx,ry,rx,sy,tx,ty] = this.transformData;
  const px = x * sx + y*rx + tx;
  const py = x * ry + y*sy + ty;
  return [px,py];
};

reference material