File Exchange

image thumbnail

VoronoiLimit(vararg​in)

version 2.8.0.0 (17.9 KB) by Jakob Sievers
Constrain the vertices of a Voronoi decomposition to the domain of the input data.

29 Downloads

Updated 31 Oct 2016

View License

The routine performs a Voronoi decomposition of an input dataset and constrains the vertices to the domain of the data themselves, such that even unbounded Voronoi cells become useful polygons (See attached figure). The function also supports internal/external user-defined boundaries.

Comments and Ratings (61)

YT

For those who like to use this function in the future in combination with patching of polygons, please note that in the documentation (https://mathworks.com/help/matlab/ref/voronoi.html) the example is stated with with the line `if all(c{i}~=1)`. If you want to make sure all polygons are patched arter this function, remove that line.

YT

After carefully checking results, this indeed changes the sides/corners correctly, but it created another problem. Patching the polygons lead to fine results in sides/corners and most of the midpoints, but for some reason there were a few polygons that weren't patched.

YT

Just want to say this is really useful! I was looking for a way to close the polygons at sides/corners and I came upon your question/answer on the mathworks forum. This gave me exactly what I was looking for.

How can I do it in N dimensions (not just 2d)?

A useful program, though I found a case where it failed to do Voronoi tessellation properly.

P=[-1,0;0,0;1,0;-0.4,0.8660254037844385;0.6,0.8660254037844385;0.2,1.732050807568877]
X = P(:,1);
Y = P(:,2);
bbox=[-1,0;1,0;0.1,1.732050807568877;-1,0];
[V,C,XY]=VoronoiLimit(X(:),Y(:),'bs_ext',bbox,'figure','on');

Error in VoronoiLimit (line 175)
mvx=vx(2,mix); %missing vx

Who can help?

void faceless

Mahmut Okatan

Thanks a lot for this useful program, though I found a case where it failed to do Voronoi tessellation properly.

XX=(1:4:27);

YY=(0.5:3:17);

[X,Y] = ndgrid(XX,YY);

bbox=[0 -1; 29 -1; 29 16.5; 0 16.5; 0 -1];

[V,C,XY]=VoronoiLimit(X(:),Y(:),'bs_ext',bbox);

Two corner cells turns out be missing.

Hi,
I am a new user of matlab, and have a problem with the function. I used the next lines:
x = [1177.3918,1199.0418, 1212.0418, 1189.2218, 1202.2218, 1179.4118, 1192.4118];
y = [-17.25, -17.25, -17.25, -34.25, -34.25, -51.25, -51.25];

[V,C,XY]=VoronoiLimit(x,y,'bs_ext',[0 0; 0 -40; 13 -40; 13 0], 'figura', 'on');

The result is only the figure, but the contents of V, C and XY are empty. There are in my workspace but without data.
Please help me.

Kaijun Ren

yo lecat

This is very usefull thank you for the work.
However, I am using your code to demodulate a noisy signal. For low modulations as QPSK, if there is a lot of noise, the constellation points are received beyond the boundaries of the polygon. I can't figure out how to put the boundaries far enough, it seems to be have a limit. Can someone help me on this?
Thank you

Yoann

yo lecat

Really useful, thanks a lot!!

Jakob Sievers

Hi all, sorry for the silence. Replies:

@Laura Veldenz:
The help text has been corrected. The right way to initiate the function is:
[V,C,XY]=VoronoiLimit(x,y,additional_variables)

@Ignacio Bordeu and @Michal Kvasnicka:
It seems that the old algorithm linked the wrong points for a very small number of the cases. I have added some extra basic requirements. Namely that (1) each proposed cell contains the original centroid (duh) and (2) that no side of a cell can intersect with any other part of the cell (again.. duh). These extra requirements seem to have corrected the problem for your specific data points. It also might have slowed the function a bit but I'll look at that if anyone are experiencing a serious slowdown. Please try it out and get back to me if it fails for some reason.

@KalMandy:
Simple. Try running e.g.:
x=rand(20,1);
y=rand(20,1);
VoronoiLimit(x,y,'bs_ext',[0 0;0 1;1 1;1 0],'figure','on');

Cheers

Jakob

KalMandy

Hi, Can anyone help me to understand how to get the vertices for unit square (for ex:defined by x=0,y=0,x=1 and y=1) using this function? How can I define the boundaries as x=0,y=0,x=1 and y=1?
Thanks!

I tried to contact Jacob Sievers directly with this problem, but he is not ready to make any bug fixing now.

@Michal Kvasnicka: I am trying to find a solution, the problem exists only for certain sets of (xc,yc) points and region sizes r.

@Ignacio Bordeu: I can confirm this problem on my data sets. Any help?

Hey guys, I have found an issue when considering certain sets of points. When trying the following example:

xc = [25.0362, 619.2890, 137.8061, 387.3650, 2.7294, 85.5450]

yc = [643.6328, 8.6653, 621.3243, 55.4894, 545.6431, 193.8842]

r = 500;
VoronoiLimit(xc,yc,'bs_ext',[0,r;r,r;r,0;0,0],'figure','on');

You can see that the limits are not drawn correctly, this issue disappears for smaller values of r.. any ideas on how to fix it?

Laura Veldenz

Hello,
there is a difference between the function and the comment about the function (first line in the comments), as seen below, the input is in different orders:

function [V,C,XY]=VoronoiLimi(varagin)

[XY,V,C]=VoronoiLimit(x,y,additional_variables)

so which one is correct? Or does it not make any difference>

Laura

good piece of code ...
well done!!!

Ban-Sok

Thank you for this great function!
Unfortunately, I sometimes get this error:

Subscript indices must either be real positive integers or logicals.

Error in VoronoiLimit (line 152)
mvx=vx(2,mix); %missing vx

I used the unit square as an external boundary. Any idea how I can avoid this error? Thanks in advance!

Works as advertised, simply put.

Matt J

Matt J (view profile)

Just a question. Are the polygons obtained by VoronoiLimit guaranteed to be the same as what you get if you take the unbounded Voronoi cells (as computed by VORONOIN, for example) and intersect them with a large rectangle?

Paul Martin

Excellent, thanks Jakob,

it worked just fine for me!

I used the convex hull of my data as a boundary, as follows:

% Get convex hull of data
K=convhull(X, Y);

% Turn the hull into X,Y boundary values

BX = X(K); BY = Y(K);

% Do the special Voronoi limited by the data
[V , C, XY] = VoronoiLimit(X, Y, 'bs_ext', [BX; BY], 'plot', 'on');

swheim

swheim (view profile)

This fails for me when I use large bounds, for example in the given examples using the following bounds:

world_bounds_x = [-8,10];
world_bounds_y = [-4,14];
bs_ext = [world_bounds_x([1 1 2 2 1]);world_bounds_y([1 2 2 1 1])]';

Also, when shrinking this bound, it sometimes makes slightly innaccurate bounds (i.e. one of the bounded-rectangle corners is slightly shifted).

Pearl

Pearl (view profile)

Jakob Sievers

Hi Preeti

Please send me an email with a description of the problem along with the specific xy coordinates you use (.mat file) so that I may have a look at it and figure out what the problem is.

Cheers

Preeti Goel

I wanted to get the points as per the external boundary, I got bugs with some examples. It was fixed when I used VoronoiBounded from the Lloyds Algorithm(Px,Py, Crs, Num Iterations, Show Plot).

Preeti Goel

I believe there is a bug in this section of the code

if length(C{ij})<3
C{ij}(1)=lV0+ixa(1);
C{ij}=[C{ij},lV0+ixa(2)];

for one of my examples:
with 3 points
one voronoi vertex in ext boundary
3 end points computed
the voronoi cells are not computed correctly and all are the same. Please help. I wanted to add files, but I do not see an option to do that here, I can send them an email id if needed. Thanks

Jakob Sievers

Hi Zu
I have added a triangle example to the current version of the file. Please download and test to see how it works. You can use any form of external boundary as long as it contains all of the x,y input points.
Cheers
Jakob

Zu Mailand

could you give me an example? the external boundary is belonging to triangle.

Jakob Sievers

The input variable "bs_ext" which is responsible for the external boundary, takes any number of vertices, meaning that you could just as easily describe a circle or whatever else you need :)

