Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268

Нужно написать функцию преобразования координат

06.04.2024, 10:53. Показов 1306. Ответов 18
Метки c#, net (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.

На двумерной карте существует корабль, который может плыть вперед и поворачивать.

На палубе корабля есть объекты, координаты которых мне нужно знать в глобальных координатах карты. Я нашел функцию, преобразовывающую глобальные координаты карты в координаты относительно корабля и с помощью нее сохранил в переменные относительные координаты нужных мне объектов.

Но мне нужно преобразовывать относительные координаты объектов, в глобальные координаты карты. Пробовал сгенерировать эту функцию нейросетями, координаты получаются похожие, но не точные, с разбросом +-50 метров, а мне нужно хотя бы с точностью до 0.1 метра.

Код преобразования глобальных координат в относительные координаты корабля:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        public static MapPos ConvertGlobalMapPosToShipPos(MapPos globalPos,
                                                          MapPos shipPos,
                                                          double shipDir)
        {
            double angle = -shipDir + Math.PI;
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);
 
            double dX = shipPos.X - globalPos.X;
            double dY = shipPos.Y - globalPos.Y;
 
            double localX = dX * sin + dY * cos;
            double localY = dX * cos - dY * sin;
 
            MapPos result = new MapPos(localX, localY);
 
            return result;
        }
Тестовые данные:
C#
1
2
3
var mapPos = new MapPos(303.56375312805, -212.71181869507);
var shipPos = new MapPos(295.7799987793, -161.99829101563);
double shipDir = 1.7219657897949;
Относительные координаты после преобразования данных выше:
X: -0.05781430215
Y: -51.3073618398

Ниже код сгенерированный нейросетью. Я ожидал, что последовательно вызвав сначала функцию `ConvertGlobalMapPosToShipPos`, а затем передав ее вывод в функцию `ConvertShipPosToGlobalMapPos` я получу назад тестовые данные из `mapPos`, но преобразование локальных координат в глобальные слишком не точный.

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        public static MapPos ConvertShipPosToGlobalMapPos(MapPos localPos,
                                                          MapPos shipPos,
                                                          double shipDir)
        {
            double angle = -shipDir + Math.PI;
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);
 
            double dX = localPos.X;
            double dY = localPos.Y;
 
            double globalX = dX * cos - dY * sin + shipPos.X;
            double globalY = dX * sin + dY * cos + shipPos.Y;
 
            MapPos result = new MapPos(globalX, globalY);
 
            return result;
        }


Может кто-нибудь подсказать функцию обратного преобразования координат для `ConvertGlobalMapPosToShipPos`? Заранее спасибо.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.04.2024, 10:53
Ответы с готовыми решениями:

Разработать функцию преобразования координат точки
Разработать функцию преобразования координат точки (X0, Y0) при повороте системы координат на угол φ по следующему правилу: x1 =...

