Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Геометрический вопрос (http://www.flasher.ru/forum/showthread.php?t=198002)

australian incognito 17.04.2013 13:43

Геометрический вопрос
 
Вложений: 1
Друзья, обращаюсь к вас с такой вот интересной задачей (см. прикрепленную картинку). Есть цель, есть пушка. Цель бегает за курсором мыши, пушка постоянно следит за целью в автоматическом режиме. Мне с легкостью удалось реализовать слежение пушки за целью по рис. 1. Но проблема в том, что у пушки оружие смещено относительно центра, и стреляет прямолинейно по отрезку CF (рис. 1). Соответственно пуля всегда проходит мимо цели. Пытаюсь вычислить угол w (рис. 2), на который нужно доворачивать пушку, но что-то все мои алгоритмы не подходят. В ходе "исследования" понял, что чем дальше цель от пушки, тем ближе угол w к углу a, а чем ближе цель к пушке, тем более похож угол w на угол a/2. Можно было бы на этом и остановится, но на средних дальностях идет достаточно серьезная погрешность.

Может найдется кто-то, кто подскажет, как все это посчитать правильно?

Заранее всем спасибо, буду благодарен любой наводке на правильный алгоритм.

samana 17.04.2013 14:17

По идее, вы можете переводить точку D, в глобальные координаты и уже их использовать при расчёте поворота пушки, вместо координат самой пушки.

mikhailk 17.04.2013 14:18

Вложений: 1
Я так понимаю, задача сводится к нахождению двух углов (около вершины С), которые я пометил одной и двумя линиями. Все треугольники прямоугольные, часть данных известна (кстати, а какие размеры/углы известны?). Вообще, насколько я помню, в решении таких задач правильнле решение прямо вытекает из правильного чертежа. Т.е., чертить до тех пор, пока решение не станет очевидным. :)

australian incognito 17.04.2013 14:33

Еще немного уточнений: ось вращения пушки - точка А. Точка вылета пули - С. Известные отрезки: АВ, АЕ, АD, т.е. по сути любые отрезки с рис. 1 известны.

AlexLucas 17.04.2013 14:40

Тут похожая тема, только там персонаж поворачивается за курсором, ну а у вас цель, разницы никакой.
Единственное что вам придётся учитывать это расстояние между A и C (которая в том примере не учитывается, и если подвести близко курсор, видно что дуло не направлено прямо на него).

australian incognito 17.04.2013 14:59

Цитата:

Сообщение от AlexLucas (Сообщение 1130193)
Тут похожая тема, только там персонаж поворачивается за курсором, ну а у вас цель, разницы никакой.
Единственное что вам придётся учитывать это расстояние между A и C (которая в том примере не учитывается, и если подвести близко курсор, видно что дуло не направлено прямо на него).

В приведенном примере как раз описан случай на рис. 1. А как я писал выше - мне нужно приблизиться к рис. 2.

chamele0n 17.04.2013 15:11

а если сделать гланым обьектом оружие, а саму пушку добавить в обьект оружия, тогда слежение будет осущетвлять не пушка, а оружие
тогда и вычислять ничего не нужно будет
хотя придется замарочиться с поворотом относительно другого центра
....
сделай танк ^_^

australian incognito 17.04.2013 15:22

Цитата:

Сообщение от chamele0n (Сообщение 1130200)
а если сделать гланым обьектом оружие, а саму пушку добавить в обьект оружия, тогда слежение будет осущетвлять не пушка, а оружие
тогда и вычислять ничего не нужно будет
хотя придется замарочиться с поворотом относительно другого центра
....
сделай танк ^_^

Это не вариант

mikhailk 17.04.2013 15:32

Вложений: 1
Может я чего-то упустил, но...
Гипотенузу и катет зеленого треугольника мы знаем, значит можем найти угол.

Собственно, чего это я, можно ограничиться непосредственно треугольником AED, нет?

samana 17.04.2013 15:39

Простите, а почему не подошел мой вариант (2 пост)? По идее ведь просчёты минимальны будут.

australian incognito 17.04.2013 15:45

Цитата:

Сообщение от samana (Сообщение 1130209)
Простите, а почему не подошел мой вариант (2 пост)? По идее ведь просчёты минимальны будут.

Я не понял, почему за основу взяты координаты точки Д?

samana 17.04.2013 15:50

Потому что это центр самого ствола пушки, именно которая должена указывать на цель. Если я правильно понял рисунок.

mikhailk 17.04.2013 16:24

Мне кажется, автор сам всех запутал, обозначив задачу как труднорешаемую.

Треугольник AED - прямоугольный, стороны AE и AD известны.
Что еще нужно?

australian incognito 17.04.2013 16:43

Цитата:

Сообщение от mikhailk (Сообщение 1130215)
Мне кажется, автор сам всех запутал, обозначив задачу как труднорешаемую.

Треугольник AED - прямоугольный, стороны AE и AD известны.
Что еще нужно?

Автор никого не путал. Не спешите с выводами.

В вашем случае нахождение угла w с рис. 2 сводится к нахождению угла а с рис. 1. А как я и говорил выше - угол a не работает, что и так ясно из рисунка.

