![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Dec 2013
Сообщений: 35
|
Привет.
У меня очередной вопрос. Хочу воссоздать алгоритм для движения некоторого обьекта в направлении противоположном координатам курсора. Движение может быть в любом мыслимом направлении в пределах плоскости, а не только вдоль координатных осей. Единственное до чего я додумался, что это как-то связано с нахождением уравнения прямой по координатам обьекта и текущим координатам курсора. 1. Я прав, что это делается через уравнение прямой. Или есть какой-то простой способ? 2. Напишите, пожалуйста, это уравнение для прямой. Если не трудно написать готовый код, буду очень благодарен. |
|
|||||
|
Если вы про линейное уравнение, то нет, здесь оно ни к месту =)
Для начала вот так var dir:Number = Math.atan2(mouseY-obj.y, mouseX-obj.x) / Math.PI * 180; dir += 180; var speed:Point = new Point(Math.cos(dir/180*Math.PI), Math.sin(dir/180*Math.PI)); Чтобы увеличить скорость движения используйте speed.normalize(10); - где 10 - новая скорость для объекта. Изначально скорость = 1, ибо на выходе после тригонометрических функций =) На самом деле, код можно упростить, но я использовал такой вид для наглядности действий. А это - элементарная тригонометрия и векторная алгебра.
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 18.02.2015 в 21:11. |
|
|||||
|
Регистрация: Dec 2014
Сообщений: 312
|
package { import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; public class Main extends Sprite { public function Main() { if (stage) addedToStage(); else addEventListener(Event.ADDED_TO_STAGE, addedToStage); } private function addedToStage(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStage); init(); } private function init():void { _circle = new Shape(); _circle.graphics.beginFill(0xff0000); _circle.graphics.drawCircle(0, 0, 50); _circle.x = stage.stageWidth / 2; _circle.y = stage.stageHeight / 2; addChild(_circle); addEventListener(Event.ENTER_FRAME, enterFrame); } private function enterFrame(e:Event):void { // при положительной скорости идем за курсором // при отрицательной - от курсора var speed:Number = -0.5; var p:Point = new Point(stage.mouseX - _circle.x, stage.mouseY - _circle.y); p.normalize(speed); _circle.x += p.x; _circle.y += p.y; } private var _circle:Shape; } } |
|
|||||
|
Регистрация: Dec 2013
Сообщений: 35
|
Ребята, вы просто отличные парни) Завидую, что для вас это всего лишь примитивная тригонометрия.
ZackMercury, я два дня страдал ради этих 2х строчек. callme, спасибо что не поленился написать целый класс. Я оценил широту твоей доброты) |
|
|||||
|
Регистрация: Jan 2012
Сообщений: 836
|
ZackMercury скинь ссылки по которым можно изучить.
|
|
|||||
|
Lorem ipsum
|
Лучше (читай элегантней) без тригонометрии.
__________________
Поймай яблоко 2! |
|
|||||
|
В блогах была пара замечательных записей, но к сожалению там что-то произошло с изображениями.
Ну, вот нашёл что-то интересное по тригонометрии. http://ege-study.ru/materialy-ege/tr...icheskij-krug/ ![]() Векторную алгебру можно на пальцах объяснить. В ней действует элементарная теорема пифагора. Допустим, есть у нас 2 точки - (2,4) и (6, 6) Расстояние от одной точки до другой? Запросто. Давайте нарисуем на координатной плоскости эти две точки.(да, да, возьмите лист бумаги и нарисуйте, вы) Как нам получить расстояние между этими двумя точками? Всё просто, рисуем от первой точки (2,4) до (6, 4) линию, и далее ведём её из этой точки ко второй точке. Мы получили сдвиг по иксу и сдвиг по игрику. Далее - дельтаИкс и дельтаИгрик. Далее всё ещё проще. Вспоминаем теорему Пифагора. Мы можем представить наши дельтуИкс и дельтуИгрик как катеты прямоугольного треугольника, и расстояние от одной точки до второй будет гипотенузой. Гипотенуза = корень из(катет1*катет1 + катет2*катет2); Расстояние между двумя точками равно корень из(дельтаИкс*дельтаИкс + дельтаИгрик*дельтаИгрик); В школе вы должны были встречаться с формулой c^2 = a^2 + b^2; где ^ - возведение в степень. Именно исходя из этой формулы и исчисляется расстояние между двумя точками. Так вот, вектор, который был прибавлен к первой точке, чтобы получить вторую равен разнице векторов (6-2, 6-4)=(4,2) Это должно быть понятно, прибавив к (2, 4) вектор (4,2) получаем (6,6) если мы к (6,6) прибавим (4,2) ещё раз, то направление движения не изменится, появится третья точка (6+4, 6+2) = (10, 8) Расстояние между первыми двумя точками будет равным расстоянию от второй до третьей. Все три точки будут на одной линии. Сколько не прибавляй к последней точке вектор (4,2) всё равно будет на одной линии каждая новая точка с остальными. То же и с отрицательными векторами. Длина вектора(расстояние между точками, или пройденный путь объекта) равна как раз корень из (4*4+2*2)=кореньиз(20) Нормаль - это вектор, длина которого равна единице. Тоесть, направление нормали может совпадать с направлением вектора, но она равна единице, а это значит, что путь, который проходит объект за одно прибавление вектора равен 1 пикселу. Для чего нужны нормали? Нормаль можно умножить на любое число и длина нормали станет этим числом. Из вектора можно сделать нормаль. Формулы, по которым можно это сделать можно найти в интернете. Введите в поисковик "нормализация вектора". Метод normalize класса Point делает дополнительную работу - он нормализирует вектор и сразу устанавливает его длину в передаваемый аргумент. Чтобы получить нормаль из любого вектора используем speed.normalize(1) Прошу обратить внимание, мы вычитаем дельтуИкс и дельтуИгрик между объектом и мышью, и нормализируем его(тоесть, сохраняем направление но длину, читай скорость перемещения устанавливаем в 1, ибо изначально она за одно перемещение достигнет конечной точки) Нормализация вектора получается путём деления каждого его компонента на его длину(а длина получается по теореме пифагора(или как ещё это называется по геометрическому среднему)). При этом выходит, что направление к мыши/от мыши настраивается путём подмены мест вычитаемых, т.е. mouseX - obj.x - к мыши obj.x - mouseX - от мыши Добавлено через 1 час 13 минут И заодно объясню, что я делал в своём варианте. Из вектора сдвигов(дельт) я вытаскивал угол направления(в тригонометрии все функции используют значения не в градусах, а в радианах, поэтому я переводил их путем /180*ПИ и наоборот /ПИ*180) Поворачивал направление на 180 градусов(в обратную сторону) и получал нормаль из направления. Добавлено через 1 час 18 минут Без тригонометрии можно обойтись в этом случае, но с тригонометрией открываются большие возможности.
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 19.02.2015 в 15:33. |
|
|||||
|
Lorem ipsum
|
Но ведь чтобы получить единичный вектор скорости, достаточно просто поделить каждую дельту на корень суммы их квадратов. Тригонометрия в данном случае является излишеством.
Спорное утверждение. Если возникнет желание подискутировать, лучше завести соотв. тему где-то во "флейме".
__________________
Поймай яблоко 2! |
|
|||||
|
Цитата:
![]() Но так как ТС хотел получать уравнение прямой по двум точкам( ), я бы на его месте без чужого комментария не понял бы суть приведённого вами кода, а код с поворотом на 180 градусов использовал для наглядности, и об этом написал в первом ответе(что код можно упростить)Добавлено через 1 час 20 минут А насчёт тригонометрии я тоже вставлю пару слов. Интересное объяснение от Tails, немного дополненное мной: Воткните палку в землю, перпендикулярно земле. Сейчас угол между землёй и палкой 90 градусов. Наклоните палку так, чтобы она образовывала с землёй угол 30 градусов. То, ВО сколько раз палка стала меньше занимать места в высоту - это синус угла 30 градусов (0.5) - половина первоначальной длины палки. То, ВО сколько раз она стала меньше в ширину занимать от той же высоты (см. картинку из моего поста, которую я в пост добавил) и есть косинус, т.е. приблизительно 0.8~0.9. И так будет для палки любой длины. отрезка или нашего прямоугольного треугольника из дельтаИкса и дельтаИгрика о_о В итоге добавляю, что получить нормаль по углу направления можно легко. косинус угла будет сдвигом по иксу, а синус - сдвигом по игрику. Мы легко можем заставить объект двигаться в зависимости от его свойства rotation. obj.x += Math.cos(obj.rotation/180*Math.PI)*speed; obj.y += Math.sin(obj.rotation/180*Math.PI)*speed; Чем меньше объясняешь что-то кому-то - тем крепче спишь =) Добавлено через 3 часа 39 минут Остальное по векторной алгебре читайте сами, мне лень писать. Например, тут http://habrahabr.ru/post/131931/
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 19.02.2015 в 18:29. |
![]() |
![]() |
Часовой пояс GMT +4, время: 19:16. |
|
|
« Предыдущая тема | Следующая тема » |
|
|