How can I plot overlapping rectangles so that they interact with each other?

If I wanted to have rectangles visualised in a 3D space with a small and constant depth that overlapped each other in a certain pattern (similar to a weaving pattern), how would I go about it?
I was thinking of using patch() for the rectangles themselves but I couldn't figure out how to get further than that. I'm looking for something similar to the sketch below.

 Réponse acceptée

DGM
DGM le 16 Mai 2023
Modifié(e) : DGM le 17 Mai 2023
Here's a start.
w = 4; % ribbon width
th = 0.2; % ribbon thickness
m = 0; % in-plane distance between bend interior and ribbon edge
mz = 0.1; % spacing between wide faces and z=0 plane
s = 2; % nominal spacing between ribbon edges
tl = 3; % tail length
p = th*tan(atan((2*mz + th)/s)/2); % a little bit of math
% vertices [x y z]
V0 = [-tl 0 mz;
w+m 0 mz;
w+m+s 0 -mz-th;
2*(w+m)+tl+s+p 0 -mz-th;
2*(w+m)+tl+s+p w -mz-th;
w+m+s w -mz-th;
w+m w mz;
-tl w mz;
-tl 0 mz+th;
w+m+p 0 mz+th;
w+m+p+s 0 -mz;
2*(w+m)+tl+s+p 0 -mz;
2*(w+m)+tl+s+p w -mz;
w+m+p+s w -mz;
w+m+p w mz+th;
-tl w mz+th];
% each row is the list of vertices defining a quadrilateral patch
F = [1 2 7 8; 2 3 6 7; 3 4 5 6; 9 10 15 16; 10 11 14 15; 11 12 13 14; 1 8 16 9;
4 5 13 12; 1 9 10 2; 10 2 3 11; 3 11 12 4; 5 13 14 6; 14 6 7 15; 7 15 16 8];
% each ribbon can be built using simple transformations of V
patch('faces',F,'vertices',V0,'facecolor','r')
V = V0(:,[2 1 3]); % swap x,y
V(:,3) = -V(:,3); % flip z
patch('faces',F,'vertices',V,'facecolor','g')
V = V0;
V(:,2) = V(:,2) + s + 2*m + w + p; % offset y
V(:,3) = -V(:,3); % flip z
patch('faces',F,'vertices',V,'facecolor','b')
V = V0(:,[2 1 3]); % swap x,y
V(:,1) = V(:,1) + s + 2*m + w + p; % offset x
patch('faces',F,'vertices',V,'facecolor','y')
% arrange the view
view(3)
axis equal
The transformations could also be done using copyobj() and hgtransform(), but I think this is just easier.
If you can read my tablet-writing, this diagram should explain the parameters and the math.

7 commentaires

Thank you so much! Could you walk me through what variable p is for and how that equation was derived in line 6?
DGM
DGM le 16 Mai 2023
Modifié(e) : DGM le 16 Mai 2023
I added a diagram that shows where p comes from.
p is the difference in length between the larger top and bottom faces. It's what makes sure that the angled section still has the same thickness. As s approaches 0, the angled section becomes vertical and p approaches th.
EDIT: I changed it so that the margin parameter m is split into two independent parts. For a tight weave, both should be zero.
I see. Is there also a way to modify it so that it could accomodate multiple ribbons rather than just two in each direction?
DGM
DGM le 16 Mai 2023
Modifié(e) : DGM le 16 Mai 2023
Sure. If the number of ribbons in each direction is parametric (N), then the number of bends in each ribbon is dependent on those parameters. Whereas I simply wrote out the vertex list for the initial ribbon, V and F would need to be generated programmatically. If the number of ribbons in each direction is not the same, then the shortcut of rotating V won't work, and you'd need to generate V twice for the different values in N.
Here, try this one.
N = [3 4]; % number of ribbons [x y]
w = 4; % ribbon width
th = 0.5; % ribbon thickness
m = 0; % in-plane distance between bend interior and ribbon edge
mz = 0; % spacing between wide faces and z=0 plane
s = 3*th; % nominal spacing between ribbon edges
tl = 2; % tail length
% define some color table for all the ribbons
CT = lines(sum(N));
% a little bit of math
p = th*tan(atan((2*mz + th)/s)/2);
N = max(N,2); % minimum N is 2
% for ribbons running in x-direction
[V0 F] = buildshape(N(1),w,th,m,mz,s,tl,p);
for k = 1:N(2)
V = V0;
V(:,2) = V(:,2) + (k-1)*(s + 2*m + w + p); % offset y
V(:,3) = sign(mod(k,2)-0.5)*V(:,3); % flip z
patch('faces',F,'vertices',V,'facecolor',CT(k,:))
end
% for ribbons running in y-direction
[V0 F] = buildshape(N(2),w,th,m,mz,s,tl,p);
V0 = V0(:,[2 1 3]); % rotate
for k = 1:N(1)
V = V0;
V(:,1) = V(:,1) + (k-1)*(s + 2*m + w + p); % offset x
V(:,3) = -sign(mod(k,2)-0.5)*V(:,3); % flip z
patch('faces',F,'vertices',V,'facecolor',CT(N(2)+k,:))
end
view(3)
axis equal
function [V F] = buildshape(n,w,th,m,mz,s,tl,p)
% BUILD VERTEX LIST
% build X
a = tl+w+m; b = a+p; c = w+2*m; d = c+2*p;
x = [a b; repmat([s s; d c],[n-2,1])]; % [bottomedge topedge]
% flip alternate length rows
idx = 5:4:length(x);
x(idx,:) = fliplr(x(idx,:));
% if N is even, end row is flipped
if mod(n,2)
x = [x; s s; a b];
else
x = [x; s s; b a];
end
% accumulate and reshape
x = reshape([0 0; cumsum(x,1)],[],1) - tl;
% build Z
z = [mz -mz-th];
z = repmat(z(mod(0:n-1,2)+1),[2 1]);
z = reshape(z + permute([0 th],[1 3 2]),[],1);
% build Y
y = repmat([0 w],[numel(z),1]);
% vertices [x y z]
V = [[x; x] y(:) [z; z]];
% BUILD FACE LIST
Fe = [1 2 2*n+[2 1]] + (0:2*(n-1)).'; % long edge faces
Fe = [Fe; Fe+4*n];
Fb = [1 2 4*n+[2 1]] + (0:2*(n-1)).'; % bottom faces
Ft = Fb + 2*n; % top faces
Fc = [0 2 6 4; 2 4 8 6]*n + [1; 0]; % end caps
F = [Fe; Fb; Ft; Fc];
end
There are probably easier ways to do this, but this is the way I did it.
For the x segment terms a,b,c,d:
This is super helpful, thank you so much!
I fixed a mistake in the calculation of P. I'm pretty sure I had that right before I split m into two parameters, but I had to make mistakes somewhere.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Graphics Performance dans Centre d'aide et File Exchange

Produits

Version

R2022b

Question posée :

le 16 Mai 2023

Commenté :

DGM
le 17 Mai 2023

Community Treasure Hunt

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

Start Hunting!

Translated by