3D Sphere projection in Matlab

68 vues (au cours des 30 derniers jours)
Dominik Jerinic
Dominik Jerinic le 18 Sep 2021
Commenté : Star Strider le 21 Sep 2021
Hi to all,
I have a problem making sphere projection in Matlab. I have a lot of horizontal (i = 1:360) and vertical (j = 1:180) values that represents a distance between the geometric center of an object and the outher limit of the bubble. I am using the mesh function and it shows perfect results but only in 2D projection. Also, I am using formula (see below) to transform the spherical coordinates to Cartesien coordinates. After this tranformation, the result is half-sphere design that is not suitable for my presentation and also it is much harder to understand the results. The result should be presented as irregular bubble around the object (center of the coordinate system, position 0-0-0).
Is there any possible way to make full sphere using my values (mentioned "i" and "j")?
sph2cart formula
n=1;
for i=1:360
for j=1:180
[x(n), y(n), z(n)] = sph2cart(deg2rad(i),deg2rad(j),final_results(j,i));
n=n+1;
end
end
x_int = linspace(min(x),max(x));
y_int = linspace(min(y),max(y));
[X, Y] = meshgrid(x_int,y_int);
Z = griddata(x,y,z, X,Y, 'cubic');
surf(X,Y,Z)

Réponses (3)

darova
darova le 19 Sep 2021
interpolate in spherical coordinates
i = rand(20,1);
j = rand(20,1);
r = 1 + 0.1*rand(20,1);
i1 = linspace(min(i),max(i),30);
j1 = linspace(min(j),max(j),30);
[I,J] = meshgrid(i1,j1); % fine mesh
R = griddata(i,j,r,I,J); % interpolate in spherical system
[x,y,z] = sph2cart(I,J,R); % convert to cartesian
[x1,y1,z1] = sph2cart(i,j,r);
[xs,ys,zs] = sphere(30);
plot3(x1,y1,z1,'.r')
surface(x,y,z)
surface(xs,ys,zs,'facecolor','none','edgecolor',ones(1,3)*0.3)
view(45,45)
axis equal
  1 commentaire
Dominik Jerinic
Dominik Jerinic le 19 Sep 2021
Thank you for your effort but maybe I don't understand this code you sent that good that I can use it in my case. Other solution below seems much easier so I will try use that if possible.

Connectez-vous pour commenter.


Star Strider
Star Strider le 19 Sep 2021
I worked on this for a while yesterday, without success. Today, I used a relatively straightforward approach that simply flips ‘Z’ by subtracting it from the minimum of the existing ‘Z’, and then plotting it on the same axes.
See if this does what you want with your ‘final_results’ matrix —
final_results = 1 + rand(180,360)/10;
n=1;
for i=1:360
for j=1:180
[x(n), y(n), z(n)] = sph2cart(deg2rad(i),deg2rad(j),final_results(j,i));
n=n+1;
end
end
x_int = linspace(min(x),max(x));
y_int = linspace(min(y),max(y));
[X, Y] = meshgrid(x_int,y_int);
Z = griddata(x,y,z, X,Y, 'cubic');
Warning: Duplicate x-y data points detected: using average values for duplicate points.
figure
surf(X,Y,Z)
hold on
surf(X,Y,min(Z(:))-Z)
hold off
view(30,30)
axis('equal')
title('Original View')
figure
surf(X,Y,Z)
hold on
surf(X,Y,min(Z(:))-Z)
hold off
view(45,90)
axis('equal')
title('Oblique Top View')
figure
surf(X,Y,Z)
hold on
surf(X,Y,min(Z(:))-Z)
hold off
view(45,0)
axis('equal')
title('Oblique Side View')
Experiment to get different results.
.
  7 commentaires
