Convert gridded sphere to dots cloud and back - matlab

I have a problem with surface generation in matlab. Below is small code. This code looks nonsense, but if It will works I would be happy with my main code :).
% create gridded 3D object
[X Y Z]=sphere(1000);
subplot(1,2,1);
sphere(50) % just for example
% transform it to 3D cloud
X=X(:);
Y=Y(:);
Z=Z(:);
idx=randperm(numel(X),10^3);
X=X(idx);
Y=Y(idx);
Z=Z(idx);
% try to restore surface
F = scatteredInterpolant(X,Y,Z);
[gX,gY]=ndgrid(linspace(min(X),max(X),100),...
linspace(min(Y),max(Y),100));
gZ=F(gX,gY);
subplot(1,2,2)
surface(gX,gY,gZ)
The problem is: if I have gridded data I may plot sphere (left picture) if my data are just Nx3 array with coordinates of some random dots on the sphere I have right picture.
I had similar question already, but the data were well organised. Could You help me with this? If you have solution on other languages or OpenGL You are welcome!

Related

Projecting an image onto a cylindrical surface in a way where the image appears flat

I'm trying to print out QR codes onto the surface of water bottles using matlab. However, the QR bottles cannot be recognized because of the curved surface of the bottle, and the therefore deformed shape of the QR codes.
I was wondering what mathematical equation I might have to apply to deform the picture (for both the general geometry of the picture, and the spacing deformation inside the picture), so that when printed onto a cylindrical surface, it seems like its on a flat surface to a camera.
Thanks!
I had some success with this and though it doesn't use Matlab, it may give you, or someone else an idea on a possible way to get started.
I generated a QR code with qrencode in Terminal like this:
qrencode -o qr.png -d 300 'http://www.thesetchells.com'
I resized that to 500x500 and then generated a "displacement map" which is just a linear gradient with a contrast stretch created to match the size of the QR code. I used ImageMagick in Terminal, but obviously you can use Matlab or other tools:
I then applied the displacement map to my QR code like this:
convert qr.png map.png -fx 'p{v*w,j}' result.png
And got a distorted QR code, which I printed and wrapped round a large bottle and my iPhone was able to read it.
Anthony Thyssen has some very useful information on "displacement maps" here.
So I've tried an approach to my problem using the basic "car.jpg" image included in Matlab.
So far, I've taken a square part of the car picture, and wrapped it around the surface of part of a cylinder.
Here is my code:
close all, clf, clear all
%% Creating cylinder
r = 6; %centimeter
h = 25; %centimeter
[X,Y,Z] = cylinder(r,100);
x = X(:,1:ceil(length(X)/3));
y = Y(:,1:ceil(length(Y)/3));
z = Z(:,1:ceil(length(Z)/3));
%% Plotting cylinder surface
figure(1), clf
h = surf(x,y,z); hold on
axis([-r r -r r]*2.2)
plot3([-r -r], get(gca,'ylim'), [0 0]);
plot3([r r], get(gca,'ylim'), [0 0]);
plot3(get(gca,'xlim'), [-r -r], [0 0]);
plot3(get(gca,'xlim'), [r r], [0 0]);
xlabel('x');
ylabel('y');
zlabel('z');
rotate3d on
axis vis3d
%% Car image
img = imread('car.jpg');
img = imrotate(img,180);
figure(2), clf
%imshow(img(1:340, 1:340, :));
imagesc(img(1:340, 1:340, :));
figure(), clf
warped_plot = warp(x,y,z,img(1:340, 1:340, :))
The next step could be to now project that warped image onto a flat surface (but I'm not sure how to do that mathematically, nor have I found a in-built Matlab function to do this).
Another possibility I was hoping to get feedback on, is to find a mathematical relation between corresponding horizontal points on the flat and cylindrical image, and then to apply the inverse of that equation to the flat image, so that once it is printed out and stuck onto a cylindrical surface it appears flat.

Draw surface of 3D cloud in matlab

I have 3D cloud of dots. I need to plot them as a surface. I tried variant with meshdrid, griddata, scatteredInterpolant,trisurf-delaunay. Nothing works. I know that this question was discussed a lot, but it seems I don't understand some important details. The code which i have now:
load('coords.mat')
figure()
subplot(1,2,1)
plot3(x,y,z,'.')
axis off
view(3)
subplot(1,2,2)
C=gray(numel(x)); % unsuccessful attempt
[~,idx]=sort(z); % to have
C=C(idx,:); % illumination
scatter3(x,y,z,50,C,'filled')
axis off
view(3)
produces the following image:
Could you help me:
1) to find a way to draw it with surface function.
and as some dots may be inside the surface (may be it is my problem)
2) How to remove 'invisible' dots?
I need solution for different cases, picture and data presents just an example.
Mat file may be downloaded here.
P.S.
In case it is important – I obtain coordinates of this dots as a rotation of random bezier curve.
UPDATE
In case data above is too big I generate another set with smaller amount of dots:
Coordinates are here.
where do you get this data from? It is represented as vectors but if you reshape it to matrices you can use the surf function. Try this code:
z=reshape(z,100,100);
y=reshape(y,100,100);
x=reshape(x,100,100);
surf(x,y,z)

