I would like to plot a polygon with multiple holes in it, like this:
P = [
0.5, 0.8;
1.0, 0.0; % outer boundary
0.0, 0.0;
0.5, 0.8;
%{
%}
0.5, 0.3;
0.3, 0.1; % inner boundary I
0.7, 0.1; % (hole)
0.5, 0.3;
%{
%}
0.5, 0.6;
0.3, 0.4; % inner boundary II
0.7, 0.4; % (hole)
0.5, 0.6;
];
figure, clf, hold on
patch(P(:,1),P(:,2), 'r', 'linestyle', 'none')
However, patch
doesn't quite work the way I expected it to. When I change the last hole to this:
% ...
0.45, 0.6; % <- slightly offset in X-direction
0.3, 0.4;
0.7, 0.4;
0.45, 0.6; % <- slightly offset in X-direction
% ...
this happens:
This technique works nicely with a single hole, but can I also apply the same technique for multiple holes? Or do I have to resort to splitting it up, as shown here?
NOTE: Eventually, I'll be plotting hundreds of (possibly partially transparent) polygons in 3D space, and I want to be able to "look through" the holes. Therefore, solutions with a "white overlay" polygon are not what I'm looking for.
The best way to handle this may be to break your polygons up into a Delaunay triangulation with constrained edges, extract only the triangles that are on the interior of the constrained edges, then create a set of face/vertex data from that to use with patch
. Given the second matrix P
from your example, here's how to do it:
C = [1:3 5:7 9:11; 2:4 6:8 10:12].';
DT = delaunayTriangulation(P, C);
vertices = DT.Points;
faces = DT.ConnectivityList(isInterior(DT), :);
patch('Faces', faces, 'Vertices', vertices, 'FaceColor', 'r', 'EdgeColor', 'none');
And the resulting figure:
You'll get a warning when creating the triangulation that "duplicate data points have been detected and removed", which is nothing to worry about. You could potentially even put all of your polygon and constraint data together into one set of matrices and do the triangulation once to create one big set of face/vertex data for multiple polygons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With