Добавлено через 2 минуты
Точнее угол а работает хорошо, только на больших расстояниях между целью и пушкой. Как только цель приближается - угол начинает хорошо работать на a/2.

mikhailk 17.04.2013 16:54

Цитата:

В вашем случае нахождение угла w с рис. 2 сводится к нахождению угла а с рис. 1. А как я и говорил выше - угол a не работает, что и так ясно из рисунка.
Дудки. :)
На первом рисунке угол w ищется в другом треугольнике. Если точно - BCE, а я предлагаю брать треугольник EAD.

Вы зря убрали точку D со второго рисунка, из за этого пропал очевидный факт, что треугольник EAD прямоугольный и с двумя известными сторонами.

AlexLucas 17.04.2013 16:57

Вложений: 1
Так ?
NewProject.swf   (1.2 Кб)

Sync 17.04.2013 17:01

+1
все конструкция вращается вокруг точки A, тогда и в расчетах нужно брать плечо AD,а не AC.

silin 17.04.2013 17:18

Код AS3:

public class Main extends Sprite
{
        private var gun:Sprite;
        private var target:Sprite;
 
        private var ab:Number = 50;
        private var ad:Number = 80;
 
        public function Main():void
        {
                gun = new Sprite();
                target = new Sprite;
 
                target.graphics.beginFill(0x80FF80);
                target.graphics.drawCircle(0, 0, 10);
 
                gun.graphics.lineStyle(10, 0xFF8080);
                gun.graphics.lineTo(ad, 0);
                gun.graphics.lineTo(ad, -ab);
                gun.graphics.lineStyle(0, 0xC0C0C0);
                gun.graphics.lineTo(ad, -500);
                gun.x = 200;
                gun.y = 200;
 
                addChild(target);
                addChild(gun);
                addEventListener(Event.ENTER_FRAME, enterFrame);
        }
 
        private function enterFrame(e:Event):void
        {
                target.x = mouseX;
                target.y = mouseY;
 
                var tP:Point = new Point(target.x, target.y);
                var gP:Point = new Point(gun.x, gun.y);
                // расстояние
                var dist:Number = Point.distance(tP, gP);
                // направление
                var dir:Number = Math.atan2(tP.y - gP.y, tP.x - gP.x);
                // поправка
                var w:Number = Math.asin(ad / dist);
 
                gun.rotation = 180 / Math.PI * (dir - w) + 90;
 
        }
 
}


Bletraut 17.04.2013 22:45

Тут же все просто, переводим координаты точки С в глобальные и по ним считаем угол между Е и С.

silin 17.04.2013 23:10

>> По идее, вы можете переводить точку D, в глобальные координаты и уже их использовать при расчёте поворота пушки
>> Тут же все просто, переводим координаты точки С в глобальные и по ним считаем угол между Е и С.

ну да, по точке D или C в глобальных координатах посчитать нужный угол не сложно, только для этого мувик уже должен быть повернут на этот угол:)

samana 17.04.2013 23:44

Цитата:

Сообщение от silin (Сообщение 1130277)
ну да, по точке D или C в глобальных координатах посчитать нужный угол не сложно, только для этого мувик уже должен быть повернут на этот угол:)

Хм.. совсем не обязательно мувик должен быть уже повёрнут ) Всё ведь работает.
Код AS3:

public class Main extends Sprite
{
        private var cannon:Sprite;
        private var localD:Point=new Point(0,50)
 
        public function Main()
        {
                //draw cannon
                cannon = new Sprite();
                cannon.graphics.lineStyle(10);
                cannon.graphics.moveTo( 0, -50);
                cannon.graphics.lineTo(0, 50);
                cannon.graphics.lineTo(50,50);
                cannon.graphics.lineStyle(1, 0xC0C0C0);
                cannon.graphics.moveTo(localD.x, localD.y);
                cannon.graphics.lineTo(localD.x + 500, localD.y);
                cannon.x = 400;
                cannon.y = 300;
                addChild(cannon);
 
                stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove);
        }
 
        private function stage_mouseMove(e:MouseEvent):void
        {
                var gPoint:Point = cannon.localToGlobal(localD);
                var dx:Number = mouseX - gPoint.x;
                var dy:Number = mouseY - gPoint.y;
                var ang:Number = Math.atan2(dy, dx);
 
                cannon.rotation = ang  * (180 / Math.PI);
        }
 
}

silin я совершенно не против вашего метода, не подумайте. Ваш код умнее моего варианта, потому что геометрия для меня - китайская грамота.

silin 18.04.2013 09:00

>>совсем не обязательно мувик должен быть уже повёрнут ) Всё ведь работает.
работает, но не точно
для MOUSE_MOVE эта неточность мизерна
но если посадить тоже самое на CLICK, например, то сразу станет понятно о чем речь: 'правильный' угол достигается только за несколько кликов\итераций

samana 18.04.2013 12:56

Цитата:

Сообщение от silin
'правильный' угол достигается только за несколько кликов\итераций

Да, вы правы. Спасибо.

australian incognito 18.04.2013 15:13

Ребята, спасибо за помощь!


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

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