Effacer les filtres
Effacer les filtres

Unwrapping the mesh on 2D plane

13 vues (au cours des 30 derniers jours)
Marta Stanska
Marta Stanska le 1 Jan 2022
Commenté : Meg Noah le 2 Jan 2022
How to create a flat pattern of this kind of spherical segment of the mesh shown below?
In CAD there is a function called sheet metal to create a flat pattern of 3D models, but how can I devide a sphere like that in Matlab?
I used
r_x = R*cos(0:pi/100:pi);
r_y = R*sin(0:pi/100:pi);
th = 0:2*pi/NumberOfSegments:2*pi;
[th, r_y] = meshgrid(th, r_y);
[X, Y] = pol2cart(th, r_y);
Z = fliplr(r_x)';
Z = repmat(Z,1,NumberOfSegments + 1);
surf(X,Y,Z)
to plot that sphere.
Here is an example - image showing a set of 12 gores to make a globe (I want just one segment).

Réponse acceptée

Meg Noah
Meg Noah le 1 Jan 2022
Here's one way - it's actually a bit overcomplicated than it needs to be in the code below to make it more general:
R = 1;
NumberOfSegments = 12;
r_x = R*cos(0:pi/100:pi);
r_y = R*sin(0:pi/100:pi);
th = 0:2*pi/NumberOfSegments:2*pi;
[th, r_y] = meshgrid(th, r_y);
[X, Y] = pol2cart(th, r_y);
Z = fliplr(r_x)';
Z = repmat(Z,1,NumberOfSegments + 1);
surf(X,Y,Z)
[AZ,EL,radius] = cart2sph(X,Y,Z);
LON_degE = rad2deg(AZ);
LAT_degN = rad2deg(EL);
% last column is wrapping
LON_degE = LON_degE(:,1:NumberOfSegments);
LAT_degN = LAT_degN(:,1:NumberOfSegments);
LON_unique = unique(LON_degE(:));
deltaLon = 360.0/(NumberOfSegments);
% choose a segment
iSegment = 1;
lonC = LON_unique(iSegment);
lon0 = wrapTo180(lonC - deltaLon);
if (lon0 <= -180)
lon0 = 180;
end
lon1 = wrapTo180(lonC + deltaLon);
if (lon1 <= -180)
lon1 = 180;
end
% get the lat/lon points at the great circle at center longitude
idx = find(abs(LON_degE - lonC) < deltaLon/100);
LATC_degN = LAT_degN(idx);
LONC_degE = LON_degE(idx);
% get the lat/lon points at the great circle at previous longitude
idx = find(abs(LON_degE - lon0) < deltaLon/100);
LAT0_degN = LAT_degN(idx);
LON0_degE = LON_degE(idx);
% get the lat/lon points at the great circle at next longitude
idx = find(abs(LON_degE - lon1) < deltaLon/100);
LAT1_degN = LAT_degN(idx);
LON1_degE = LON_degE(idx);
% find the arclength distances between consequetive points
% along the center line use the haversine formula for great
% circles on a sphere.
% find the arclength distances from the center to the previous longitude
goreY = R*deg2rad(distance(LATC_degN(1),LONC_degE(1),LATC_degN,LONC_degE));
% arclength distances to the previous longitude
goreX0 = -R*deg2rad(distance(LAT0_degN,LON0_degE,LATC_degN,LONC_degE));
% arclength distances to the next longitude
goreX1 = R*deg2rad(distance(LATC_degN,LONC_degE,LAT1_degN,LON1_degE));
figure()
plot(goreX0,goreY,'--.r');
hold on;
plot(goreX1,goreY,'--.b');
axis equal
  1 commentaire
