简体   繁体   中英

Delaunay triangulation implementation in matlab

Hello it`s my first post here. I want to write matlab script for Delaunay triangulation. Here is my script:

clear all;clc
%% Delaunay
x=[ 160.1671 366.9226 430.7894 540.1208 660.2771 508.7287 252.1787];
y=[ 223.9615 259.5000 120.5769 245.5000 283.1923 472.7308 469.5000];

%
x=x';
y=y';

%orginal plot
dd=delaunay(x,y);
dt=TriRep(dd,x,y);
triplot(dt);
z=[x.^2+y.^2]
i=1:length(x);
ptk=[i' x y]
%% main loop
l=0;
for i=1:length(x)-2
for j=1+i:length(x)
    for k=1+i:length(x)
        if (j ~= k)
            l=l+1;
            xn = (y(j)-y(i))*(z(k)-z(i)) - (y(k)-y(i))*(z(j)-z(i));
            yn = (x(k)-x(i))*(z(j)-z(i)) - (x(j)-x(i))*(z(k)-z(i));
            zn = (x(j)-x(i))*(y(k)-y(i)) - (x(k)-x(i))*(y(j)-y(i));
                if (zn < 0)
                    border=zn;
                        for m=1:length(x)
                            border = (border) & ...
                                ((x(m)-x(i))*xn +...
                                (y(m)-y(i))*yn +...
                                (z(m)-z(i))*zn <= 0);
                            if (border) 
                            ii(m)=[i];
                            jj(m)=[j];
                            kk(m)=[k];
                            end
                        end
                end
        end
    end
end
end
wart=[ii' jj' kk']
dd
figure(2)
triplot(wart,x,y)

This is what I should get from this script. This matrix is generated as delaunay() matlab function:

dd =
 6     7     2
 7     1     2
 4     6     2
 1     3     2
 4     3     5
 6     4     5
 2     3     4

This is what I get from implementation :

wart =
 4     7     6
 4     7     5
 4     7     5
 4     7     5
 4     7     5
 4     6     5
 4     6     5

Could anyone of you tell me what is wrong with this ? Where is a mistake or simply guide me?

jils.

The issue is in your innermost loop, here:

if (zn < 0)
                border=zn;
                    for m=1:length(x)
                        border = (border) & ...
                            ((x(m)-x(i))*xn +...
                            (y(m)-y(i))*yn +...
                            (z(m)-z(i))*zn <= 0);
                        if (border) 
                        ii(m)=[i];
                        jj(m)=[j];
                        kk(m)=[k];
                        end
                    end
            end

You want to check if the triangle defined by points [i,j,k] is valid. Only if it is so for all m (no points inside the circumcircle) do you want to save those three points into your output. Currently, if the first point you check is outside the circumcircle, those three points get saved no matter what. In addition, since you loop over the same m for each possible triangle, even if you find the correct values you're likely overwriting them later on. This is also why you get repeats of the same values in your output.

In these cases it is always worth stepping through (mentally, manually on the command line, or using debug methods) your loops to see what happens. Your first output 4 7 6 doesn't appear in the inbuilt function results. So set your i,j,k to those values and see what happens in that inner loop.

Incidentally, you don't actually need a loop there. Check all values at once by doing something like:

 border = (x-x(i)).*xn + (y-y(i)).*yn + (z-z(i)).*zn;
 if all(border<0)
    % then store coordinates
 end

You can start with an empty output ([]) and append (using end+1 ), or calculate the max number of triangles and preallocate your output to that size, use a counter variable to keep track of how many you find and put them in the right place in the output array, and then trim the output to size right at the end. If you're planning to have larger input data sets, it would be better to preallocate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM