![]() |
|
||||||||||
|
|||||
|
Регистрация: Feb 2011
Сообщений: 100
|
Она некорректна, потому что стена это отрезок, а не вектор. Если матеманически, то надо посчитать проекцию вектора (допустим A) на стену (получим вектор B) , и проекцию вектора на нормаль к стене (вектор C), потом умножить скалярно С на -1 и сложить B и C. Будет искомый вектор.
|
|
|||||
|
Регистрация: Feb 2011
Сообщений: 100
|
Ещё покрутив в голове задачку, придумал немного более быстрое решение:
A - исходный вектор B - проекция вектора на стенку Отражённый вектор = 2*B - A. МОжет можно ещё как-то упростить, но я думаю уже хватит. Как найти проекцию вектора на стенку надо говорить? |
|
|||||
|
Регистрация: Feb 2011
Сообщений: 100
|
Вон есть уже в том коде вектора, что я дал:
public function projectOnto( v:Vector2D ):Vector2D { var dp:Number = this.dot(v); var f:Number = dp / ( v.x*v.x + v.y*v.y ); return new Vector2D( f*v.x , f*v.y); } По идее должно сработать. А потом |
|
|||||
|
Регистрация: Mar 2011
Адрес: Минск
Сообщений: 11
|
если нужно получить зеркальный отскок от стены заданной вектором, то можно: найти угл между нашим вектором и вектором стены и поверунуть наш вектор на 2 таких угла.
UPD: в общем вот мой 2D вектор: (есть сериализация, и лишние вычисления(X Y length angle - пересчитываются все разом, кто хочет может реализовать отложенные вычисления - лично мне было лень, н 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. |
![]() |
![]() |
Часовой пояс GMT +4, время: 20:09. |
|
|
« Предыдущая тема | Следующая тема » |
|
|