Использование матрицы преобразования в 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(). Так что мне действительно не нужно преобразование в матричной форме здесь. Тем не менее, любопытно.


person Headcrab    schedule 16.01.2013    source источник


Ответы (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;
}

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

person pvoosten    schedule 23.02.2013
comment
Я что-то упустил из вашего ответа, или использование класса Kinetic.Transform действительно имеет очень мало смысла? Например, вы говорите, что поместите элементы матрицы преобразования в атрибут m, а затем используйте их для вычисления перемещения, поворота и масштабирования вручную. Зачем вообще беспокоиться об атрибуте m? - person Headcrab; 03.03.2013
comment
«Kinetic.Transform», вероятно, используется внутри для вычисления матрицы преобразования из атрибутов поворота, масштаба и перемещения. Матрица преобразования — это то, что фактически используется для выполнения преобразований. Вы можете расширить Kinetic.Transform реализацией, показанной выше, но она не содержит готовых методов как таковых. В качестве альтернативы вы можете просто скопировать код из моего сообщения, чтобы реализовать вспомогательные функции, которые будут делать то, что вам нужно. - person pvoosten; 05.03.2013
comment
Кто-нибудь знает о проблеме с github, отслеживающей эту функцию? - person freakTheMighty; 06.02.2014