Finding concave hull around abstract shape
조회 수: 12 (최근 30일)
이전 댓글 표시
Hallo together,
I have quite some abstract shape and try to found a more rectangular concave hull around it. I attached the polyshape data.
Now I wanna achieve a boundary faced like this and generate a patch object out of it:
I tried already a lot. Using the boundary function or alphaShape, but I could never reach a similar results. Either I had hole in my polyshape object at the end, or there was to much area close to the circle attached to the new polyshape object. Of course the with red indicated areas to be added to the final polyshape object dont have to be exactly like in the picture but similar I wanna achieve.
Also similar shapes should be solvelable.
Does somebody have a idear how to solve this? I would be really glad.
Thanks a lot!
댓글 수: 0
답변 (3개)
Star Strider
2024년 10월 10일
I am not certain what you want. The information creates a 2D polyshape.
The boundary function is likely most appropriate here, although you will have to experiment with various values of the shrink factor to get the result you want.
Try this —
LD = load('matlab_answer_example.mat')
ps = LD.new_polyShape1
xv = ps.Vertices(:,1);
yv = ps.Vertices(:,2);
[ixb1,v1] = boundary(xv, yv, 0.1)
[ixb2,v1] = boundary(xv, yv, 0.8)
figure
plot(ps, 'DisplayName','Original Polyshape')
hold on
plot(xv(ixb1), yv(ixb1), '-c', 'DisplayName','Shrink = 0.1')
plot(xv(ixb2), yv(ixb2), '-m', 'DisplayName','Shrink = 0.8')
hold off
axis('equal')
legend('Location','best')
.
댓글 수: 0
Matt J
2024년 10월 10일
편집: Matt J
2024년 10월 11일
ps = load('matlab_answer_example.mat').new_polyShape1;
tic;
V=cell2mat(arrayfun(@(i) upsamp(polybuffer(ps,-i)),[0,1],'UniformOutput',0)');
shp=alphaShape(V,6,'HoleThreshold',2*area(ps));
toc
plot(shp,'EdgeColor','none');hold on
plot(ps, 'FaceColor','none','EdgeColor','red');hold off
axis equal
function V=upsamp(ps)
V=ps.Vertices;
V(any(~isfinite(V),2),:)=[];
V(end+1,:)=V(1,:);
N=height(V);
V=interp1(V,linspace(1,N,100*N));
V(end,:)=[];
end
댓글 수: 2
John D'Errico
2024년 10월 10일
편집: John D'Errico
2024년 10월 10일
I don't know the soure of this data. But, can you start with the two pieces as separate entities, form polyshapes from each, and then use the union tool? For example, here I'll separate the two into pieces artificially.
load matlab_answer_example.mat
I1 = 70:570;
I2 = [1:70,571:722];
xy = new_polyShape1.Vertices;
S1 = polyshape(xy(I1,:));
S2 = polyshape(xy(I2,:));
H1 = plot(S1);
H1.FaceColor = 'r';
hold on
H2 = plot(S2);
H2.FaceColor = 'b';
hold off
S3 = union(S1,S2);
plot(S3)
댓글 수: 3
Steven Lord
2024년 10월 11일
What specifically do you expect the two polyshapes to look like in this case after you've adjusted them?
clear all
load MatlabAnswer_polyShapes.mat
whos
plot(polyShapes_1_CutOut, FaceColor='r')
hold on
plot(polyShapes_2_CutOut, FaceColor='c')
Do you want one of the polyshapes to contain only the cyan circles and the other only the red?
figure
plot(polyShapes_1_CutOut, FaceColor='r')
hold on
plot(polyShapes_2_CutOut, FaceColor='c')
plot(polyShape_1, FaceColor = 'none', EdgeColor = 'r')
plot(polyShape_2, FaceColor = 'none', EdgeColor = 'c')
polyShape_3 = subtract(polyShape_2,polyShape_1);
plot(polyShape_3, FaceColor = 'none', EdgeColor = 'k')
The subtract function got part of the way there, though the edge goes through one of the cyan circles. Is this on the right track for what you're hoping to create?
And just to confirm that you mean what I think you mean, when you say "Additionaly I want, that both polyshapes have a distance of x (x=1) towards each other." do you mean that you want the shortest distance between a point on the polyshape surrounding the cyan circles and a point on the polyshape surrounding the red circles to be 1 unit (exactly 1 unit or at least 1 unit?) So if we applied polybuffer with a distance of 1 to one of the polyshapes, it would not overlap (or not even touch) the other?
참고 항목
카테고리
Help Center 및 File Exchange에서 Elementary Polygons에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!