Convert Set of (x,y) Coordinates Into Polygon
    18 views (last 30 days)
  
       Show older comments
    
I converted the attached coordinates (x,y) into an alphashape. See image. 
shp = alphaShape(coordinates(:,1),coordinates(:,2),'HoleThreshold',50);
What I need are the coordinates at the polygon vertices (shown in red), and importantly, in the proper order shown with the numbers. I would like to be able to use the polyshape function next...
 I have toyed with boundaryfacet, delauney but with no luck.
Any suggestions?
Thanks.

0 Comments
Accepted Answer
  Matt J
      
      
 on 30 Jan 2025
        
      Edited: Matt J
      
      
 on 30 Jan 2025
  
      This uses tspsearch from the File Exchange,
load coordinates
shp = alphaShape(coords(:,1),coords(:,2),'HoleThreshold',50);
[bf,P]=boundaryFacets(shp);
p=tspsearch(P,5); P=P(p,:);
pgon1=polyshape(P); pgon2=polyshape(P,Simplify=true);
idx= ismember(pgon1.Vertices, pgon2.Vertices,'rows');
V=flipud(pgon1.Vertices(idx,:));
[~,s]=min(sum(V,2)); V=circshift(V,1-s);
V(4,1)=V(3,1); V(5,1)=V(6,1); V([3,6],:)=[]; %Fix bad corners
plot(pgon1,FaceColor='none') ;hold on
scatlabel( scatter(V(:,1),V(:,2)) );hold off
2 Comments
  Matt J
      
      
 on 30 Jan 2025
				Thanks @Paul Safier. You can Accept whichever solution you end up using, and you can upvote the other solutions.
More Answers (3)
  Star Strider
      
      
 on 30 Jan 2025
        
      Edited: Star Strider
      
      
 on 30 Jan 2025
  
      Try this — 
LD = load('coordinates.mat')
coordinates = LD.coords;
shp = alphaShape(coordinates(:,1),coordinates(:,2),'HoleThreshold',50);
shpx = shp.Points(:,1);
shpy = shp.Points(:,2);
[minx,maxx] = bounds(shpx);
[miny,maxy] = bounds(shpy);
minxv = shpx == minx;
% nnz(minxv)
maxxv = shpx == maxx;
% nnz(maxxv)
minyv = shpy == miny;
% nnz(minyv)
minyidx = find(minyv);
endsidx = find(diff(minyidx) > 151);
corner = minyidx(endsidx:endsidx+1);
midpt = round(mean(corner));
[minmidpty,maxmidpty] = bounds(shpy(midpt+(0:151)));
VertexPoints = table([1; 8; 6; 7; 2; 5; 3; 4], [minx; minx; maxx; maxx; shpx(corner(1)); shpx(corner(2)); shpx(corner(1)); shpx(corner(2))], [miny; maxy; miny; maxy;  shpy(corner(1)); shpy(corner(2)); minmidpty; minmidpty], VariableNames=["Corner","X","Y"] );
VertexPoints = sortrows(VertexPoints,1)
figure
plot(shp)
hold on
plot(minx, miny, 'rs', MarkerFaceColor='r')
plot(minx, maxy, 'rs', MarkerFaceColor='r')
plot(maxx, miny, 'rs', MarkerFaceColor='r')
plot(maxx, maxy, 'rs', MarkerFaceColor='r')
plot(shpx(corner), shpy(corner), 'rs', MarkerFaceColor='r')
plot(shpx(corner(1)), minmidpty, 'rs', MarkerFaceColor='r')
plot(shpx(corner(2)), minmidpty, 'rs', MarkerFaceColor='r')
hold off
axis([100  300    20  180])
text(VertexPoints{:,2}, VertexPoints{:,3}, compose('%2d',VertexPoints{:,1}), Color='r', FontWeight='bold', Vert='middle', Horiz='left', FontSize=12)
EDIT — Added text call.  
.
0 Comments
  Walter Roberson
      
      
 on 30 Jan 2025
        load coordinates
coordinates = coords;
k = boundary(coordinates);
plot(coordinates(k,1), coordinates(k,2))
4 Comments
  Paul
      
      
 on 30 Jan 2025
				load coordinates
coordinates = coords;
shp = alphaShape(coordinates(:,1),coordinates(:,2),'HoleThreshold',50);
[bf,P] = boundaryFacets(shp);
pgon = polyshape(P);  % KeepCollinearPoints = false by default
figure
plot(pgon)
hold on
plot(pgon.Vertices(:,1),pgon.Vertices(:,2),'o')  % only 10 points
Not clear to me what the expectations are for handling the "double vertices" on those inner corners, which I think are also there using the boundary() solution shown above.
boundary doesn't have an option to remove colinear points AFAICT, so I suppose one could use boundary() with whatever shrink factor and then covert that result to a polyshape to get rid of colinear points.
  Catalytic
      
 on 30 Jan 2025
        
      Edited: Catalytic
      
 on 30 Jan 2025
  
      load coordinates
shp = alphaShape(coords(:,1),coords(:,2),'HoleThreshold',50);
[~,P]=boundaryFacets(shp);
chull=convhull( polyshape(coords));
concavity =subtract(chull   , polyshape(P));
[xlim,ylim]=boundingbox(concavity);
innerV=table2array(combinations(xlim,ylim));
finalPolyshape=subtract( chull , polyshape(innerV([1,2,4,3],:))   );
V=flipud(finalPolyshape.Vertices);
plot(finalPolyshape); 
hold on; 
scatter(V(:,1),V(:,2),'ro','filled'); 
scatter(coords(1:2:end,1),coords(1:2:end,2),'.k','SizeData',1)
hold off
0 Comments
See Also
Categories
				Find more on Bounding Regions in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!