Need help in 3D plot using MATLAB (X,Y,Z,V)

I need to ask help in plotting a 3D volume in MATLAB. My data set includes the X, Y, Z coordinate and corresponding intensity value, V.
I was using pcolor (X,Y,V) and shading interp while i was doing the 2D images but then I got stuck when I am about to create the 3D images. I have tried scatter3, smooth3 and slice but it seems it does not fit the function I need.
My goal is to plot the 3D grid with the corresponding intensity value per coordinate and apply shading interp between these points.
I am really new in 3D plotting and I would really appreciate any help in achieving my goal. Thank you so much!
Here are some example of images that I am trying to create
(source: ndt.net)
(source: www.bam.de)
I have a solution for your first example, in which you show three cross-sections of the volume data. With this solution you can essentially plot several pcolor with different orientations, in one same 3D figure.
First, you need the data for the different slices. This is exactly what you had when you did pcolor(X,Y,V) to plot the cross section in 2D, where X, Y and V are two dimensional matrices. You will also need to create a matrix Z with the z-position of the slice (e.g. Z = zeros(size(X)) + z0). Then you use the command surface(X,Y,Z,V) to plot the cross section image in 3D, where X,Y,Z are the positions, and V is the color (value of the function).
Repeat this procedure for all the other slices, using appropriate X,Y,Z,V matrices for each slice. For slices oriented on other axes you will have to define X,Y,Z accordingly. Remember to use "hold on" after the first surface command, so that all the slices are plotted.
Example:
surface(X1,Y1,Z1,V1); shading interp; hold on
surface(X2,Y2,Z2,V2); shading interp;
surface(X3,Y3,Z3,V3); shading interp;
colormap(jet(2048)); caxis([0,3]); % color axis colormap and scaling
axis equal; xlabel('X'); ylabel('Y'); zlabel('Z') % X,Y,Z scaling and label
Result figure here:

Plotting 2 functions in a 3D chart

I am new to MATLAB. I have 2 functions,z=sin(x) and
y=cos(x). I want to plot them in a 3D (x,y,z) chart (but not with subplot), z=sin(x) in plane X-Z and y=cos(x) in plane X-Y. As I have seen, standard plot or plot3d functions are not obvious to use. May be needed some axis manipulation, etc, but I don't have it.
I would like to know the solution if only I would or any guidance is appreciated.
Here you have a small example of what you want to do
clear;clc; %clear variables from workspace and clean commadn line
x=-pi:0.1:pi; %define x
cero=zeros(size(x)); %create a vector of zeros
z=sin(x);
y=cos(x);
hold on %tell matlab to plot averything together
plot3(x,cero,z,'g');
plot3(x,y,cero,'r');
grid on; %pretty self-describing
view([1,1,1]) %set viewpoint to not se just a plane
hold off %stop ploting everything together
Ask if you don't get some of the lines

How do I make a surf plot in MATLAB with irregularly spaced data?

I know I can create a 3D surface plot in MATLAB by doing:
x = linspace(1,10,100);
y = linspace(10,20,100);
[X Y] = meshgrid(x,y);
Z = X * Y;
surf(X,Y,Z);
But this requires that all the nodes for the height map generated line up. I have a set of data which has arbitrary points (x,y) and a height (z). Is there a simple way to plot a graph which will generate a surface between the points in a similar fashion to surf?
Appologies, after some hunting I managed to answer my own question:
You can use the trisurf function:
tri = delaunay(x,y);
trisurf(tri,x,y,z);
If you have dense data you will want to do shading interp (or another value, check doc shading) so you don't get a black blob due to the grid.
It looks like you've found your answer by using DELAUNAY and TRISURF to generate and plot a triangulated surface.
As an alternative, you could also fit a regularly-spaced grid to your nonuniformly-spaced points in order to generate a surface that can be plotted with the SURF command. I discuss how this can be done using the TriScatteredInterp class (or the deprecated function GRIDDATA) in my answer to this other question on SO.