|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Jan 2014
Сообщений: 6
|
Тригонометрия. Ошибка в условии изменения дельты угла в радиальной системе координат.
Добрый день!
Проблема в следующем: В прикрепленном ролике подвижный корабль (ship) летит к синему указателю цели (pointer), который перемещается вокруг неподвижного корабля (target). Мне нужно, чтобы при значении угла α < 90 градусов (т.е. Math.PI/2) синий указатель менял направление перемещения на противоположное. Угол α на картинке обозначен. Вот код функции ответственной за перемещение указателя: function MovePointer(ship:Object, targ:Object, point:Object, R:Number, DAngle:Number):Number { var angle = Math.atan2(point.y - targ.y, point.x - targ.x); if ( Math.abs( Math.PI-( angle - (Math.PI+Math.atan2(ship.y - targ.y, ship.x - targ.x)) ) ) < Math.PI/2 ) { DAngle=-DAngle; } angle += DAngle; point.x = targ.x + R * Math.cos(angle); point.y = targ.y + R * Math.sin(angle); return DAngle; } StarControl.rar |
|
|||||
Регистрация: Jan 2014
Сообщений: 6
|
Изменил алгоритм на:
function MovePointer(ship:Object, targ:Object, point:Object, R:Number, DAngle:Number):Number { var angle = Math.atan2(point.y - targ.y, point.x - targ.x); trace (Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle); if ( ( Math.abs( Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle ) < (Math.PI/2 + 2*Math.abs(DAngle)) ) || ( Math.abs( Math.atan2(ship.y - targ.y, ship.x - targ.x) - angle ) > (Math.PI*3/2 - 2*Math.abs(DAngle)) ) ) { DAngle=-DAngle; } angle += DAngle; point.x = targ.x + R * Math.cos(angle); point.y = targ.y + R * Math.sin(angle); return DAngle; } StarControl.rar |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Примерно так должно быть:
const product : Number = (point.y - targ.y) * (ship.y - targ.y) + (point.x - targ.x) * (ship.x - targ.x); if (product > 0) { DAngle = -DAngle; } Вычисление угла и вращение стоит оставить ваше. |
|
|||||
Регистрация: Jan 2014
Сообщений: 6
|
Цитата:
Как вы к этому выражению пришли? "(point.y - targ.y) * (ship.y - targ.y) + (point.x - targ.x) * (ship.x - targ.x)" Если не сложно - можно фото вычислений на бумаге? Или ссыль какую) Последний раз редактировалось InSelecto; 13.01.2014 в 00:55. |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Цитата:
Мне кажется, нужно менять алгоритм. Пока угол тупой - target движется в предыдущем направлении. Если же угол острый (или прямой) - затупляем его вне зависимости от предыдущего движения. Для этого смотрим на знак if (product < 0) { const crossProduct : Number = (point.y - targ.y) * (ship.x - targ.x) - (point.x - targ.x) * (ship.y - targ.y); DAngle = (crossProduct <= 0 ? -1 : 1) * Math.abs(DAngle); } Не люблю считать в углах, если все можно посчитать в векторах. В углах очень много граничных случаев. Ваша задача проверки угла на тупизну эквивалентна проверке знака косинуса угла. А проверка знака косинуса угла эквивалентна проверке знака скалярного произведения векторов (скалярное произведение равно произведению длин на косинус угла между ними). Формула product - формула скалярного произведения векторов по их коордиантам в ортонормированном базисе. Формула crossProduct - "длина" векторного произведения векторов, ее знак определяет направление поворота между векторами (в каком случае положительно - не помню). Т.е. при изменении порядка веткоров "векторное произведение" поменяет знак. Пока точные углы не нужны, векторного произведения вполне достаточно для качественной оценки (поворот по/против часовой стрелки). Вся необходимая теория - в учебниках по линейной алгебре (первый курс университетов). |
|
|||||
Регистрация: Jan 2014
Сообщений: 6
|
Цитата:
Добавлено через 11 минут Цитата:
|
|
|||||
.
|
Прошу прощения за занудство, но по решению комиссии IEEE от 30.02.1901 года, термин "радиальная" (Система Координат) заменен на полярная (СК).
|
Часовой пояс GMT +4, время: 01:29. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|