Multiple faces merging into a single face when using alphaShape()

16 views (last 30 days)
I'm trying to create a 3D model of a n-gon cylinder using alphaShape(). The model, when plotted, shows all the faces correctly up to n=8, where n is the number of sides of the polygon. For n>8 all the side faces of the cylinder merge into a single surface as shown in the figures. I need to have all the faces seperately, in order to apply pressure later in the modeling. I've included the code that I'm using. Any help is appriciated.
Edit:
My final goal is to use this model later in the code, apply force on some faces (see the following line of code), and solve for the stress distribution within the object.
structuralBoundaryLoad(model, 'Face', 1, 'Pressure', 1e6)
For that I have to specify the relevent face identified by MATLAB. The issue right now is that although there are nodes and vertices specified, the model doesn't show seperate faces. They all merge into a single face f1.
n=9;% The number of sides of the polygon
m=0:n-1;
rootvec=10*exp(1i*2*pi*m/n);%find vertices using nth root of unity
x1=real(rootvec);
y1=imag(rootvec);
z1=10*ones(1,n);
z2=zeros(1,n);
x1 = x1(:);
y1 = y1(:);
z1 = z1(:);
z2 = z2(:);
P = [x1 y1 z1; x1 y1 z2];
shp = alphaShape(P(:,1),P(:,2),P(:,3),50);
plot(shp)
axis equal
[elements,nodes] = boundaryFacets(shp);
nodes = nodes';
elements = elements';
model = createpde();
geometryFromMesh(model,nodes,elements);
pdegplot(model,'FaceLabels','on','FaceAlpha',0.5)
  2 Comments
Matt J
Matt J on 14 Apr 2021
I need to have all the faces seperately, in order to apply pressure later in the modeling.
What do you mean by "have them". Do you want a cell array containing the vertex coordinates of each face? What is the final organization of the data that you seek?
Ash128
Ash128 on 14 Apr 2021
I added more context to the question above. My final goal is to apply force on the side of faces of the model using structuralBoundaryLoad() and solve for the stress distribution. For that I want each face to be specified like
structuralBoundaryLoad(model, 'Face', 5, 'Pressure', 1e6)
structuralBoundaryLoad(model, 'Face', 7, 'Pressure', 1e6)
structuralBoundaryLoad(model, 'Face', 10, 'Pressure', 1e6)
Right now they seem to merge together.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 14 Apr 2021
If you have R2020b, I think you can just do this:
n=9;% The number of sides of the polygon
m=0:n-1;
rootvec=10*exp(1i*2*pi*m/n);%find vertices using nth root of unity
x1=real(rootvec);
y1=imag(rootvec);
model=createpde();
g=extrude( decsg([2,n, x1,y1].') ,10);
geometryFromEdges(model,g);
pdegplot(g,'FaceLabels','on','FaceAlpha',0.5)
  2 Comments
Ash128
Ash128 on 14 Apr 2021
I get an error at
g=extrude( decsg([2,n, x1,y1].') ,10);
>> Check for missing argument or incorrect argument data type in call to function 'extrude'.
Shouldn't the input arguement for extrude() be a DiscreteGeometry object? decsg() gives a decomposed geometry matrix. I couldn't find a way to convert one type to the other.
Ash128
Ash128 on 14 Apr 2021
Ok, this worked.
g=extrude( geometryFromEdges(model,decsg([2,n, x1,y1].')) ,10);
% geometryFromEdges(model,g);
pdegplot(g,'FaceLabels','on','FaceAlpha',0.5)

Sign in to comment.

More Answers (2)

Matt J
Matt J on 13 Apr 2021
Edited: Matt J on 13 Apr 2021
I don't think you need polyshape here. Because the shape is always convex, all facets are boundary facets and the facet matrix can be obtained directly from convhulln
elements=convhulln(P);
  2 Comments
Ash128
Ash128 on 13 Apr 2021
I did that, but it still gives the 2nd figure that doesn't show all the faces.
K = convhulln(P);
nodes = P';
elements = K';
model = createpde();
geometryFromMesh(model,nodes,elements);
figure
pdegplot(model,'FaceLabels','on','FaceAlpha',0.5)
Matt J
Matt J on 13 Apr 2021
Edited: Matt J on 13 Apr 2021
Well then it's obviously not the fault of either alphaShape or convhulln, if both are giving the same result. Somehow geometryFromMesh isn't able to group the triangular partitions into planar sections.

Sign in to comment.


Matt J
Matt J on 13 Apr 2021
Edited: Matt J on 13 Apr 2021
I'm not familiar with how geometryFromMesh works, but using lcon2vert (which you must Download), you can generate a cell array containing the vertex nodes for each face. Perhaps it will be of some help.
n=9;% The number of sides of the polygon
m=0:n-1;
rootvec=10*exp(1i*2*pi*m/n);%find vertices using nth root of unity
x1=real(rootvec);
y1=imag(rootvec);
z1=10*ones(1,n);
z2=zeros(1,n);
x1 = x1(:);
y1 = y1(:);
z1 = z1(:);
z2 = z2(:);
P = [x1 y1 z1; x1 y1 z2];
n=size(P,1);
[A,b]=vert2lcon(P);
Faces = num2cell( (1:n).*(abs(A*P.'-b)<=1e-6) ,2);
Faces=cellfun(@(z)nonzeros(z).',Faces,'uni',0),
Faces =
11×1 cell array
{1×4 double}
{1×4 double}
{1×4 double}
{1×9 double}
{1×4 double}
{1×4 double}
{1×4 double}
{1×9 double}
{1×4 double}
{1×4 double}
{1×4 double}
  1 Comment
Ash128
Ash128 on 14 Apr 2021
Hi Matt, Thanks for the answer. But I'm not sure this helps in my situation. I added more context in the original question. I want structuralBoundaryLoad() function to be able to identify each face.

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!