Использование матрицы преобразования в KineticJS

У меня есть тело, смоделированное с помощью Box2Dweb, и изображение, прикрепленное к телу. Я хочу взять матрицу преобразования тела и применить преобразование к изображению (нарисовать изображение с преобразованием), чтобы его положение и ориентация (относительная) на экране совпадали с позицией тела. Я не могу найти функцию для использования с матрицей преобразования в KineticJS. Есть отдельные функции для перемещения и вращения, и есть Kinetic.Transform класс, который содержит некоторую "матрицу" внутри, но я понятия не имею, что с этим делать. Там также есть _setTransform где-то функционировать, но опять же, не знаю, как его использовать (и подчеркивает ли это, что я не должен вызывать его напрямую или как?).

Я использовал этот код для рисования изображений поверх тел в простом Javascript:

function drawImageOverBody(context, body, image, scale)
{
    context.save();
    var pos = body.GetPosition();
    var center = [scale*pos.x, scale*pos.y];
    var R = body.GetTransform().R;
    context.translate(center[0], center[1]);
    context.transform(R.col1.x, R.col1.y, R.col2.x, R.col2.y, 0, 0);
    context.translate(-center[0], -center[1]);
    context.drawImage(image, center[0] - image.width/2.0, center[1] - image.height/2.0);
    context.restore();
}

Как мне сделать то же самое с KineticJS?

РЕДАКТИРОВАТЬ: очевидно, единственные преобразования, которые я могу получить от Box2d, это перевод и вращение, которые я могу получить, вызвав GetPosition() а также GetAngle() на теле Box2d, затем примените к изображению KineticJS с setX(), setY() а также setRotation(), Поэтому мне не нужно преобразование в матричной форме здесь. Тем не менее, любопытно.

1 ответ

Kinetic.Transform Класс может быть использован для вычисления поворота, масштаба и смещения от заданной матрицы преобразования. Установить m атрибут Kinetic.Transform к матрице преобразования, затем используйте объект преобразования для вычисления поворота, масштаба и перемещения. Вращение, масштабирование и перевод могут быть применены к любому Kinetic.Node

Перевод дается непосредственно двумя последними пунктами в матрице.

Если вы приобрели преобразование из другого места, вы можете применить его к Kinetic.Transform как это:

var tf = new Kinetic.Transform ();
tf.m = [Math.sqrt (2), Math.sqrt (2), -3 / 2 * Math.sqrt (2), 3/2 * Math.sqrt (2), 4, 5];

Перевод самый простой. это дано двумя последними элементами: 4 в направлении X, 5 в направлении Y. Существует также способ получить его.

var translation = tf.getTranslation ();

Вы можете получить масштаб из матрицы преобразования:

var m = tf.getMatrix(); // or tf.m
var scaleX = Math.sqrt(m[0]*m[0] + m[1]*m[1]);
var scaleY = Math.sqrt(m[2]*m[2] + m[3]*m[3]);

Не забывайте, что изображение может быть перевернуто по оси X или Y или обоим. Рассчитайте определитель, чтобы принять это во внимание:

if(m[0]*m[3] - m[1]*m[2] < 0){
    scaleY = -scaleY;
}

Отрегулируйте знак весов, чтобы легче было вращать:

if(m[0] < 0){
    scaleX = -scaleX;
    scaleY = -scaleY;
}

Теперь последний, вращение. Вы можете получить это с помощью Math.asin или же Math.acos, но вы должны принять во внимание квадрант угла поворота. Это один из способов ее решения:

var angle = Math.acos(m[3] / scaleY);
if(m[2]/scaleY > 0){
    angle = -angle;
}

Обратите внимание, что порядок применения различных преобразований важен. Если вы используете метод, описанный выше, сначала примените перевод, затем вращение, затем масштабирование.

Другие вопросы по тегам