Показать сообщение отдельно
Старый 14.09.2011, 22:45
kodo вне форума Посмотреть профиль Отправить личное сообщение для kodo Найти все сообщения от kodo
  № 18  
Ответить с цитированием
kodo

Регистрация: Mar 2011
Адрес: Минск
Сообщений: 11
если нужно получить зеркальный отскок от стены заданной вектором, то можно: найти угл между нашим вектором и вектором стены и поверунуть наш вектор на 2 таких угла.

UPD: в общем вот мой 2D вектор:
(есть сериализация, и лишние вычисления(X Y length angle - пересчитываются все разом, кто хочет может реализовать отложенные вычисления - лично мне было лень, н

Код AS3:
package kodo_basic 
{
 
	import flash.utils.IDataInput;
	import flash.utils.IDataOutput;
	import flash.utils.IExternalizable;
 
	/**
	 * ...
	 * @author Kodo
	 * 
	 * Клас вектора.
	 * 
	 * Для удобства храняться и используются градусы а не раианы(каждый раз переводятся)!!!!
	 * Угл сохраняется в формате (-180, 180] где [0-180] - по часовой, (0,-180) - против часовой
	 */
	public class Vector2D implements IExternalizable
	{
		// Используются большие буквы!! - чтобы опреедлить get\set с маленькой
		//Длинна
		private var Length:Number;
		//угл
		private var myAngle:Number;
		private var X:Number;
		private var Y:Number;
 
		/** ДЛИННА ВОСПРИНИМАЕТСЯ ПО МОДУЛЮ!! */
		public function Vector2D( newLenght:Number = 0, newAngle:Number = 0 ) 
		{
			Length = Math.abs( newLenght );
			// Вызываем Set для угла, тамже автоматически установятся и x,y
			this.angle = newAngle;
 
 
 
		}
 
		// Методы СЕРИАЛИЗАЦИИ
		public function readExternal(input:IDataInput):void
		{
			Length = input.readDouble();
			myAngle = input.readDouble();
			X = input.readDouble();
			Y = input.readDouble();
		}
 
		public function writeExternal(output:IDataOutput):void
		{
 
			output.writeDouble(Length);
			output.writeDouble(myAngle);
			output.writeDouble(X);
			output.writeDouble(Y);
		}
 
 
		public function coppy():Vector2D
		{
			return new Vector2D( this.Length, this.myAngle );
		}
 
		public function get x():Number
		{
			return X;
		}
		public function set x(newX:Number):void
		{
			X = newX;
			Length = Math.sqrt(X * X + Y * Y);
			myAngle = Math.atan2(Y, X) * 180 / Math.PI;
		}
 
 
		public function get y():Number
		{
			return Y;
		}
		public function set y(newY:Number):void
		{
			Y = newY;
			Length = Math.sqrt(X * X + Y * Y);
			myAngle = Math.atan2(Y, X) * 180 / Math.PI;
		}
 
		public function get length():Number
		{
			return Length;
		}
		public function set length( newLength:Number ):void
		{
			if( newLength >= 0)
			{
				Length = newLength;
			}
			else
			{
				// корректируем длинну
				Length = Math.abs(newLength);
				// корректируем угл
				myAngle = (myAngle + 180) % 360;
				if (myAngle > 180) this.myAngle = myAngle - 360;
				else if (myAngle <= -180) this.myAngle = myAngle + 360;
			}
			Y = Length * Math.sin( myAngle * Math.PI/180);
			X = Length * Math.cos( myAngle * Math.PI/180);
		}
 
		public function get angle():Number
		{
			return myAngle;
		}
		public function set angle( newAngle:Number ):void
		{
			newAngle = newAngle % 360;
			if (newAngle > 180) this.myAngle = newAngle - 360;
			else if (newAngle <= -180) this.myAngle =newAngle + 360;
			else this.myAngle = newAngle;
			Y = Length * Math.sin( myAngle * Math.PI/180);
			X = Length * Math.cos( myAngle * Math.PI/180);		
		}
 
		// Складывает вектор-параметр с текущим
		public function sumVectors( newVector:Vector2D ):void
		{
			X += newVector.x;
			Y += newVector.y;
			Length = Math.sqrt(X * X + Y * Y);
			myAngle = Math.atan2(Y, X) * 180 / Math.PI;
		}
		/**
		 * Возвращает дельта-угл между данным вектором и вектором-параметром.
		 * результатом будет угл который стоит прибавить к вектору чтобы он был повёрнут втуже сторону что вектр-параметр.
		 * @param	targetVector2D	- вектор-параметр
		 * @return	угл который стоит прибавить к вектору чтобы он был повёрнут втуже сторону что вектр-параметр
		 */
		public function  deltaAngleToVector2D( targetVector2D:Vector2D ):Number
		{
			var deltaAngle:Number = (targetVector2D.angle - this.angle);
			if ( deltaAngle > 180) deltaAngle = deltaAngle - 360;
			else if (deltaAngle <= -180) deltaAngle = deltaAngle + 360;
			return deltaAngle;
		}
		// Возвращает дельта-угл между данным вектором и некоторым углом-параметром.
		// результатом будет угл который стоит прибавить к вектору чтобы он был повёрнут втуже сторону что угл-параметр.
		public function deltaAngleToAngle( targetAngle:Number ):Number
		{
			// Здесь используем остаток от деления на 360 - на случай ввода угла не из промежутка (-180,180]
			var deltaAngle:Number = (targetAngle - this.angle)%360;
			if ( deltaAngle > 180) deltaAngle = deltaAngle - 360;
			else if (deltaAngle <= -180) deltaAngle = deltaAngle + 360;
			return deltaAngle;			
		}
 
		public function toString():String
		{
			return new String( "[Vector, length: " + this.Length + " , angle:" + this.myAngle + "]" );
		}
	}
 
}


Последний раз редактировалось kodo; 14.09.2011 в 23:52.