Написать формулы преобразования прямоугольных координат
Написать формулы преобразования прямоугольных координат, если если новой системы находимся в точке О`(-1,1), угол от положительного...

Написать функцию, выполняющую преобразования списка
Добрый вечер, помогите пожалуйста с заданием: Написать функцию, выполняющую следующие преобразования списка: удаляются все повторения...

18
Эксперт .NET
 Аватар для Usaga
14310 / 9391 / 1355
Регистрация: 21.01.2016
Сообщений: 35,420
06.04.2024, 12:06
Цитата Сообщение от ATop Посмотреть сообщение
Может кто-нибудь подсказать функцию обратного преобразования координат для `ConvertGlobalMapPosToShipPos`? Заранее спасибо.
Ну а нейросеть что?
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
06.04.2024, 12:18  [ТС]
И GPT и локальные нейросети выдают плюс-минус код метода `ConvertShipPosToGlobalMapPos`, написанный под спойлером. Чем дальше от центра корабля, тем больше погрешность конвертации внутренних координат в глобальные. От +-3 метров в центре корабля, до +-50 на его краях.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3429 / 2748 / 575
Регистрация: 04.09.2018
Сообщений: 8,626
Записей в блоге: 3
06.04.2024, 14:20
Цитата Сообщение от ATop Посмотреть сообщение
относительные координаты нужных мне объектов
Относительно чего? Центра корабля?
1
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.04.2024, 15:34
Цитата Сообщение от wizard41 Посмотреть сообщение
Относительно чего? Центра корабля?
Обычно относительные координаты считают от позиции родительского объекта, принятой за 0. Как он считал не известно...
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3429 / 2748 / 575
Регистрация: 04.09.2018
Сообщений: 8,626
Записей в блоге: 3
06.04.2024, 15:37
Цитата Сообщение от Someone007 Посмотреть сообщение
относительные координаты считают от позиции родительского объекта
Someone007, точно так. поэтому и уточняю у ТС, на всякий случай.

Тогда получается, что текущие "глобальные" координаты корабля являются в то же время "локальным" нулем для относительных координат объекта. Преобразования элементарные, не пойму зачем он для этого полез к GPT, который, еще и привел не очень корректные варианты.
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
06.04.2024, 15:55  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
Относительно чего? Центра корабля?
Я могу получать координаты корабля на карте, которые соответствуют определенной точке на нем. Эти координаты я считаю нулем для локальных координат корабля.

Цитата Сообщение от wizard41 Посмотреть сообщение
Тогда получается, что текущие "глобальные" координаты корабля являются в то же время "локальным" нулем для относительных координат объекта
Координаты корабля на карте могут быть к примеру [100.00, 100.00], эти глобальные координаты и будут нулем локальных координат корабля. Единственная сложность в том, X и Y корабля почти никогда не соответствуют X и Y глобальных координат карты, т.к. кор может поворачиваться. Поворот корабля задается в радианах и передается в методы выше аргументом `shipDir`, где Восток это +-0 радиан, запад +-3.14 рад, север +1.57 рад, а юг -1.57 рад.


Цитата Сообщение от wizard41 Посмотреть сообщение
Преобразования элементарные, не пойму зачем он для этого полез к GPT
Просто я не могу составить необходимые расчеты самостоятельно, вот и спросил нейронки, а когда не справилась она, я начал приставать к людям на форуме, извините.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.04.2024, 16:47
Цитата Сообщение от ATop Посмотреть сообщение
Единственная сложность в том, X и Y корабля почти никогда не соответствуют X и Y глобальных координат карты, т.к. кор может поворачиваться.
При повороте координаты не меняются, или я что-то не понимаю?... Что за поворот такой, при котором у вас почему-то координаты меняются?
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
06.04.2024, 17:38  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Что за поворот такой, при котором у вас почему-то координаты меняются?
Я о том, что движение на 5 метров по Y в координатах корабля, почти никогда не равняется движению 5 метрам в глобальных координатах, т.к. координаты кора почти всегда повернуты относительно осей координат карты. Если нужная мне точка находится в координатах корабля на [5, 0], я не могу просто прибавить 5 к координате Х корабля на карте и получить нужную мне точку.

0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3429 / 2748 / 575
Регистрация: 04.09.2018
Сообщений: 8,626
Записей в блоге: 3
06.04.2024, 17:51
Цитата Сообщение от ATop Посмотреть сообщение
я не могу просто прибавить 5 к координате Х корабля на карте и получить нужную мне точку
Ну это же очевидно. Тебе нужно соотнести вектор движения/пройденный путь по вектору с соотв. осью, где длина перемещения по этой оси будет равна катету треугольника (ну смотря как его повернуть).
Цитата Сообщение от ATop Посмотреть сообщение
приставать к людям на форуме, извините
Извинятся не надо - надо было сразу к людям приставать тут (это нормально), а не идти к gpt по такому мизерному вопросу.

Добавлено через 8 минут
Любой объект на палубе корабля, если считать его "железно прибитым" к нему - будет отстоять от центра массы корабля (локального нуля) на некоторые ΔX, ΔY, т.е. будет иметь свои собственные координаты относительно центра. На точно такие же ΔX, ΔY будут различаться его "глобальные" координаты.
При повороте корабля, нужно будет вычислять новые ΔX, ΔY для объекта, с учетом угла поворота.
1
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.04.2024, 18:57
Неужели что-то типа этого
C#
1
2
3
4
5
6
7
8
9
Vector2 shipPosGlobal = new Vector2(10, 20);
 
Vector2 objectPosLocal = new Vector2(-1, 1);
 
float rotation = -MathF.PI / 2;
 
Vector2 objectPosLocalRotated = Vector2.Transform(objectPosLocal, Matrix3x2.CreateRotation(rotation));
 
Vector2 objectPosGlobalRotated = shipPosGlobal + objectPosLocalRotated;
не работает?
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
06.04.2024, 22:00  [ТС]
Если поворот считать вот так `float rotation = (float)(-shipDir + Math.PI);` ответ будет такой же, как в методе `ConvertShipPosToGlobalMapPos`, написанным нейросетью.

Т.е. передав в метод `ConvertGlobalMapPosToShipPos` `MapPos(303.56375312805, -212.71181869507)`, а полученные из него локальные координаты передать в ваш метод, то вернется не изначальные, глобальные координаты, а `X = 346.4935302734375, Y = -169.78204345703125`. Разница по X и Y с изначальными данными -42.9 метра.

Остальные способы расчета поворота, после двух преобразований, совсем далеки от начальных координат.

PS.
Может быть метод `ConvertGlobalMapPosToShipPos` изначально не верно считает локальные координаты, по этому после двух преобразований выходит погрешность. Но на глаз вроде бы он возвращает адекватные данные.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
07.04.2024, 01:02
Локальные координаты должны быть посчитаны для изначального положения корабля без всяких поворотов, т.к. они от поворота в принципе не зависят.
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3429 / 2748 / 575
Регистрация: 04.09.2018
Сообщений: 8,626
Записей в блоге: 3
07.04.2024, 04:50
Лучший ответ Сообщение было отмечено ATop как решение

Решение

ATop,
по быстрому набросал пример поворота корабля вместе с некоторым объектом.
Объект - красный квадрат, закреплен на корабле и имеет относительные координаты -20;-45 (относительно центра корабля).

Корабль находится в точке 0;0 (глобальные координаты).
В примере происходит поворот локальной (корабельной) системы координат (зеленые линии) относительно глобальной (серые линии).
Вместе с кораблем поворачивается и объект на нем, одновременно происходит расчет глобальных координат объекта.
За нулевой угол курса принято направление на север.


Глобальные координаты объекта высчитываю следующим образом:
class VesselObject

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    class VesselObject(Point localPos) : BaseModel
    {
        public Point LocalPosition { get; set; } = localPos;
 
        double globalX, globalY;
        public double GlobalX { get => globalX; private set => Set(ref globalX, value); }
        public double GlobalY { get => globalY; private set => Set(ref globalY, value); }
 
        public void GlobalPosCalc(double angle)
        {
            angle *= 3.141592 / 180;
            GlobalX = LocalPosition.X * Math.Cos(angle) + LocalPosition.Y * Math.Sin(angle);
            GlobalY = -LocalPosition.X * Math.Sin(angle) + LocalPosition.Y * Math.Cos(angle);
        }
    }

пока без учета смещения судна по глобальным координатам (т.е. корабль стоит на месте в точке 0;0).

Предлагаю самостоятельно попробовать доработать формулы расчета, чтобы учитывались смещения корабля.
Вложения
Тип файла: 7z VesselNav.7z (55.7 Кб, 12 просмотров)
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
07.04.2024, 06:04  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
по быстрому набросал пример поворота корабля вместе с некоторым объектом.
Большое спасибо, ваша программа помогла мне понять как правильно рассчитать поворот.

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

Сейчас я конвертирую глобальные координаты в локальные и обратно без каких либо погрешностей, какие координаты дал на вход, те и получил на выходе. Огромное спасибо всем кто отвечал, вряд ли бы я когда-нибудь смог решить эту задачу самостоятельно.

Работающий код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        public static MapPos ConvertGlobalMapPosToShipPos(MapPos globalPos, MapPos shipPos, double shipDir)
        {
            double angle = -shipDir + Math.PI;
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);
 
            double dX = shipPos.X - globalPos.X;
            double dY = shipPos.Y - globalPos.Y;
 
            double localX = dX * sin + dY * cos;
            double localY = dX * cos - dY * sin;
 
            return new MapPos(localX, localY);
        }
 
        public static MapPos ConvertShipPosToGlobalMapPos(MapPos localPos, MapPos shipPos, double shipDir)
        {
            double angle = shipDir - Math.PI / 2;
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);
 
            var globalX = (-localPos.X * cos - localPos.Y * sin) + shipPos.X;
            var globalY = (-localPos.X * sin + localPos.Y * cos) + shipPos.Y;
 
            return new MapPos(globalX, globalY);
        }
1
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
07.04.2024, 13:54
Так и не понял зачем вам все эти лишние преобразования локальных в глобальные и обратно...

У вас изначально для объектов на корабле должны быть известны их локальные координаты. Имея их вы в 1-2 строчки можете преобразовать их в глобальные используя вектора как показано в посте выше. Всё.

Сами координаты у вас должны быть объявлены как Vector2, а не как ваш костыльный MapPos. Зачем вы изобретаете велосипед?
1
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
07.04.2024, 14:47
Как-то так...
Вложения
Тип файла: zip WinFormsPlotApp.zip (6.3 Кб, 6 просмотров)
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3429 / 2748 / 575
Регистрация: 04.09.2018
Сообщений: 8,626
Записей в блоге: 3
07.04.2024, 18:02
Цитата Сообщение от Someone007 Посмотреть сообщение
а не как ваш костыльный MapPos
Кстати да, я вообще не понял что это такое, этот MapPos... Позиция карты? Нафига это нужно.
1
108 / 14 / 7
Регистрация: 06.07.2013
Сообщений: 268
08.04.2024, 09:27  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
У вас изначально для объектов на корабле должны быть известны их локальные координаты
Я не знаю координат объектов на корабле. Я могу узнать только координаты корабля и координаты персонажа. Я в ручную подхожу персонажем к нужному объекту, получаю его глобальные координаты и преобразую их в локальные координаты корабля при помощи метода ConvertGlobalMapPosToShipPos, сохраняю их в переменную и дальше работаю только с функцией ConvertShipPosToGlobalMapPos.

Цитата Сообщение от Someone007 Посмотреть сообщение
Сами координаты у вас должны быть объявлены как Vector2
Цитата Сообщение от wizard41 Посмотреть сообщение
Кстати да, я вообще не понял что это такое, этот MapPos... Позиция карты? Нафига это нужно.
Я никогда не пользовался объектом Vector2, по этому создал свой класс, который хранит координаты на карте. Такое название выбрал т.к. игра отдает позиции объектов на карте функциями с названиями похожими на MapPos.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.04.2024, 09:27
Помогаю со студенческими работами здесь

Нужно написать и отладить программу выполнения преобразования...
Всем привет!!!! =) помогите пожалуйста решить задачи! буду очень благодарен вам!!!вообще не понимаю С++((( надеюсь,что вы мне поможите....

Написать функцию itoa (n,s) преобразования целого числа n в стринг s
Написать функцию itoa (n,s) преобразования целого числа n в стринг s

Нужно написать код с осями координат x и y
Программа рисования графиков функций 2 переменных в виде поверхности, образованной линиями, параллельными осям x и y. Так звучит задание

Нужно написать программу (хранение 2D координат)
Задача такая: реализовать класс для 2х-мерных точек в декардовой системе координат. Класс должен хранить координаты как double (с плав....

Написать процедуру и функцию преобразования положительного десятичного числа в 8-разрядное двоичное
Написать процедуру и функцию преобразования положительного десятичного числа в 8- разрядное двоичное . В основной программе ввести массив...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru