Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/50: Рейтинг темы: голосов - 50, средняя оценка - 4.78
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10

Аппроксимация\Интерполяция массива координат

01.08.2014, 17:22. Показов 10543. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть массив координат X,Y. Вида int[][]. Строю по данным точкам ломаную линию, но получается очень огромное количество лишних точек (массив мне передают, моя задача как раз его уменьшить). Т.е. например на одном прямом отрезке еще 100-200 лишних точек. Строю по порядку от 0 ... до N, точки просто соединяю. Как мне упростить максимально этот массив, чтобы осталось несколько точек просто. Т.е. погрешность меня не сильно волнует, общее черты надо сохранить. Читал про аппроксимацию и интерполяцию, но не очень пойму как применить. Дайте ссыль или направление куда копать хоть. Спасибо заранее.
2
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.08.2014, 17:22
Ответы с готовыми решениями:

Интерполяция и аппроксимация
Вот готовый текст: x = ; % Значения х y = ; % Значения у N = 10; % колличество точек xx = linspace(min(x),max(x),100); % Вводим...

Аппроксимация и интерполяция
Помогите плиз с лабой Функция1 3sin(корень x)+0.35x-3.8 Задание 1 Провести полиномиальную аппроксимацию данных функции и ...

Интерполяция и аппроксимация функций
Здравствуйте! Помогите решить задачу в MathCAD. По заданным экспериментальным точкам построить: 1) канонический интерполяционный...

11
Заблокирован
01.08.2014, 18:13
Цитата Сообщение от Dimka_Zar Посмотреть сообщение
Как мне упростить максимально этот массив, чтобы осталось несколько точек просто. Т.е. погрешность меня не сильно волнует, общее черты надо сохранить. Читал про аппроксимацию и интерполяцию, но не очень пойму как применить. Дайте ссыль или направление куда копать хоть. Спасибо заранее.
Dimka_Zar, Правильно ли я вас понимаю?
Вы хотите отбросить максимальное количесвто значений, при которых аппроксимирующая функция будет иметь приемлемый вид? Если да, то интерполяция тут не нужна. Почему не взять определенную небольшую окрестость, и отбрасывать все, что в неё входит

Может лучше поясните на конкретном примере?
1
26 / 26 / 29
Регистрация: 11.02.2012
Сообщений: 101
01.08.2014, 18:25
Dimka_Zar, Вот простое решение, скользящее среднее. Надо отсортировать массив, а потом построить ломанную из новых точек. По оси X решите что будет 100 точек например(i=0 до 99). А значение по Yi будет равняться сумме по Y всех входящих точек расположенных между Yi и Yi-1 деленное на число точек между Yi и Yi-1
0
871 / 721 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
01.08.2014, 19:16
Snaf,
Скользящее среднее сглаживает резкие колебания.

Dimka_Zar,
Достаточно подобрать некую погрешность и если допусти в ней находится 10 точек, то просто напросто все кроме первой и последней на отрезке удалить
0
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 10:40  [ТС]
Всем спасибо за ответы, уезжал на выходные не смог ответить. Поясню все таки задачу более подробней. У меня есть массив географических координат даже не int, а double[Latitude][Longitude]. По данным точкам я строю маршрут на карте. Точек очень много в силу не зависящих от меня обстоятельств. Так вот если по всем строить, то выходят одни точки, ниже пример. Далее я могу выбрать точки, через каждые 10м например. Получается более красиво. Но их все таки очень много. Хотелось бы получить очень упрощенную траекторию как я нарисовал красным на последнем рисунке. Могу перевести в декартовы координаты это все, потому изначально вопрос про X и Y ставил.
Миниатюры
Аппроксимация\Интерполяция массива координат   Аппроксимация\Интерполяция массива координат   Аппроксимация\Интерполяция массива координат  

