|
|
|||||
Умножение матрицы на нормаль
Помогите разобраться плз, суть такая:
Есть 4 точки в пространстве (вершины прямоугольника). И есть нормализованный вектор, указывающий направление. Какие действия нужно выполнить, что-бы повернуть прямоугольник в доль нормали? var normal:Point = new Point(4, 2); var p1:Point = new Point(150, 150); var p2:Point = new Point(250, 150); var p3:Point = new Point(250, 250); var p4:Point = new Point(150, 250); normalize(normal); function normalize(vec:Point):void { var len:Number = Math.sqrt(vec.x * vec.x + vec.y * vec.y); vec.x /= len; vec.y /= len; }
__________________
Дети не должны знать о своих родителях |
|
|||||
Цитата:
Если просто спрайт повернуть, то: Если именно точки и именно относительно начала координат, то: Matrix matrix = new Matrix(v.x, -v.y, v.y, v.x); var p1_ = matrix.transformPoint(p1); var p2_ = matrix.transformPoint(p2); var p3_ = matrix.transformPoint(p3); var p4_ = matrix.transformPoint(p4); 1. Этот центр надо найти 2. Сместить его в (0, 0), прибавив ко всем точкам (-center.x, -center.y) 3. Повернуть матрицей matrix 4. Сдвинуть точки обратно, прибавив ко всем точкам (center.x, center.y) Центр для прямоугольника ищется тупо как среднее арифметическое: |
|
|||||
Вот, изобразил задачу графически:
То-есть, у прямоугольника есть исходные данные: 1. Положение центра в некоторой прямоугольной системе координат: x и y, 2. Координаты вершин этого прямоугольника, в этой системе. Для каждой из 4 точек: x и y Задача состоит в том, что-бы получить новые координаты вершин, "повернув" прямоугольник вокруг его центра. Для поворота используется нормализованный вектор, указывающий угол поворота. (стрелочка внутри прямоугольника) Хотелось бы узнать решение, без применения готовых классов, таких как matrix.
__________________
Дети не должны знать о своих родителях |
|
|||||
например
public function Main():void { var p1:Point = new Point(150, 150); var p2:Point = new Point(250, 150); var p3:Point = new Point(250, 250); var p4:Point = new Point(150, 250); var center:Point = new Point(200, 200); var v:Vector.<Point> = Vector.<Point>([p1, p2, p3, p4]); var v1:Vector.<Point> = new Vector.<Point>(); var rot:Point = new Point(4, 2); var angle:Number = Math.atan2(rot.y, rot.x); for (var i:int = 0; i < v.length; i++) { v1.push(rotatePoint(v[i], center, angle)); } drawFig(v,0x0000FF); drawFig(v1, 0xFF0000); } private function rotatePoint(p:Point, c:Point, a:Number):Point { var dist:Number = Point.distance(c, p); var dir:Number = Math.atan2(p.y - c.y, p.x - c.x); return c.add(Point.polar(dist, dir + a)); } private function drawFig(vertices:Vector.<Point>, color:int=0):void { graphics.lineStyle(1, color); graphics.moveTo(vertices[vertices.length - 1].x, vertices[vertices.length - 1].y); for (var i:int = 0; i < vertices.length; i++) { graphics.lineTo(vertices[i].x, vertices[i].y); } } |
|
|||||
Спасибо Silin. У тебя даже с примером цветным
Но все-же, меня интересовало решение без использования методов сторонних классов, чистое решение. Вот такой получился вариант, на форуме dxdy помогли: import flash.geom.Point; import flash.events.MouseEvent; var center:Point = new Point(200, 200); var p1:Point = new Point(100, 100); var p2:Point = new Point(300, 100); var p3:Point = new Point(300, 300); var p4:Point = new Point(100, 300); var normal:Point = new Point; stage.addEventListener(MouseEvent.MOUSE_MOVE, mouse); function normalize(vec:Point):void { var d:Number = Math.sqrt(vec.x * vec.x + vec.y * vec.y); vec.x /= d; vec.y /= d; } function mouse(e:MouseEvent):void { normal.x = mouseX - center.x; normal.y = mouseY - center.y ; normalize(normal); draw(); } function draw():void { this.graphics.clear(); this.graphics.lineStyle(1, 0xff0000); this.graphics.moveTo(center.x, center.y); this.graphics.lineTo(center.x + normal.x*50, center.y + normal.y*50); // Поворот квада var dx:Number; var dy:Number; dx = p1.x-center.x; dy = p1.y-center.y; var op1:Point = new Point(dx*normal.y + dy*normal.x, dx*(-normal.x) + dy * normal.y); dx = p2.x-center.x; dy = p2.y-center.y; var op2:Point = new Point(dx*normal.y + dy*normal.x, dx*(-normal.x) + dy * normal.y); dx = p3.x-center.x; dy = p3.y-center.y; var op3:Point = new Point(dx*normal.y + dy*normal.x, dx*(-normal.x) + dy * normal.y); dx = p4.x-center.x; dy = p4.y-center.y; var op4:Point = new Point(dx*normal.y + dy*normal.x, dx*(-normal.x) + dy * normal.y); this.graphics.drawCircle(op1.x + center.x, op1.y+center.y, 5); this.graphics.drawCircle(op2.x + center.x, op2.y+center.y, 5); this.graphics.drawCircle(op3.x + center.x, op3.y+center.y, 5); this.graphics.drawCircle(op4.x + center.x, op4.y+center.y, 5); this.graphics.moveTo(op1.x + center.x, op1.y + center.y); this.graphics.lineTo(op2.x + center.x, op2.y + center.y); this.graphics.lineTo(op3.x + center.x, op3.y + center.y); this.graphics.lineTo(op4.x + center.x, op4.y + center.y); this.graphics.lineTo(op1.x + center.x, op1.y + center.y); }
__________________
Дети не должны знать о своих родителях |
|
|||||
Ну уж примитивные add/substract/normalize не использовать это слишком
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; public class Vectors extends Sprite { private var _vertices:Vector.<Point>; private var _rotated:Vector.<Point>; private var _center:Point; public function Vectors() { var p1:Point = new Point(150, 150); var p2:Point = new Point(250, 150); var p3:Point = new Point(250, 250); var p4:Point = new Point(150, 250); _center = new Point(200, 200); _vertices = Vector.<Point>([p1, p2, p3, p4]); _rotated = new Vector.<Point>(); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } private function mouseMoveHandler(event:MouseEvent):void { graphics.clear(); var normal:Point = new Point(event.stageX - _center.x, event.stageY - _center.y); drawLine(_center, _center.add(normal)); drawFig(_vertices, 0xFF0000); normal.normalize(1); for (var i:int = 0; i < _vertices.length; i++) { _rotated[i] = rotatePoint(_vertices[i], _center, normal); } drawFig(_rotated, 0x0000FF); } private function rotatePoint(p:Point, zero:Point, normal:Point):Point { var t:Point = p.subtract(zero); var dx:Number = t.x * normal.y + t.y * normal.x; var dy:Number = t.x * -normal.x + t.y * normal.y; t.x = dx; t.y = dy; return t.add(zero); } private function drawFig(vertices:Vector.<Point>, color:uint=0):void { graphics.lineStyle(1, color); graphics.moveTo(vertices[vertices.length - 1].x, vertices[vertices.length - 1].y); for (var i:int = 0; i < vertices.length; i++) { graphics.lineTo(vertices[i].x, vertices[i].y); } } private function drawLine(p1:Point, p2:Point, color:uint = 0):void { graphics.lineStyle(1, color); graphics.moveTo(p1.x, p1.y); graphics.lineTo(p2.x, p2.y); } } } Вот так это выглядело бы с матрицей: package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.geom.Point; public class Vectors extends Sprite { private var _vertices:Vector.<Point>; private var _rotated:Vector.<Point>; private var _center:Point; private var _m:Matrix; public function Vectors() { var p1:Point = new Point(150, 150); var p2:Point = new Point(250, 150); var p3:Point = new Point(250, 250); var p4:Point = new Point(150, 250); _center = new Point(200, 200); _m = new Matrix(); _m.tx = _center.x; _m.ty = _center.y; /* * для простоты смещаем в начало координат. * точнее их изначально надо было задавать от начала * координат */ _vertices = Vector.<Point>([p1.subtract(_center), p2.subtract(_center), p3.subtract(_center), p4.subtract(_center)]); _rotated = new Vector.<Point>(); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } private function mouseMoveHandler(event:MouseEvent):void { graphics.clear(); var normal:Point = new Point(event.stageX - _center.x, event.stageY - _center.y); drawLine(_center, _center.add(normal)); normal.normalize(1); _m.a = normal.y; //косинус угла поворота _m.b = -normal.x; //синус угла поворота _m.c = normal.x; //синус угла поворота _m.d = normal.y; //косинус угла поворота for (var i:int = 0; i < _vertices.length; i++) { _rotated[i] = _m.transformPoint(_vertices[i]); } drawFig(_rotated, 0x0000FF); } private function drawFig(vertices:Vector.<Point>, color:uint=0):void { graphics.lineStyle(1, color); graphics.moveTo(vertices[vertices.length - 1].x, vertices[vertices.length - 1].y); for (var i:int = 0; i < vertices.length; i++) { graphics.lineTo(vertices[i].x, vertices[i].y); } } private function drawLine(p1:Point, p2:Point, color:uint = 0):void { graphics.lineStyle(1, color); graphics.moveTo(p1.x, p1.y); graphics.lineTo(p2.x, p2.y); } } }
__________________
משיח לא בא משיח גם לא מטלפן |
|
|||||
Цитата:
В нашей конторе мы эти методы вообще не использовали по одной простой причине: Они создают новые точки. Т.е. в теории удобно - на практике невозможно использовать. Это боевого кода, конечно, касается. |
|
|||||
Мне была нужна матрица 2х2, для двумерной проекций. Я сам не очень хорошо понимаю эти марицы, к тому-же, документаций по AGAL довольно мало, не понятно как там выполняется умножение m33 или m44.
Команда нормализаций обрабатывает вектора только с 3 значениями, мой же в 2д.
__________________
Дети не должны знать о своих родителях |
Часовой пояс GMT +4, время: 18:28. |
|
« Предыдущая тема | Следующая тема » |
|
|