Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 17.03.2013, 14:57
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 1  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
По умолчанию Умножение матрицы на нормаль

Помогите разобраться плз, суть такая:

Есть 4 точки в пространстве (вершины прямоугольника). И есть нормализованный вектор, указывающий направление. Какие действия нужно выполнить, что-бы повернуть прямоугольник в доль нормали?

Код AS3:
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;
}
__________________
Дети не должны знать о своих родителях

Старый 17.03.2013, 15:44
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 2  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
в доль нормали?
Вдоль пишется слитно.

Если просто спрайт повернуть, то:
Код AS3:
rotation = Math.atan2(v.y, v.x) * 180 / Math.PI;
Если именно точки и именно относительно начала координат, то:
Код AS3:
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)

Центр для прямоугольника ищется тупо как среднее арифметическое:
Код AS3:
var center:Point = new Point(
    (p1.x + p2.x + p3.x + p4.x) / 4,
    (p1.y + p2.y + p3.y + p4.y) / 4);

Старый 17.03.2013, 16:42
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 3  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Вот, изобразил задачу графически:
Название: Untitled-1.png
Просмотров: 434

Размер: 5.4 Кб

То-есть, у прямоугольника есть исходные данные:
1. Положение центра в некоторой прямоугольной системе координат: x и y,
2. Координаты вершин этого прямоугольника, в этой системе. Для каждой из 4 точек: x и y

Задача состоит в том, что-бы получить новые координаты вершин, "повернув" прямоугольник вокруг его центра. Для поворота используется нормализованный вектор, указывающий угол поворота. (стрелочка внутри прямоугольника)

Хотелось бы узнать решение, без применения готовых классов, таких как matrix.
__________________
Дети не должны знать о своих родителях

Старый 17.03.2013, 17:40
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 4  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
например
Код AS3:
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);
	}
}

Старый 17.03.2013, 23:41
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 5  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Спасибо Silin. У тебя даже с примером цветным

Но все-же, меня интересовало решение без использования методов сторонних классов, чистое решение. Вот такой получился вариант, на форуме dxdy помогли:
Код AS3:
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);
}
__________________
Дети не должны знать о своих родителях

Старый 18.03.2013, 14:01
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 6  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Ну уж примитивные add/substract/normalize не использовать это слишком
Код AS3:
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);
		}
	}
}
Но в итоге, вы все равно пришли к матричному преобразованию. Ваши dx/dy это точка умноженная на матрицу.
Вот так это выглядело бы с матрицей:
Код AS3:
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);
		}
	}
}
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 18.03.2013, 17:12
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 7  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Ну уж примитивные add/substract/normalize не использовать это слишком
Мало ли.
В нашей конторе мы эти методы вообще не использовали по одной простой причине:
Они создают новые точки.
Т.е. в теории удобно - на практике невозможно использовать.
Это боевого кода, конечно, касается.

Старый 18.03.2013, 18:10
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 8  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
В моем случае, я хотел перенести эти вычисления на AGAL.
__________________
Дети не должны знать о своих родителях

Старый 18.03.2013, 18:17
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 9  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Там тоже есть готовый normalize/add/substract и матрицы. )
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 18.03.2013, 18:32
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 10  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Мне была нужна матрица 2х2, для двумерной проекций. Я сам не очень хорошо понимаю эти марицы, к тому-же, документаций по AGAL довольно мало, не понятно как там выполняется умножение m33 или m44.

Команда нормализаций обрабатывает вектора только с 3 значениями, мой же в 2д.
__________________
Дети не должны знать о своих родителях

Создать новую тему Ответ Часовой пояс GMT +4, время: 18:28.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 18:28.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.