Meg Noah
Meg Noah le 2 Jan 2022
OK, here's another attempt:
R = 1;
NumberOfSegments = 24;
NumberOfLatitudes = 100;
r_x = R*cos(0:pi/NumberOfLatitudes:pi);
r_y = R*sin(0:pi/NumberOfLatitudes:pi);
th = 0:2*pi/NumberOfSegments:2*pi;
LON_unique = rad2deg(th);
deltaLon = 360.0/(NumberOfSegments);
[th, r_y] = meshgrid(th, r_y);
[X, Y] = pol2cart(th, r_y);
Z = fliplr(r_x)';
Z = repmat(Z,1,NumberOfSegments + 1);
% surf(X,Y,Z)
[AZ,EL,radius] = cart2sph(X,Y,Z);
LON_degE = rad2deg(AZ);
LAT_degN = rad2deg(EL);
% last column is wrapping
LON_degE = LON_degE(2:NumberOfLatitudes+1,1:NumberOfSegments);
LAT_degN = LAT_degN(2:NumberOfLatitudes+1,1:NumberOfSegments);
% choose a segment
figure()
clrs = colormap(jet);
deltaClr = floor(size(clrs,1)/NumberOfSegments);
for iSegment = 1:2:NumberOfSegments
lonC = wrapTo180(LON_unique(iSegment));
if (lonC <= -180)
lonC = 180;
end
lon0 = wrapTo180(lonC - deltaLon);
if (lon0 <= -180)
lon0 = 180;
end
lon1 = wrapTo180(lonC + deltaLon);
if (lon1 <= -180)
lon1 = 180;
end
% get the lat/lon points at the great circle at center longitude
idx = find(abs(LON_degE - lonC) < 1e-4);
LATC_degN = LAT_degN(idx);
LONC_degE = LON_degE(idx);
% get the lat/lon points at the great circle at previous longitude
idx = find(abs(LON_degE - lon0) < deltaLon/100);
LAT0_degN = LAT_degN(idx);
LON0_degE = LON_degE(idx);
% get the lat/lon points at the great circle at next longitude
idx = find(abs(LON_degE - lon1) < deltaLon/100);
LAT1_degN = LAT_degN(idx);
LON1_degE = LON_degE(idx);
% find the arclength distances between consequetive points
% along the center line use the haversine formula for great
% circles on a sphere.
% find the arclength distances from the center to the previous longitude
idxEquator = find(abs(LATC_degN) < 1e-4);
goreY = R*deg2rad(distance(LATC_degN(idxEquator),LONC_degE(idxEquator),LATC_degN,LONC_degE));
goreY(LATC_degN < 0) = -goreY(LATC_degN < 0);
% find the center of the gore in the Longitudes from the first one
goreXC = R*deg2rad(distance(0,lonC,0,0));
if (lonC < 0)
goreXC = -goreXC;
end
% arclength distances to the previous longitude
goreX0 = goreXC-R*deg2rad(distance(LAT0_degN,LON0_degE,LATC_degN,LONC_degE));
% arclength distances to the next longitude
goreX1 = goreXC+R*deg2rad(distance(LATC_degN,LONC_degE,LAT1_degN,LON1_degE));
iclr = deltaClr*(iSegment-1)+1;
if iclr > size(clrs,1)
iclr = 1;
end
plot(goreXC*ones(size(goreY)),goreY,':','color',clrs(iclr,:));
hold on;
plot(goreX0,goreY,'.','color',clrs(iclr,:));
plot(goreX1,goreY,'.','color',clrs(iclr,:));
xticks([-pi,-3*pi/4,-pi/2,-pi/4,0,pi/4,pi/2,3*pi/4,pi]);
xticklabels({'-\pi','-3\pi/4','-\pi/2','-\pi/4','0','\pi/4','\pi/2','3\pi/4','\pi'});
xlim([-5*pi/4 5*pi/4]);
yticks([-pi/2,-pi/4,0,pi/4,pi/2]);
yticklabels({'-\pi/2','-\pi/4','0','\pi/4','\pi/2'});
ylim([-3*pi/4,3*pi/4]);
axis equal
end

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Elementary Polygons dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by