Unwrapping the mesh on 2D plane

조회 수: 40 (최근 30일)
Marta Stanska
Marta Stanska 2022년 1월 1일
댓글: Meg Noah 2022년 1월 2일
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).

채택된 답변

Meg Noah
Meg Noah 2022년 1월 1일
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
Meg Noah
Meg Noah 2022년 1월 2일
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

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Point Cloud Processing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by