Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 18.02.2015, 20:21
DenDobriy вне форума Посмотреть профиль Отправить личное сообщение для DenDobriy Найти все сообщения от DenDobriy
  № 1  
Ответить с цитированием
DenDobriy

Регистрация: Dec 2013
Сообщений: 35
По умолчанию Определение уравнения прямой по 2м координатам

Привет.
У меня очередной вопрос.
Хочу воссоздать алгоритм для движения некоторого обьекта в направлении противоположном координатам курсора. Движение может быть в любом мыслимом направлении в пределах плоскости, а не только вдоль координатных осей.
Единственное до чего я додумался, что это как-то связано с нахождением уравнения прямой по координатам обьекта и текущим координатам курсора.
1. Я прав, что это делается через уравнение прямой. Или есть какой-то простой способ?
2. Напишите, пожалуйста, это уравнение для прямой. Если не трудно написать готовый код, буду очень благодарен.

Старый 18.02.2015, 20:44
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 2  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,921
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Если вы про линейное уравнение, то нет, здесь оно ни к месту =)
Для начала вот так

Код AS3:
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));
На выходе получаем экземпляр Point со скоростями x и y, прибавляйте их при входе в кадр(ENTER_FRAME) к координатам объекта.
Чтобы увеличить скорость движения используйте speed.normalize(10); - где 10 - новая скорость для объекта.
Изначально скорость = 1, ибо на выходе после тригонометрических функций =)

На самом деле, код можно упростить, но я использовал такой вид для наглядности действий.

А это - элементарная тригонометрия и векторная алгебра.
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 18.02.2015 в 21:11.
Старый 18.02.2015, 22:20
callme вне форума Посмотреть профиль Отправить личное сообщение для callme Найти все сообщения от callme
  № 3  
Ответить с цитированием
callme
 
Аватар для callme

Регистрация: Dec 2014
Сообщений: 312
Код AS3:
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;
    }
}

Старый 19.02.2015, 00:17
DenDobriy вне форума Посмотреть профиль Отправить личное сообщение для DenDobriy Найти все сообщения от DenDobriy
  № 4  
Ответить с цитированием
DenDobriy

Регистрация: Dec 2013
Сообщений: 35
Ребята, вы просто отличные парни) Завидую, что для вас это всего лишь примитивная тригонометрия.
ZackMercury, я два дня страдал ради этих 2х строчек.
callme, спасибо что не поленился написать целый класс. Я оценил широту твоей доброты)

Старый 19.02.2015, 11:06
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 5  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,921
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
А в чём проблема изучить тригонометрию?) И векторную алгебру?
__________________
There is no thing in this world that is not simple.

Старый 19.02.2015, 14:23
Godwarlock вне форума Посмотреть профиль Отправить личное сообщение для Godwarlock Найти все сообщения от Godwarlock
  № 6  
Ответить с цитированием
Godwarlock

Регистрация: Jan 2012
Сообщений: 836
ZackMercury скинь ссылки по которым можно изучить.

Старый 19.02.2015, 14:33
Zebestov вне форума Посмотреть профиль Отправить личное сообщение для Zebestov Посетить домашнюю страницу Zebestov Найти все сообщения от Zebestov
  № 7  
Ответить с цитированием
Zebestov
Lorem ipsum
 
Аватар для Zebestov

модератор форума
Регистрация: May 2001
Адрес: Одесса
Сообщений: 4,869
Записей в блоге: 4
Лучше (читай элегантней) без тригонометрии.
Код AS3:
var speed:Point = new Point(obj.x - mouseX, obj.y - mouseY);
speed.normalize(1);
__________________
Поймай яблоко 2!

Старый 19.02.2015, 15:08
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 8  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,921
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
В блогах была пара замечательных записей, но к сожалению там что-то произошло с изображениями.

Ну, вот нашёл что-то интересное по тригонометрии.
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.
Старый 19.02.2015, 16:29
Zebestov вне форума Посмотреть профиль Отправить личное сообщение для Zebestov Посетить домашнюю страницу Zebestov Найти все сообщения от Zebestov
  № 9  
Ответить с цитированием
Zebestov
Lorem ipsum
 
Аватар для Zebestov

модератор форума
Регистрация: May 2001
Адрес: Одесса
Сообщений: 4,869
Записей в блоге: 4
Но ведь чтобы получить единичный вектор скорости, достаточно просто поделить каждую дельту на корень суммы их квадратов. Тригонометрия в данном случае является излишеством.

Цитата:
Сообщение от ZackMercury Посмотреть сообщение
Без тригонометрии можно обойтись в этом случае, но с тригонометрией открываются большие возможности.
Спорное утверждение. Если возникнет желание подискутировать, лучше завести соотв. тему где-то во "флейме".
__________________
Поймай яблоко 2!

Старый 19.02.2015, 16:36
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 10  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,921
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Цитата:
Но ведь чтобы получить единичный вектор скорости, достаточно просто
поделить каждую дельту на корень суммы их квадратов. Тригонометрия в
данном случае является излишеством.
Согласен
Но так как ТС хотел получать уравнение прямой по двум точкам(), я бы на его месте без чужого комментария не понял бы суть приведённого вами кода, а код с поворотом на 180 градусов использовал для наглядности, и об этом написал в первом ответе(что код можно упростить)

Добавлено через 1 час 20 минут
А насчёт тригонометрии я тоже вставлю пару слов.
Интересное объяснение от Tails, немного дополненное мной:

Воткните палку в землю, перпендикулярно земле. Сейчас угол между землёй и палкой 90 градусов.
Наклоните палку так, чтобы она образовывала с землёй угол 30 градусов.
То, ВО сколько раз палка стала меньше занимать места в высоту - это синус угла 30 градусов (0.5) - половина первоначальной длины палки.
То, ВО сколько раз она стала меньше в ширину занимать от той же высоты (см. картинку из моего поста, которую я в пост добавил) и есть косинус, т.е. приблизительно 0.8~0.9.

И так будет для палки любой длины. отрезка или нашего прямоугольного треугольника из дельтаИкса и дельтаИгрика о_о

В итоге добавляю, что получить нормаль по углу направления можно легко. косинус угла будет сдвигом по иксу, а синус - сдвигом по игрику.

Мы легко можем заставить объект двигаться в зависимости от его свойства rotation.

Код AS3:
obj.x += Math.cos(obj.rotation/180*Math.PI)*speed;
obj.y += Math.sin(obj.rotation/180*Math.PI)*speed;
Добавлено через 2 часа 21 минуту
Чем меньше объясняешь что-то кому-то - тем крепче спишь =)

Добавлено через 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, время: 17:02.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 17:02.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.