Способы нанесения изолиний
От: Andir Россия
Дата: 14.05.02 06:51
Оценка:
Народ подскажите инфу по subj.

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

C Уважением, Andir !
Re: Способы нанесения изолиний
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 14.05.02 07:46
Оценка: 6 (2)
Здравствуйте Andir, Вы писали:

A>Народ подскажите инфу по subj.


A>Постановка задачи:

A>Дано множество точек заданных своими координатами, в каждой точке задано значение некоторого параметра, нужно провести линии равных значений, через определённый шаг.

A>C Уважением, Andir !


Если необходимо выполнить какие-то математические расчеты, я зачастую обращаюсь к пакету MATLAB, к счастью там присутствуют многие алгоритмы, причем в исходниках, правда на своем внутреннем языке M-файлов. Там же и присутствует и такая функция contour, которая выполняет, похоже, именно то, что вам надо. Ниже я привожу ее исходный текст, а также и исходный текст функции contour3, которая используется в тексте contour. Я понимаю, что без должной подготовки ВАм будет трудно понять, как это работает, но если выполнять матемматику вам приходиться часто, то настоятелльно рекомендую выучить этот язык.

function [cout, hand] = contour(varargin)
%CONTOUR Contour plot.
%   CONTOUR(Z) is a contour plot of matrix Z treating the values in Z
%   as heights above a plane.  A contour plot are the level curves
%   of Z for some values V.  The values V are chosen automatically.
%   CONTOUR(X,Y,Z) X and Y specify the (x,y) coordinates of the
%   surface as for SURF.
%   CONTOUR(Z,N) and CONTOUR(X,Y,Z,N) draw N contour lines, 
%   overriding the automatic value.
%   CONTOUR(Z,V) and CONTOUR(X,Y,Z,V) draw LENGTH(V) contour lines 
%   at the values specified in vector V.  Use CONTOUR(Z,[v v]) or
%   CONTOUR(X,Y,Z,[v v]) to compute a single contour at the level v. 
%   [C,H] = CONTOUR(...) returns contour matrix C as described in
%   CONTOURC and a column vector H of handles to LINE or PATCH
%   objects, one handle per line.  Both of these can be used as
%   input to CLABEL. The UserData property of each object contains the
%   height value for each contour. 
%
%   The contours are normally colored based on the current colormap
%   and are drawn as PATCH objects. You can override this behavior
%   with the syntax CONTOUR(...,'LINESPEC') to draw the contours as
%   LINE objects with the color and linetype specified.
%
%   Uses code by R. Pawlowicz to handle parametric surfaces and
%   inline contour labels.
%
%   Example:
%      [c,h] = contour(peaks); clabel(c,h), colorbar
%
%   See also CONTOUR3, CONTOURF, CLABEL, COLORBAR.

%   Additional details:
%
%   CONTOUR uses CONTOUR3 to do most of the contouring.  Unless
%   a linestyle is specified, CONTOUR will draw PATCH objects
%   with edge color taken from the current colormap.  When a linestyle
%   is specified, LINE objects are drawn. To produce the same results
%   as MATLAB 4.2c, use CONTOUR(...,'-').
%
%   Thanks to R. Pawlowicz (IOS) rich@ios.bc.ca for 'contours.m' and 
%   'clabel.m/inline_labels' so that contour now works with parametric
%   surfaces and inline contour labels.

%   Copyright 1984-2000 The MathWorks, Inc. 
%   $Revision: 5.16 $  $Date: 2000/06/02 04:30:44 $

error(nargchk(1,5,nargin));

nin = nargin;
if isstr(varargin{end})
    nin = nin - 1;
end

if nin <= 2,
    [mc,nc] = size(varargin{1});
    lims = [1 nc 1 mc];
else
    lims = [min(varargin{1}(:)),max(varargin{1}(:)), ...
            min(varargin{2}(:)),max(varargin{2}(:))];
end

[c,h,msg] = contour3(varargin{:});
if ~isempty(msg), error(msg); end

for i = 1:length(h)
  set(h(i),'Zdata',[]);
end

if ~ishold
  view(2);
  set(gca,'box','on');
  grid off
end

if nargout > 0
    cout = c;
    hand = h;
end



[code]
function [cout,h,msg] = contour3(varargin)
%CONTOUR3 3-D contour plot.
% CONTOUR3(...) is the same as CONTOUR(...) except that the contours
% are drawn at their corresponding Z level.
%
% C = CONTOUR3(...) returns contour matrix C as described in CONTOURC
% and used by CLABEL.
%
% [C,H] = CONTOUR3(...) returns a column vector H of handles to PATCH
% objects. The UserData property of each object contains the height
% value for each contour.
%
% Example:
% contour3(peaks)
%
% See also CONTOUR, CONTOURF, CLABEL, COLORBAR.