0
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 10:45  [ТС]
Копал в сторону измерения азимута, но разница настолько мала..что получается криво. XRoy, как именно погрешность такую реализовать? Или дайте статьи примеры почитать, я не ленивый, просто не пойму пока что в какую сторону двигаться.
0
Заблокирован
04.08.2014, 12:16
Dimka_Zar, Так намного понятнее. Вы не могли бы прикрепить исходный массив координат (X,Y)? На первый взгляд, можно взять обычную окружность, но хотелось бы проверить.
0
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 13:03  [ТС]
Ev_Hyper, на данный момент я не переводил еще в декартовы. Я только вот нашел пример с применением алгоритма Рамера—Дугласа—Пекера. Вот на JS написали решение именно для моей задачи. Самый нижний пример по ссылке.
А вот в таком виде (txt файл) я получаю выгрузку из другой части программы эти координаты. Прикрепил его.
Вложения
Тип файла: txt 4.txt (8.4 Кб, 37 просмотров)
0
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 13:04  [ТС]
Сейчас попробую переделать с JS на C# и отпишу тут о результате. Спасибо за помощь!
0
298 / 260 / 108
Регистрация: 26.10.2012
Сообщений: 810
04.08.2014, 14:15
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
List<Point> GetSmoothedPoints(IList<Point> inputPoints)
{
List<Point> points = new List<Point>{inputPoints[0]};
int start = 0;
int end = 2;
const double maxError = 1;
 
while(end < inputPoints.Count)
{
      while(end <inputPoints.Count && GetError(inputPoints, start, end) < maxError) end++;
      start = end - 1;
      if(end < inputPoints.Count) points.Add(inputPoints[start]);
      end++;
}
points.Add(inputPoints.Last());
return points;
}
 
// Функция определяющая погрешность приближения диапазона точек inputPoints отрезком отрезком 
// от start до end
double  GetError(IList<Point> inputPoints, int start,int end)
{
///
}
1
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 15:18  [ТС]
Лучший ответ Сообщение было отмечено Ev_Hyper как решение

Решение

jetyb, а в GetError() что будет?

Добавлено через 48 минут
Всем спасибо! Решил я задачу, взял отсюда нижний пример, написанный на JS. Переписал для своей задачи и C#.
Кому интересно - решение ниже.
Вот класс, в который я закидываю координаты одной точки:

C#
1
2
3
4
5
        public class Point 
        {
            public double lat {get; set;}
            public double lng {get; set;}
        }
Далее из файла что был выше в аттаче (txt) делаю список точек, используя класс выше:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        public static List<Point> GetListPoints()
        {
            List<Point> Points = new List<Point>();
            string[] s = System.IO.File.ReadAllLines("4.txt");
            for (int i = 0; i < s.Length; i++)
            {
                string[] split = s[i].Split(',');
                Point point = new Point();
                point.lat = Convert.ToDouble(split[0] + "," + split[1]);
                point.lng = Convert.ToDouble(split[2] + "," + split[3]);
                Points.Add(point);
            }
            return Points;
        }