Dominik Jerinic
Dominik Jerinic le 21 Sep 2021
I will thank you again for your effort. You did a great job and now I have some more codes to think about. Unfortunately, those codes are not satisfied for my project but I will try to figure out something. If you get to some new idea please share with me, I will be very thankful. Best regards.
Star Strider
Star Strider le 21 Sep 2021
My pleasure!
One final attempt —
x_bl = 2;
y_bl = 1;
z_bl = 0.5;
V_bl = -5;
V_bl_v = 0;
mi = 0;
URE_sop_h = 0.715;
URE_sop_v = 0.5;
O_poz = 10;
%% 1. layer
gs_bl = zeros (180, 360);
xy_bl_max = max (x_bl, y_bl);
d_first_layer = max (xy_bl_max, z_bl) / 2;
first_layer = gs_bl + d_first_layer;
%% 2. layer
if V_bl == 0
V_bl_h = 0;
elseif V_bl > 0
V_bl_h = (V_bl^2 - V_bl_v^2)^0.5;
elseif V_bl < 0
V_bl_h = - (V_bl^2 - V_bl_v^2)^0.5;
end
Vjer_p_h = (URE_sop_h / 2 * 6) + mi;
G_p_h_max = abs(V_bl_h) / O_poz;
Vjer_p_v = (URE_sop_v / 2 * 6) + mi;
G_p_v_max = abs(V_bl_v) / O_poz;
if V_bl >= 0
for i = 1:360
for j = 1:180
if i >= 270 || i <= 90
if j <= 90 && V_bl_v >= 0
G_p_h (i) = Vjer_p_h + cosd (i) * G_p_h_max;
G_p_v (j) = Vjer_p_v + cosd (j) * G_p_v_max;
elseif j < 90 && V_bl_v < 0
G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
elseif j > 90 && V_bl_v > 0
G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
elseif j >= 90 && V_bl_v <= 0
G_p_h (i) = Vjer_p_h + cosd (i) * G_p_h_max;
G_p_v (j) = Vjer_p_v - cosd(j) * G_p_v_max;
end
else G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
end
G_p_hv (j,i) = (G_p_h (i)^2 + G_p_v (j)^2)^0.5;
second_layer (j,i) = first_layer (j,i) + G_p_hv (j,i);
end
end
else
for i = 1:360
for j = 1:180
if i <= 270 && i >= 90
if j <= 90 && V_bl_v >= 0
G_p_h (i) = Vjer_p_h - cosd (i) * G_p_h_max;
G_p_v (j) = Vjer_p_v + cosd (j) * G_p_v_max;
elseif j < 90 && V_bl_v < 0
G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
elseif j > 90 && V_bl_v > 0
G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
elseif j >= 90 && V_bl_v <= 0
G_p_h (i) = Vjer_p_h - cosd (i) * G_p_h_max;
G_p_v (j) = Vjer_p_v - cosd (j) * G_p_v_max;
end
else G_p_h (i) = Vjer_p_h;
G_p_v (j) = Vjer_p_v;
end
G_p_hv (j,i) = (G_p_h (i)^2 + G_p_v (j)^2)^0.5;
second_layer (j,i) = first_layer (j,i) + G_p_hv (j,i);
end
end
end
% 2D graphics
mesh (1:360, 1:180, second_layer)
title ('final\_results')
% 3D graphics
n=1;
for i=1:360
for j=1:180
[x(n), y(n), z(n)] = sph2cart(deg2rad(i),deg2rad(j),second_layer(j,i));
n=n+1;
end
end
x_int = linspace(min(x),max(x), 1000);
y_int = linspace(min(y),max(y), 1000);
[X, Y] = meshgrid(x_int,y_int);
Z = griddata(x,y,z, X,Y, 'cubic');
Warning: Duplicate x-y data points detected: using average values for duplicate points.
surf(X,Y,Z, 'EdgeColor','none')
axis('equal')
% THIS 2D FORMULA MAKES PERFECT RESULTS. WHEN YOU CHANGE "V_bl" FROM 5 TO
% -5 RESULT IS AS EXPECTED.
% THIS 3D GRAPHICS FORMULA MAKE HALF-SPHERE BUBBLE AND I NEED FULL-SPHERE
% IRREGULAR BUBBLE ACCORDING TO GIVEN VALUES. WHEN YOU CHANGE "V_bl" FROM 5 TO
% -5 RESULT IS INCORRECT BECAUSE I GET THE SAME SHAPE.
lower_half = 4.25*ones(180,360);
n=1;
for i=1:360
for j=1:180
[x(n), y(n), z2(n)] = sph2cart(deg2rad(i),deg2rad(j),lower_half(j,i));
n=n+1;
end
end
x_int = linspace(min(x),max(x), 1000);
y_int = linspace(min(y),max(y), 1000);
[X, Y] = meshgrid(x_int,y_int);
Z2 = griddata(x,y,z2, X,Y, 'cubic');
Warning: Duplicate x-y data points detected: using average values for duplicate points.
figure
surf(X,Y,Z, 'EdgeColor','none')
hold on
surf(X,Y, min(Z(:))-Z2+0.6, 'EdgeColor','none')
hold off
view(30,30)
axis('equal')
title('Original View')
figure
surf(X,Y,Z, 'EdgeColor','none')
hold on
surf(X,Y,min(Z(:))-Z2+0.6, 'EdgeColor','none')
hold off
view(45,90)
axis('equal')
title('Oblique Top View')
figure
surf(X,Y,Z, 'EdgeColor','none')
hold on
surf(X,Y,min(Z(:))-Z2+0.6, 'EdgeColor','none')
hold off
view(45,0)
axis('equal')
title('Oblique Side View')
This provides a smooth lower half, however the circumferences do not exactly match, so I leave that for you to resolve, since I have never been able to figure out how your code works.
This is the best I can do, and my final effort.
.

Connectez-vous pour commenter.


Dominik Jerinic
Dominik Jerinic le 19 Sep 2021
Thank you for your effort but the upper and lower half-sphere shows the same results even my values are not the same. Maybe there is an errot in the code you sent me or there are some adjustments needed inside the code to show the correct picture. Also, I don't know how to solve the problem of the blank space in the horizontal line 0 (see picture above you posted). In the code, I put i = 1:360 and j = 1:180 values so the i = 0 and j = 0 are blank spots. :( Or maybe it is something in my code but when I am using "mesh" function, everything is great.
  2 commentaires
Star Strider
Star Strider le 19 Sep 2021
I do not have your ‘final_results’ matrix (that I assume is (180x360), since that is how you are addressing it), so I cannot determine what the problem is.
My impression is that your matrix depicts half a sphere, and that you want to plot the whole sphere. I assume that you want a mirror image of the data you have, reflected so that it becomes two symmetric hemispheres, and my code does exactly that.
I need to have the ‘final results’ matrix to work with if you want me to help you with it.
.
Dominik Jerinic
Dominik Jerinic le 19 Sep 2021
My final_results matrix is 180x360 as you said. If we are looking the "i" values, 0 and 360 represents to position right in front of the object (0° or 360°), 90 represents the position exacly to the right side (90° to the right), 180 represents position on the back (backside) and 270 represents position exacly to the left side (90° to the left). If we are looking the "j" values, 0 represents vertical position overhead (+90° pitch), 90 represents the horizontal position (0° pitch) and 180 represents vertical position underground (-90° pitch). So that means that I covered every single degree in horizotal and vertical axis so I should have enough values to make irregular bubble. As you asked, I am sending you the final_result matrix in attachment. It will help me a lot to proceed with my work so I thank you in advance.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by