Недавно столкнулся с задачей трансформации (масштабирование, поворот или наклон) объекта относительно произвольной точки. Предлагаю к ознакомлению свое решение этой задачи.
package com.dmitrykrasnov.research {
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
public class TransformationAboutPoint extends Sprite {
public function TransformationAboutPoint() {
// Для примера, нарисуем квадрат.
var myBox : Shape = new Shape();
myBox.graphics.lineStyle(1, 0x000000);
myBox.graphics.beginFill(0x000000);
myBox.graphics.drawRect(16, 16, 32, 32);
myBox.graphics.endFill();
// Возьмем его матрицу трансформации и повернем ее на 45 градусов.
// Заметьте, поворот произойдет относительно начала координат.
var myMatrix : Matrix = myBox.transform.matrix;
myMatrix.rotate(Math.PI / 4);
// Выберем точку вращения (пусть это будет центр нашего квадрата).
var axisPoint : Point = new Point(32, 32);
// Выясним, куда она сместилась в результате поворота.
var newPoint : Point = myMatrix.transformPoint(axisPoint);
// Вычислим относительное смещение.
var deltaX : Number = axisPoint.x - newPoint.x;
var deltaY : Number = axisPoint.y - newPoint.y;
// Компенсируем относительное смещение.
myMatrix.translate(deltaX, deltaY);
// Применим трансформации к нашему квадрату.
myBox.transform.matrix = myMatrix;
// Посмотрим на результат.
addChild(myBox);
// На всякий случай, нарисуем проверочные направляющие.
var guideLines : Shape = new Shape();
guideLines.graphics.lineStyle(1, 0xFF0000);
guideLines.graphics.moveTo(0, axisPoint.y);
guideLines.graphics.lineTo(64, axisPoint.y);
guideLines.graphics.moveTo(axisPoint.x, 0);
guideLines.graphics.lineTo(axisPoint.x, 64);
addChild(guideLines);
}
}
}Если кому-то известно более изящное решение, пожалуйста, опишите его в комментариях.
Насчет изящности не знаю, но в моем переводе статьи про Motion XML описан способ через transformationPoint
ОтветитьУдалитьhttp://fla-master.livejournal.com/5588.html
fla-master, указанный вами способ очень хорош там, где нужна анимация. Если же речь идет о статичном размещении объектов, об отображении на bitmap или о построении градиентов, то Motion XML ни к чему. О решении именно таких задач я и писал.
ОтветитьУдалитьМатричные (хоть 2D, хоть 3D) поворот и масштабирование делаются вокруг центра матрицы. Чтобы выполнить трансформацию вокруг произвольной точки достаточно предварительно сдвинуть матрицу, чтобы эта самая точка стала центром (x -= px, y -= py). После чего выполнить необходимые преобразования и вернуть матрицу на место (x += px, y += py).
ОтветитьУдалитьАнтон Волков, а можно подробней?
ОтветитьУдалитьКуда уж подробнее :)
ОтветитьУдалитьВ вашем случае:
myMatrix.translate(-axisPoint.x, -axisPoint.y);
myMatrix.rotate(Math.PI / 4);
myMatrix.translate(axisPoint.x, axisPoint.y);
Антон Волков
ОтветитьУдалить+1
для большого количества точек жельательно один раз посчитать матрицу преобразования, и с помощью нее преобразовывать все точки (будет меньше вычислений).
ОтветитьУдалитьMATR = MatrTrans(-point) * MatrRot * MatrTrans(+point)
во, дела! я со своим каментом почти на год опоздал :)
ОтветитьУдалить> во, дела! я со своим каментом почти на год опоздал :)
ОтветитьУдалитьНу, это не страшно. Ваш комментарий не стал от этого менее полезным.
Вам и всем отписавшимся - огромное спасибо за дельные мысли.
Стоит отметить, что такие н
ОтветитьУдалитьО-о-огроменное спасибо! Почти спас от бессонной ночи! :)
ОтветитьУдалить