Получить координаты изображения после поворота и перевода?

В настоящее время я рисую некоторые изображения (препятствия) на холсте, но я выполняю context.rotate() и context.translate(), прежде чем рисовать их (в точке 0,0 после перевода точки).

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

До того, как я реализовал вращение и перемещение, я выполнял столкновения, основываясь на средних точках транспортного средства и препятствия в нужное время. Однако я понятия не имею, как я могу получить фактические непереведенные и неповернутые координатные точки препятствий.

Примечание: для каждого препятствия я знаю переменную, которую я поворачиваю и перемещаю, проблема в том, что я выполняю поворот и перемещение несколько раз друг за другом, например так:

// set origin to center
context.translate(canvasX, canvasY);

context.rotate(i/30);
context.translate(20,10);

if(toggle < 20) {
    size++;
    if(size > 10) {
      size = 10;
    }
    drawImageRot(image_red, 0, 0, ((image_red.height / img_max) * size), ((image_red.width / img_max) * size), 30);
    //circle('red', size);
}
// rotate + move along x
context.rotate(y / 40);
context.translate(40, 0);

if(toggle > 100 && toggle < 120) {
    size++;
    if(size > 10) {
      size = 10;
    }
    drawImageRot(image_red, 0, 0, ((image_red.height / img_max) * size), ((image_red.width / img_max) * size), 30);
    //circle('red', size);
}
context.rotate(z / 20);
context.translate(5, 5);

if(toggle > 200 && toggle < 220) {
    size++;
    if(size > 10) {
      size = 10;
    }
    drawImageRot(image_red, 0, 0, ((image_red.height / img_max) * size), ((image_red.width / img_max) * size), 30);
}

Итак, на третьем изображении я бы сделал 4 разных перевода и 3 разных поворота.

Как я могу получить координаты точек препятствий? или в любом случае я могу легко проверить, перекрываются ли два изображения, не требуя координатных точек?

РЕДАКТИРОВАТЬ:

Я решил разделить обнаружение столкновений, чтобы проверять сразу после выполнения drawImageRot() следующим образом:

// set origin to center
context.translate(canvasX, canvasY);

context.rotate(i/30);
context.translate(20,10);

if(toggle < 20) {
    size++;
    if(size > 10) {
      size = 10;
    }
    drawImageRot(image_red, 0, 0, ((image_red.height / img_max) * size), ((image_red.width / img_max) * size), 30);
    // HERE I NEED TO SET my currentX and currentY points! But how?
    currentX = 0;
    currentY = 0;

    if((Math.abs(currentX - playerX) <= 20 && Math.abs(currentY - playerY) <= 20)) {
      drawCollision(currentX, currentY, size);
      isCollision = true;
    }
}

person dan2k3k4    schedule 17.05.2013    source источник


Ответы (1)


Похоже, я нашел свой ответ, @simonsarris создал класс transform.js, чтобы помочь перевести/повернуть точки «x, y»:

https://github.com/simonsarris/Canvas-tutorials/blob/master/transform.js

Например, по адресу: http://jsfiddle.net/b2fEX/.

// LIBRARY from:
// https://github.com/simonsarris/Canvas-tutorials/blob/master/transform.js
// code below

function Transform() {
  this.reset();
}

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

Transform.prototype.multiply = function(matrix) {
  var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1];
  var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1];

  var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3];
  var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3];

  var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4];
  var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5];

  this.m[0] = m11;
  this.m[1] = m12;
  this.m[2] = m21;
  this.m[3] = m22;
  this.m[4] = dx;
  this.m[5] = dy;
};

Transform.prototype.invert = function() {
  var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);
  var m0 = this.m[3] * d;
  var m1 = -this.m[1] * d;
  var m2 = -this.m[2] * d;
  var m3 = this.m[0] * d;
  var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);
  var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);
  this.m[0] = m0;
  this.m[1] = m1;
  this.m[2] = m2;
  this.m[3] = m3;
  this.m[4] = m4;
  this.m[5] = m5;
};

Transform.prototype.rotate = function(rad) {
  var c = Math.cos(rad);
  var s = Math.sin(rad);
  var m11 = this.m[0] * c + this.m[2] * s;
  var m12 = this.m[1] * c + this.m[3] * s;
  var m21 = this.m[0] * -s + this.m[2] * c;
  var m22 = this.m[1] * -s + this.m[3] * c;
  this.m[0] = m11;
  this.m[1] = m12;
  this.m[2] = m21;
  this.m[3] = m22;
};

Transform.prototype.translate = function(x, y) {
  this.m[4] += this.m[0] * x + this.m[2] * y;
  this.m[5] += this.m[1] * x + this.m[3] * y;
};

Transform.prototype.scale = function(sx, sy) {
  this.m[0] *= sx;
  this.m[1] *= sx;
  this.m[2] *= sy;
  this.m[3] *= sy;
};

Transform.prototype.transformPoint = function(px, py) {
  var x = px;
  var y = py;
  px = x * this.m[0] + y * this.m[2] + this.m[4];
  py = x * this.m[1] + y * this.m[3] + this.m[5];
  return [px, py];
};


// CODE:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');

ctx.fillRect(50,50,50,50);

var t = new Transform();
ctx.translate(50,0)
ctx.rotate(1);
t.translate(50,0);
t.rotate(1);

ctx.fillRect(50,50,50,50);
var pt = t.transformPoint(50,50);
alert('top left of translated rectangle is: ' + pt);
person dan2k3k4    schedule 17.05.2013