Показать сообщение отдельно
Старый 14.09.2011, 14:27
inozemcev вне форума Посмотреть профиль Отправить личное сообщение для inozemcev Найти все сообщения от inozemcev
  № 1  
Ответить с цитированием
inozemcev
 
Аватар для inozemcev

блогер
Регистрация: Mar 2010
Адрес: x = stage.stageWidth/2 y= stage.stageHeight/2
Сообщений: 293
Записей в блоге: 2
По умолчанию actionscript и физика

Ребята помогите разобраться с физикой и реализовать задачу пересечения двух векторов.

Задача при пересечении дух векторов - вектора мяча и вектора стены - получить новый вектор мяча.

Сам ориентировался на данную статью. Смог разобраться в терминологии, смог найти точку пересечения, но построить новый вектор не получается. К автору топика уже не обратится. статья старая.

В статье используется ationscript 1 Поэтому сделал несколько отличный код, ввел понятия VectorDara VectorView

Код AS3:
public class VectorData 
{
	private var _start:Point;
	private var _end:Point;
	private var _delta:Point;
 
	private var _ort:Point;
 
	private var _normal_l:VectorData;
	private var _normal_r:VectorData;
 
	public static const END_POINT:Boolean = true;
	public static const DELTA_POINT:Boolean = false;
 
	public function VectorData(start:Point, endOrDelta:Point, type:Boolean = END_POINT)  
	{
		_start = start; 
		if (type)
		{
			_end = endOrDelta;
			_delta = new Point (_end.x - _start.x, _end.y - _start.y);
		} else {
			_delta = endOrDelta;
			_end = new Point (_start.x + _delta.x, _start.y + _delta.y);
		}
	}
 
	public function get start () :Point
	{
		return _start;
	}
 
	public function get delta () :Point
	{
		return _delta;
	}
 
	public function get end () :Point
	{
		return _end;
	}
 
	public function get length () :Number
	{
		return Math.sqrt (delta.x * delta.x + delta.y * delta.y);
	}
 
	public function get ort () :Point
	{
		if (!_ort)
		{
			_ort = new Point (delta.x / length, delta.y / length);
		}
		return _ort;
	}
 
	public function get rad () :Number
	{
		return Math.atan2 (ort.y, ort.x);
	}
 
	public function get gradus () :Number
	{
		return rad * 180 / Math.PI;
	}
 
	public function get normal_l () :VectorData
	{
		if (!_normal_l)
		{
			_normal_l = new VectorData(start,new Point (-delta.y, delta.x), VectorData.DELTA_POINT);
		}
		return _normal_l;
	}
 
	public function get normal_r () :VectorData
	{
		if (!_normal_r)
		{
			_normal_r = new VectorData(start,new Point (delta.y, - delta.x), VectorData.DELTA_POINT);
		}
		return _normal_r;
	}
 
	public static function add (vector1:VectorData, vector2:VectorData) :VectorData
	{
		var newDelta:Point = new Point (vector1.delta.x + vector2.delta.x, vector1.delta.y + vector2.delta.y);
		var newVector:VectorData = new VectorData (vector1.start, newDelta, false);
		return newVector;
	}
 
	public static function cosA (vector1:VectorData, vector2:VectorData) :Number
	{
		return (vector1.ort.x * vector2.ort.x + vector1.ort.y * vector2.ort.y);
	}
 
	public static function scalar (vector1:VectorData, vector2:VectorData) :Number
	{
		return (vector1.length * vector2.length * VectorData.cosA (vector1, vector2))
	}
 
	public static function proection (vector:VectorData, scalarDot:int ) :Point
	{
		var newDelta:Point = new Point (vector.ort.x * scalarDot / vector.length, vector.ort.y * scalarDot / vector.length);
		return newDelta;
	}
 
	public static function intersection (vector1:VectorData, vector2:VectorData) :Point
	{
		var delta3:Point = new Point (vector2.start.x - vector1.start.x, vector2.start.y-vector1.start.y);
		var vector3:VectorData = new VectorData (vector1.start, delta3, DELTA_POINT); 
 
		var t:Number = scalarNV (vector3, vector2) / scalarNV (vector1, vector2); 
		return new Point (vector1.start.x + vector1.delta.x * t, vector1.start.y + vector1.delta.y * t);
	}
 
	public static function scalarNV (vector1:VectorData, vector2:VectorData) :int
	{
		return vector1.delta.x * vector2.delta.y - vector1.delta.y* vector2.delta.x;
	}
 
	public static function dot (vector1:VectorData, vector2:VectorData) :int
	{
		return vector1.delta.x * vector2.delta.x + vector1.delta.y * vector2.delta.y;
	}
 
}

И собственно главный класс Main
Код AS3:
public class Main extends Sprite 
	{
		private var start:Point;
		private var vectorDatas:Array = [];
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			stage.addEventListener (MouseEvent.CLICK, onClick);
		}
 
		private function onClick (event:MouseEvent) :void
		{
			if (numChildren == 3) 
			{
				vectorDatas = [];
				while (numChildren) removeChildAt (0);
				start = null;
			}
 
			var end:Point = new Point (event.stageX, event.stageY);
			if (start)
			{
				var vectorData:VectorData = new VectorData (start, end);
				//trace ('Vector length : ' + vectorData.length);
 
				vectorDatas.push(vectorData);
 
				var vectorView:VectorView = new VectorView (vectorData);
				addChild (vectorView);
 
				vectorView.draw ();
				start = null;
			} else {
				start = end;
			}
 
 
			if (numChildren == 2)
			{
 
 
				vectorData = makeBounce (vectorDatas[0], vectorDatas[1]);
				vectorView = new VectorView (vectorData);
				vectorView.draw (1, 0xCCCC00, 1);
				addChild (vectorView);
			}
		}
 
		private function makeBounce (vector1:VectorData, vector2:VectorData) :VectorData
		{
			var iPoint:Point = VectorData.intersection (vector1, vector2);
 
			var dot_v1_v2:int = VectorData.dot (vector1, vector2);
			var dot_v1_v2_left:int = VectorData.dot (vector1, vector2.normal_l);
 
			var proectionV2:Point = VectorData.proection (vector2, dot_v1_v2);
			var proectionV2left:Point = VectorData.proection (vector2, dot_v1_v2_left);
 
			proectionV2left.x *= -1;
			proectionV2left.y *= -1;
 
			var newVectorDelta:Point = new Point(proectionV2.x + proectionV2left.x, proectionV2.y + proectionV2left.y);
			var newVector:VectorData = new VectorData (iPoint, newVectorDelta, VectorData.DELTA_POINT);
			return newVector;
		}
 
		/*
		private function createVector (start:Point, endOrDelta:Point, color:int, type:Boolean = VectorData.END_POINT) :VectorView
		{
			var vectorData:VectorData = new VectorData (start, endOrDelta, type);
			var vectorView:VectorView = new VectorView (vectorData);
			vectorView.draw (1, color, 1);
			return vectorView;
		}
		*/
	}


Последний раз редактировалось inozemcev; 14.09.2011 в 14:36.