Francesco

Hi Jakob,

The current limited domain is only a rectangular or a square. If the limited domain is a circle or a triangle, can we modify more for your Matlab code? Thanks

Jakob Sievers

Hi francesco
I'm not sure I understand your question. The function supports both internal an external bounds such as illustrated (e.g. run with no input to see how it works). Is the bound you are thinking of not covered by any of these options?

Francesco

Thanks Jakob. I figured out :)

We should use dt=DelaunayTri(x(:),y(:)).

A question, if I want a bound domain which is rectangular, triangle or any more complicated geometry. How could I do for your function?
Thanks

Jakob Sievers

Hi Francesco. The DelaunayTri function will be removed from Matlab in favor of the DelaunayTriangulation function (http://se.mathworks.com/help/matlab/ref/delaunaytri.html). I don't know when the latter was implemented but it might be after the 2012 edition of Matlab, which is why it does not show up in your version of Matlab. Unless you upgrade to current matlab I suggest you use DelaunayTri if that works for you.

Cheers

Jakob

Jakob Sievers

Hi Francesco

I forgot to add the link to the information in question:
http://se.mathworks.com/help/matlab/ref/delaunaytri.html

Francesco

It seems that it should be the function 'dt=DelaunayTri(x(:),y(:))', right?

Francesco

I have an error when compiling

Undefined function 'delaunayTriangulation' for input arguments of type 'double'.

Error in VoronoiLimit (line 96)
dt=delaunayTriangulation(x(:),y(:));

As checked, I cannot find the function delaunayTriangulation in my Matlab R2012b.

Please help.
Thanks

shyam

shyam (view profile)

Jakob Sievers

One of my comments was removed so I'll reiterate briefly: three points is at the lower limit of when delaunayTriangulation can actually provide voronoi cells. if length(x)>3, however, cells begin to form.

Jakob Sievers

Follow-up comment: You may be able to solve this by: (1) deriving the centroid of the three points, (2) extrapolating each point based on this centroid far beyond the external bounds you have specified to add three extra points, (3) using all 6 pointsto create the voronoi cells. The program should remove the outer three points automatically. This is just off the top of my head so get back to me if you try this and it works or doesn't.

Yuanzhe

Hi Jakob
That problem has been sovled. However, I find another bug. When you just choose three points as the generator, for example, (-1,0), (1,0) and (0,1) are generators, and choose the boundary as 'boundary_x=[-2;2;2;-2;-2];boundary_y=[-2;-2;2;2;-2];'. The program cannot give the right result. At this stage, I have not found the reason and I am trying to solve it. Do you know why?
Thanks.
Yuanzhe

Yuhang Wang

Jakob Sievers

New version uploaded. Please let me know if this solves the problem for you!

Jakob Sievers

AH. I just noticed I had made a "range" function back in the day and its output was a vector of size=[1 2] where the values where min/max of the input vector respectively. This explains everything. Matlab must have used my "range" function instead of the one native to the program. I will fix this immediately and upload a new version ASAP. Stay tuned for the update.

Yuanzhe

Hi Jakob
Another question. Could one vertex connect with three or more infinite vertices? If so, it seems that the program does not consider this situation. Is that right? Thank you.
Regards,
Yuanzhe

Yuanzhe

Hi Jakob
I have check the result of the code. It seems that "range function gives the difference between the minimum and maximum of a vector". So the code "rx=range(x);" just gets rx of 1 times 1 dimension. But if I change this code to "rx=[min(x),max(x)];", the program could run. Is that right?
Thanks.
Yuanzhe

Jakob Sievers

Dear Michele
This is all a bit puzzling to me. When run without input x and y are both vectors. Consequently rx=range(x) and ry=range(y) gives two-element min/max ranges (size=[1,2]) and bnd=[rx ry]; becomes a four-element vector (size=[1,4]) on which crs is based. I cant figure out what might be going wrong based on your (and Yuanzhe's) description. Could you elaborate a bit? Are you running with no input or with user-defined input, and if so; what kind?
Cheers
Jakob

Michele Guidi

I downloaded the last verion today since this function would really help me a lot and I found the same error of Yuanzhe.
It is in the creation of the crs matrix (lines 77-82), where using the function RANGE(X), with X being a vector, simply return the range between the max and min value and not a vector, so it attempt to access an index out of bound.
I tried to fix the problem myself but made some avalanche consecutive errors.

Jakob Sievers

Dear Yuanzhe
I do not get that error, but I have been doing a number of bugfixes these past few days so maybe if you try downloading the current version you won't experience that error? Please get back to me in case that didn't work for you.
Cheers
Jakob

Yuanzhe

Dear Jakob
When run the program without input, there is an error. As x and y are vectors, bnd only has two elements and bnd(4) does not exist. So how to solve it? Thanks.

Kobye

Kobye (view profile)

Excellent function. I agree with Michele that an edge constraint functionality would be great to handle internal polygonal edges in the domain, e.g. plate with a hole cutout. The default DT = DelaunayTri(points,EC) function has the EC input variable to handle this. From this Delaunay Triangulation, the Voronoi tesselation can be calculated. This could be a good starting point.

UIC

UIC (view profile)

Dear Jakob,
There is only a small bug in the code you may resolve that. for some Voronoi cells (specially those near edges) vertices are not correct. Would you mind to check that.

Good luck,

Ashkan,

Jakob Sievers

Hi Michele
That is an interesting case. I am very limited timewise at the moment but when I do return to this function I will definitely take it into consideration. Could be interesting to add options for empty spaces of arbitrary polygon shapes within the bounding box.

Michele

Great function!
I have a question though. Is it possible to add new internal bounds, for example a "hole" inside a square region?
Thanks

maxime

maxime (view profile)

Great function !
I upgraded it for using it with any bounding shape. Just replacing "crs" variable by any polygon.
Works fine !

S

S (view profile)

Pearl

Pearl (view profile)

I 2nd Richard. I'm trying to get extended boundary, but still have no luck. Let me know if you have chance to upgrade the code. However, I don't have the mapping toolbox either :"(

Jakob Sievers

I have indeed considered adding an option to describe extended boundaries yourself. I will see if I get the time to make those changes.
I am not aware of any file-exchange alternatives to what polybool does, so I'm afraid the mapping toolbox remains a requirement.

Thanks for this, as I have run into the same problem, with a slight variation. I want the Voronoi diagram limited by a larger boundary outside of the original set of vertices from which the Voronoi diagram is calculated. HOWEVER, unfortunatey I cannot use your function because I do not have the mapping toolbox.

Updates

2.8.0.0

Bugfixes

2.7.0.0

Bugfixes + addition of a routine which automatically checks for a more recent version of the function on the Mathworks fileexchange

2.6.0.0

Bugfixes

2.5.0.0

Bugfixes

2.4.0.0

Routine improved to allow for proper handling of cells which are split into two, or more, closed polygons. In these cases the original cell is split into an appropriate number of new cells.

2.3.0.0

Bugfixes

2.2.0.0

bugfixes

2.1.0.0

[7th July 2015]: Treatment of xy input points around boundaries improved (See example figure)

2.0.0.0

Bugfixes

1.9.0.0

Output vertex order set to counter-clockwise

1.8.0.0

Bug fixes

1.7.0.0

Bugfixes + addition of triangle external boundary example

1.6.0.0

[31th March 2015]: Bugfixes

1.5.0.0

Bug fixes

1.4.0.0

Bug fixes

1.3.0.0

New figure

1.2.0.0

Bugfixes

1.1.0.0

UPDATE 25th March 2015: The routine has been updated to allow for the description of both an external boundary and multiple internal boundaries. See help for info.

MATLAB Release Compatibility
Created with R2016b
Compatible with any release
Platform Compatibility
Windows macOS Linux

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.


Learn About Live Editor