% Additional details:
%
% Unless a linestyle is specified, CONTOUR3 will draw PATCH objects
% with edge color taken from the current colormap. When a linestyle
% is specified, LINE objects are drawn. To produce the same results
% as v4, use CONTOUR3(...,'-').
%
% The order of the handles h relative to the values in cout is used
% in CLABEL to create rotated inline labels. If you change this
% order, you may have to change CLABEL also.

% Clay M. Thompson 3-20-91, 8-18-95
% Modified 1-17-92, LS
% Copyright 1984-2000 The MathWorks, Inc.
% $Revision: 5.16 $ $Date: 2000/06/02 04:30:45 $

error(nargchk(1,5,nargin));
msg = [];

% Check for empty arguments.
for i = 1:nargin
if isempty(varargin{i})
error ('Invalid Argument — Input matrix is empty');
end
end

% Trim off the last arg if it's a string (line_spec).
nin = nargin;
if isstr(varargin{end})
[lin,col,mark,msg] = colstyle(varargin{end});
if ~isempty(msg), error(msg); end
nin = nin — 1;
else
lin = '';
col = '';
end

if nin <= 2,
[mc,nc] = size(varargin{1});
lims = [1 nc 1 mc];
else
lims = [min(varargin{1}(,max(varargin{1}(, ...
min(varargin{2}(,max(varargin{2}(];
end

if isempty(col) % no color spec was given
colortab = get(newplot,'colororder');
[mc,nc] = size(colortab);
end

% Check for level or number of levels N. If it's a scalar and a
% non-zero integer, we assume that it must be N. Otherwise we
% duplicate it so it's treated as a contour level.
if nin == 2 | nin == 4,
if prod(size(varargin{2})) == 1 % might be N or a contour level
if ~(varargin{2} == fix(varargin{2}) & varargin{2})
varargin{2} = [varargin{2},varargin{2}];
end
end
end

% Use contours to get the contour levels.
[c,msg] = contours(varargin{1:nin});
if ~isempty(msg)
if nargout==3,
cout = []; h = [];
return
else
error(msg);
end
end

if isempty(c), h = []; if nargout>0, cout = c; end, return, end

% Create the plot
newplot;
if ~ishold
view(3); grid on
set(gca,'xlim',lims(1:2),'ylim',lims(3:4))
end

limit = size(c,2);
i = 1;
h = [];
color_h = [];
while(i < limit)
z_level = c(1,i);
npoints = c(2,i);
nexti = i+npoints+1;

xdata = c(1,i+1:i+npoints);
ydata = c(2,i+1:i+npoints);
zdata = z_level + 0*xdata; % Make zdata the same size as xdata

% Create the patches or lines
if isempty(col) & isempty(lin),
cu = patch('XData',[xdata NaN],'YData',[ydata NaN], ...
'ZData',[zdata NaN],'CData',[zdata NaN], ...
'facecolor','none','edgecolor','flat',...
'userdata',z_level);
else
cu = line('XData',xdata,'YData',ydata,'ZData',zdata,'userdata',z_level);
end
h = [h; cu(];
color_h = [color_h ; z_level];
i = nexti;
end

if isempty(col) & ~isempty(lin)
% set linecolors — all LEVEL lines should be same color
% first find number of unique contour levels
[zlev, ind] = sort(color_h);
h = h(ind); % handles are now sorted by level
ncon = length(find(diff(zlev))) + 1; % number of unique levels
if ncon > mc % more contour levels than colors, so cycle colors
% build list of colors with cycling
ncomp = round(ncon/mc); % number of complete cycles
remains = ncon — ncomp*mc;
one_cycle = (1:mc)';
index = one_cycle(:,ones(1,ncomp));
index = [index(; (1:remains)'];
colortab = colortab(index,;
end
j = 1;
zl = min(zlev);
for i = 1:length(h)
if zl < zlev(i)
j = j + 1;
zl = zlev(i);
end
set(h(i),'linestyle',lin,'color',colortab(j,;
end
else
if ~isempty(lin)
set(h,'linestyle',lin);
end
if ~isempty(col)
set(h,'color',col);
end
end

% If command was of the form 'c = contour(...)', return the results
% of the contours command.
if nargout > 0
cout = c;
end
[\code]
Re[2]: Способы нанесения изолиний
От: Andir Россия
Дата: 14.05.02 08:12
Оценка:
Здравствуйте Mystic, Вы писали:

M>Здравствуйте Andir, Вы писали:


A>>Народ подскажите инфу по subj.


A>>Постановка задачи:

A>>Дано множество точек заданных своими координатами, в каждой точке задано значение некоторого параметра, нужно провести линии равных значений, через определённый шаг.

A>>C Уважением, Andir !


[code skip]

спасибо конечно ...
разобраться попробую, но это всё таки конфа по алгоритмам, а не по реализациям ...

Thk, Andir !
Re: Способы нанесения изолиний
От: OlegO Россия http://www.mediachase.ru
Дата: 14.05.02 09:06
Оценка: 1 (1)
Здравствуйте Andir, Вы писали:

A>Народ подскажите инфу по subj.


A>Постановка задачи:

A>Дано множество точек заданных своими координатами, в каждой точке задано значение некоторого параметра, нужно провести линии равных значений, через определённый шаг.

A>C Уважением, Andir !


Суть такая:
1. Этап разбить множество точек на треугольники. Треангуляция. Надеюсь это просто.
2. У нас есть треугольники. Диапозон значений от [A,B] с шагом H
3. В цикле от A до B с шагом H
4. Цикл по треугольникам.
5. Может быть два:
— Линия не проходит через треугольник. Значение не попадает в диапозон [Min,Min] значений по вершинам треугольника. Пропускаем тругольник.
— Линия проходит через треугольник. Значение попадает в диапозон [Min,Min] значений по вершинам треугольника. Находим точки пересечения линии с треугольникам делая линейную апроксимацию.


float Uzl[MAXNUM+1][2]; - сами точки
int Elm[MAXNUM+1][3]; - массив треугольков по Id вершин
float Z[MAXNUM+1]; - массив значений  в точке

void CChildView::DrawIzo (CDC *pDC)
{
    int i,j,k;
    BOOL flag0,flag1,flag2;
    int v0,v1,v2;
    float z0,z1,z2,x0,x1,x2,y0,y1,y2,z;
    float h;
    float xl[2],yl[2];
    MinZ=1e10;
    MaxZ=-1e10;
    CPen *pPen,IzoPen;

    
    for(i=1;i<=Nuz;i++)
    {
        if(Z[i]>MaxZ) MaxZ=Z[i];
        if(Z[i]<MinZ) MinZ=Z[i];
    }

    h=(MaxZ-MinZ)/Nizo;

    for (k=0;k<Nizo;k++)
    {
        z=MinZ+h*k;

        pPen=pDC->SelectObject (&Color[k+1]);

        for(i=1;i<=Nel;i++)
        {
            flag0=flag1=flag2=FALSE;
            v0=Elm[i][0];z0=Z[v0];x0=Uzl[v0][0];y0=Uzl[v0][1];
            v1=Elm[i][1];z1=Z[v1];x1=Uzl[v1][0];y1=Uzl[v1][1];
            v2=Elm[i][2];z2=Z[v2];x2=Uzl[v2][0];y2=Uzl[v2][1];
                
            if((z0-z)*(z1-z)<0) flag2=TRUE;
            if((z0-z)*(z2-z)<0) flag1=TRUE;
            if((z1-z)*(z2-z)<0) flag0=TRUE;

            j=0;

            if(flag2) 
            {
                xl[j]=x0+(x1-x0)/(z1-z0)*(z-z0);
                yl[j]=y0+(y1-y0)/(z1-z0)*(z-z0);
                j++;
            }
            if(flag1) 
            {
                xl[j]=x0+(x2-x0)/(z2-z0)*(z-z0);
                yl[j]=y0+(y2-y0)/(z2-z0)*(z-z0);
                j++;
            }
            if(flag0&&(j!=2)) 
            {
                xl[j]=x1+(x2-x1)/(z2-z1)*(z-z1);
                yl[j]=y1+(y2-y1)/(z2-z1)*(z-z1);
                j++;
            }

            if(flag0||flag1||flag2)
            {
               pDC->MoveTo ((int)(20+lx*(xl[0]-MinX)),
                (int)(20+ly*(yl[0]-MinY)));
               pDC->LineTo ((int)(20+lx*(xl[1]-MinX)),
                (int)(20+ly*(yl[1]-MinY)));
            }
            
        
        } 
        IzoPen.DeleteObject ();
        pDC->SelectObject (pPen);
    }

    
}
С уважением, OlegO.
Re[2]: Способы нанесения изолиний
От: Andir Россия
Дата: 14.05.02 09:19
Оценка:
Здравствуйте OlegO, Вы писали:

OO>Суть такая:

OO>1. Этап разбить множество точек на треугольники. Треангуляция. Надеюсь это просто.
OO>2. У нас есть треугольники. Диапозон значений от [A,B] с шагом H
OO>3. В цикле от A до B с шагом H
OO>4. Цикл по треугольникам.
OO>5. Может быть два:
OO> — Линия не проходит через треугольник. Значение не попадает в диапозон [Min,Min] значений по вершинам треугольника. Пропускаем тругольник.
OO> — Линия проходит через треугольник. Значение попадает в диапозон [Min,Min] значений по вершинам треугольника. Находим точки пересечения линии с треугольникам делая линейную апроксимацию.

Во-о это уже ближе и даже наверно подходит(только по-моему триангуляцию нужно проводить особым образом, чтобы получать более точные решения и избегать особых точек алгоритма у неё даже вроде название какое-то есть).

Читайте пожалуйста внимательней subj, мне нужны способы. ВСЕ возможные способы проведения линий равного уровня, постановка задачи в первом топике.
Дело в том что существуют способы и без триангуляции, вот они меня в первую очередь и интересуют, хотя и этот как один из ... подойдёт.
Извините если не очень корректно сформулировал, что мне нужно.

P.S. Просьба не приводить кода, реализацию сделать могу и сам (да и не сильно она нужна).

C Уважением Andir!
Re[3]: Способы нанесения изолиний
От: migel  
Дата: 14.05.02 12:11
Оценка:
Здравствуйте Andir, Вы писали:

A>Читайте пожалуйста внимательней subj, мне нужны способы. ВСЕ возможные способы проведения линий равного уровня, постановка задачи в первом топике.

A>Дело в том что существуют способы и без триангуляции, вот они меня в первую очередь и интересуют, хотя и этот как один из ... подойдёт.
A>Извините если не очень корректно сформулировал, что мне нужно.

A>P.S. Просьба не приводить кода, реализацию сделать могу и сам (да и не сильно она нужна).


A>C Уважением Andir!

Можно попробывать еще метод сеток с интерполяцией или метод монте-карло — накидать случайных точек и проинтерполировать значения.
Re: Способы нанесения изолиний
От: Vladimir_Vasilyev  
Дата: 14.05.02 12:29
Оценка:
Здравствуйте Andir, Вы писали:

A>Народ подскажите инфу по subj.


A>Постановка задачи:

A>Дано множество точек заданных своими координатами, в каждой точке задано значение некоторого параметра, нужно провести линии равных значений, через определённый шаг.

A>C Уважением, Andir !



Ищите поисковиками статью :

Вычислительные мктоды и программирование. 2001. Т.2 стр.22-32
"Построение изолиний с автоматическим масштабированием" А.В. Переберин
Re: Способы нанесения изолиний
От: Gosha Украина  
Дата: 14.05.02 17:49
Оценка:
Здравствуйте Andir, Вы писали:

A>Постановка задачи:

A>Дано множество точек заданных своими координатами, в каждой точке задано значение некоторого параметра, нужно провести линии равных значений, через определённый шаг.
У меня была подобная задачка для изотерм в прямоугольном слое материала с неравномерным распределением температур. Я просто шел по двумерному массиву сначала сверху вниз, а потом слева направо и "прокалывал" точки там, где происходила смена знака в разнице между искомой величиной (по которой нужно строить изотерму) и текущей.
Не знаю подойдет ли тебе это решение, но как вариант...
Кстати, увидел твое сообщение и обрадовался, сам давно хотел спросить у народа, как это сделать лучше. Может еще вариантов подскажут.
Удачи.
Re[4]: Способы нанесения изолиний
От: Andir Россия
Дата: 14.05.02 22:29
Оценка:
Здравствуйте migel, Вы писали:

M>Можно попробывать еще метод сеток с интерполяцией или метод монте-карло — накидать случайных точек и

проинтерполировать значения.

Не очень понял, давай чуть поподробнее, я как-то себе не представляю каким образом сюда запихать монте-карло или сетку с интерполяцией?

С Уважением, Andir !
Re[3]: Способы нанесения изолиний
От: OlegO Россия http://www.mediachase.ru
Дата: 15.05.02 05:33
Оценка:
Здравствуйте Andir, Вы писали:

A>Читайте пожалуйста внимательней subj, мне нужны способы. ВСЕ возможные способы проведения линий равного уровня, постановка задачи в первом топике.


Ну тогда твоя задача в общем случае сводится решению двух:

1. Построение Интерполяционной функции в 3-х мерном пространстве на основе данных точек. Т.е. нахождение F(x,y,z)=0 | F(xi,yi,zi)==0 для всех точек.

2. Нахождение Кривой получаемой системой уравнений F(x,y,z)=0, z-z0=0.

Очевидно что способ решения задачи 2 будет напрямую зависить от того каким способом ты будешь строить функцию F, линейной ли интерполяйией или сплайн, ну и так далее, по этой теме достаточно много в инете материала.
С уважением, OlegO.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.