И вот сам метод, который возвращает такой же список классов Point, но уже урезанный:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 private static List<Point> GDouglasPeucker(List<Point> source, int kink)
        {
            int n_source, n_stack, n_dest, start, end, i, sig;
            double dev_sqr, max_dev_sqr, band_sqr;
            double x12, y12, d12, x13, y13, d13, x23, y23, d23;
            var F = ((Math.PI / 180.0) * 0.5);
            int[] index;
            int[] sig_start; 
            int[] sig_end;
 
            if (source.Count < 3) return (source);
 
            n_source = source.Count;
            band_sqr = kink * 360.0 / (2.0 * Math.PI * 6378137.0);
            band_sqr *= band_sqr;
            n_dest = 0;
            sig_start = new int[source.Count];
            sig_end = new int[source.Count];
            index = new int[source.Count];
            sig_start[0] = 0;
            sig_end[0] = n_source - 1;
            n_stack = 1;
 
            while (n_stack > 0) {
 
                start = sig_start[n_stack - 1];
                end = sig_end[n_stack - 1];
                n_stack--;
 
                if ((end - start) > 1)
                {
                    x12 = (source[end].lng - source[start].lng);
                    y12 = (source[end].lat - source[start].lat);
                    if (Math.Abs(x12) > 180.0)
                    x12 = 360.0 - Math.Abs(x12);
                    x12 *= Math.Cos(F * (source[end].lat + source[start].lat));
                    d12 = (x12 * x12) + (y12 * y12);
 
                    for (i = start + 1, sig = start, max_dev_sqr = -1.0; i < end; i++)
                    {
                        x13 = (source[i].lng - source[start].lng);
                        y13 = (source[i].lat - source[start].lat);
                        if (Math.Abs(x13) > 180.0)
                        x13 = 360.0 - Math.Abs(x13);
                        x13 *= Math.Cos(F * (source[i].lat + source[start].lat));
                        d13 = (x13 * x13) + (y13 * y13);
                        x23 = (source[i].lng - source[end].lng);
                        y23 = (source[i].lat - source[end].lat);
                        if (Math.Abs(x23) > 180.0)
                        x23 = 360.0 - Math.Abs(x23);
                        x23 *= Math.Cos(F * (source[i].lat + source[end].lat));
                        d23 = (x23 * x23) + (y23 * y23);
 
                        if (d13 >= (d12 + d23))
                            dev_sqr = d23;
                        else if (d23 >= (d12 + d13))
                            dev_sqr = d13;
                        else
                            dev_sqr = (x13 * y12 - y13 * x12) * (x13 * y12 - y13 * x12) / d12;// solve triangle
 
                        if (dev_sqr > max_dev_sqr)
                        {
                            sig = i;
                            max_dev_sqr = dev_sqr;
                        }
                    }
 
                    if (max_dev_sqr < band_sqr)
                    {   
                        index[n_dest] = start;
                        n_dest++;
                    }
                    else
                    {
                        n_stack++;
                        sig_start[n_stack - 1] = sig;
                        sig_end[n_stack - 1] = end;
                        n_stack++;
                        sig_start[n_stack - 1] = start;
                        sig_end[n_stack - 1] = sig;
                    }
                }
                else
                {
                    index[n_dest] = start;
                    n_dest++;
                }
            }
            index[n_dest] = n_source - 1;
            n_dest++;
            List<Point> r = new List<Point>();
            for (i = 0; i < n_dest; i++)
                r.Add(source[index[i]]);
            return r;
        }
В нем source - входной список географических координат, а kink - погрешность в метрах. Для моей задачи отлично подошло 30.

Вызываю все это List<Point> End_Points = GDouglasPeucker(GetListPoints(), 30);
И вот он End_Points, мои урезанный точки.
1
4 / 4 / 1
Регистрация: 01.08.2014
Сообщений: 10
04.08.2014, 15:28  [ТС]
Вот результирующий файл) Такой же, как я утром думал получить
Миниатюры
Аппроксимация\Интерполяция массива координат  
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.08.2014, 15:28
Помогаю со студенческими работами здесь

Delphi - Аппроксимация. Интерполяция?
1) Есть массив значений в StringGrid1.: (гистограмма) x / F(x) 1 / 0 2 / 5 3 / 12 .... xk / F(xk) ...

Аппроксимация. Квадратичная интерполяция
Нужен пример реализации квадратичной интерполяции на интервале с 11 точками. Исходные хi вычисляются по формуле xi=-2+7*(i-1)/10, i=1,11 и...

Интерполяция и аппроксимация функции
Здравствуйте! Помогите, пожалуйста с решением задачи. Сделать надо в Маткаде

Интерполяция и аппроксимация данных
Выполнить аппроксимацию полученных экспериментальных данных методом наименьших квадратов с помощью функции linfit(X,Y,F). Построить графики...

Аппроксимация.Линейная интерполяция
Здравствуйте!Помогите,пожалуйста,найти ошибку в коде.Высчитывает неверные корни. #include&lt;iostream&gt; #include&lt;math.h&gt; ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru