|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Изолинии и 2D Массива
Доброго времени суток. Интересуюсь у знатоков : как из массива данных (Xi,Yi,F(Xi,Yi)) построить изолинии для всей области X,Y. Заранее спасибо.
|
#2
|
|||
|
|||
Цитата:
А что есть "изолиния", а то что-то искать лень... |
#3
|
|||
|
|||
Изолинии- это линии соединяющие равные значения функции
Напр. Изобара- линия соедин равные значения давления воздуха (у синоптиков) Алгоритм может быть примерно таким 1. Для заданной точки [x,y] ищем из 4-ех соседних точек ту где функция наиболее близка к начальной точке. 2. Проводим туда вектор LineTo(x,y) 3. Для новой точки ищем из трех соседних (кроме начальной) наиболее близкое значение 4. продолжаем пока не упремся в тупик или линия не замкнется. 5. Все это проделываем для каждой точки с заданным интервалом по F(x,y) Учитывая что F(x,y)- типа float проверяем неравенство abs(F(x0,y0) - F(x,y)) < Epsilon где Epsilon- это допускаемая погрешность вычисления F(x,y) Громоздко. Может у кого есть идеи получше? Задача нетривиальная. Последний раз редактировалось chainik, 22.01.2012 в 10:30. |
#4
|
|||
|
|||
Я тут немного подумал....
Мой алгоритм требует запоминания пути, те откуда мы пришли в данную точку. Наверное это не обязательно. Предлагаю следующее Пусть надо построить изолинию для значения функции Fn и пусть задана точность определения изолинии Epsilon и шаг по координатам X,Y равный Delta Тогда 1. Просматриваем все точки (X,Y) с шагом Delta и проверяем условие abs(F(X,Y) - Fn) < Epsilon Если нет- точку пропускаем 2. Если да - то проверяем на это же условие соседние 4 точки (X+-Delta, Y+-Delta) Если да то проводим туда векторы из данной точки. LineTo(X+-Delta, Y+-Delta) 3. И так по всем точкам. Изолинии нарисуются сами как совокупность векторов. Этот вариант куда как алгоритмически проше чем первый. Занятно Если задать слишком грубое Epsilon то изолинии станут толстыми. Если Epsilon мало- то в линиях могут появиться разрывы. Последний раз редактировалось chainik, 22.01.2012 в 11:52. |
#5
|
|||
|
|||
chainik. Задумка интересная, что-то подобное получилось реализовать, но как заметили получается разная толщина линий причем существенно. Даже целая замкнутая область получилась. Мне очень понравилась реализация в МАтКад, но при работе с большими массивами данных он просто тупит((( Поэтому: - исходников никто не видел на дэлфи?
|
#6
|
|||
|
|||
я бы создал массив размерностью - размер картинки на выходе
заполнил его цифрами порезал бы его на уровни, нарисовал их разными цветами какой-нибудь алгоритм поиска границ ещё гуглани на тему интерполяция, сплайны Последний раз редактировалось Pyro, 23.01.2012 в 10:49. |
#7
|
|||
|
|||
Код:
{---------------------------------------------------------------------- здесь исправленный алгоритм. От точки (x,y) ищется из 4-ех соседних наиболее близкая по значению функции и в эту точку проводится вектор ( а не во все как в моем предыд алгоритме). В качестве функции здесь как пример конус опрокинутый вершиной на коорд плоскость. Соответственно изолинии- это сечения конуса те окружности. Рмсует на TImage размером 200х200 пикс -------------------------------------------------------------------------} const Delta=1; Epsilon=0.8; var H:extended; function Isoln(x,y:extended):extended; begin Result:=Sqrt((x-100)*(x-100)+(y-100)*(y-100)); //конус end; {-------------------------------------------------------- находит оптимальный путь возвращает true- путь найден ---------------------------------------------------------} function FindTrace(x,y:extended;const H,Epsilon:extended; out OutX,OutY:extended):boolean; begin Result:=(abs(Isoln(x,y) - H) < Epsilon); if Result then begin OutX:=x-Delta;OutY:=y; if abs(Isoln(x+Delta,y) - H) < abs(Isoln(OutX,OutY) - H) then OutX:=X+Delta; if abs(Isoln(x,y-Delta) - H) < abs(Isoln(OutX,OutY) - H) then OutY:=Y-Delta; if abs(Isoln(x,y+Delta) - H) < abs(Isoln(OutX,OutY) - H) then OutY:=Y+Delta; end; end; {--------------work----------------------------} procedure TForm1.Button1Click(Sender: TObject); var OutX,OutY,x,y:extended; begin H:=StrToFloat(Edit1.Text); x:=0; with Image1.Canvas do while x < 200 do begin y:=0; while y < 200 do begin if FindTrace(x,y,H,Epsilon,OutX,OutY) then begin MoveTo(round(x),round(y));LineTo(round(OutX),round(OutY)); end; y:=y+Delta; end; x:=x+Delta; end; end; end. |
#8
|
|||
|
|||
Цитата:
|