I have line, or trajectory in 3D space. I also have a 2D shape. I want to take this shape and move it along the curve keeping the surface normal parallel to the tangent of the curve. Based on a post here I have successfully done this that produces something which 'looks right' for shapes with rotational symmetry like a circle. See the code and figure below for the example.
% create data
npts = 30;
tend = 8*pi;
t = linspace(0,tend,npts)';
z = linspace(-1,1,npts)';
omz = sqrt(1-z.^2);
x = cos(t).*omz;
y = sin(t).*omz;
scatter3 (x,y,z, 'x');
hold on
% fit 3 slms to data in each direction
xslm = slmengine (t, x, 'knots', ceil(npts/1.5));
yslm = slmengine (t, y, 'knots', ceil(npts/1.5));
zslm = slmengine (t, z, 'knots', ceil(npts/1.5));
% test points
tq = linspace(0,tend,200 * npts)';
dx = slmeval (t, xslm, 1, false);
dy = slmeval (t, yslm, 1, false);
dz = slmeval (t, zslm, 1, false);
quiver3(x,y,z,dx,dy,dz);
plot3 (slmeval(tq, xslm, 0, false), slmeval(tq, yslm, 0, false), slmeval(tq, zslm, 0, false));
hold off
axis equal
% The following taken from post on matlab central
%
% http://uk.mathworks.com/matlabcentral/newsreader/view_thread/159522
%
% P10 = P1-P0;
%
% P20 = P2-P0;
% N = dot(P10,P10)*P20-dot(P20,P20)*P10; % <-- Approx. tangent direction
R = 0.05;
P0 = [x,y,z];
N = [dx, dy, dz];
% circle points
% theta = linspace(0,2*pi).';
box_x = [ -R; R; R; -R; -R ];
box_y = [ -R/2; -R; R; R/2; -R/2 ];
for ind = 1:size(P0,1)
T = null(N(ind,:)).'; % Get two orthogonal unit vectors which are orthog. to N
% V = bsxfun ( #plus, ...
% R * ( cos(theta) * T(1,:) + sin(theta) * T(2,:) ), ...
% P0(ind,:) );
V = bsxfun ( #plus, ...
box_x * T(1,:) + box_y * T(2,:), ...
P0(ind,:) );
hold on
quiver3(P0(ind,1),P0(ind,2),P0(ind,3),T(1,1),T(1,2),T(1,3), 0.5, 'b');
quiver3(P0(ind,1),P0(ind,2),P0(ind,3),T(2,1),T(2,2),T(2,3), 0.5, 'b');
plot3(V(:,1),V(:,2),V(:,3));
hold off
end
Note that this code makes use of the Shape Language Modelling functions from the Matlab file exchange to make the curve and get it's tangent at various points, but this isn't crucial to the problem.
However, as you can see, the rotation of the shape flips as you move around the curve with this method. I need to keep the rotation of the shape consistent as I actually wish to sample values from scattered 3D data on the shape surface which represents the inside of a 'tube' or whatever the shape is.
So how can I control the orientation of my shape as I move along the curve?
You need 2 vectors and position! The tangent (you have it) and one vector to align to like up which must be not parallel to tangent. Then just construct 3D transform matrix use tangent as Z-axis and exploit the cross product to get the other two for example:
Up = (0,1,0)
Z = tangent/|tangent|
X = cross(Z,Up)
Y = cross(X,Z)
O = position
Position is just the actual position at the trajectory +/- shape offset. You can adjust the sign of the X,Y,Z axises by negating them or by changing the cross product operand order to obtain the mirroring of shape you want. Now to construct the transform matrix see:
Understanding 4x4 homogenous transform matrices
Now just transform/render your shape with this matrix.
Related
How to distribute the points to be like Fig.A
This matlab code for Fig. B :
N = 30; % number of points
r = 0.5; % r = radius
d = 50; % dimension
C_point = 0; % center point
figure, clf
C = ones(1, d) * C_point;
C_rep = repmat( C,N,1);
X = randn(N,d);
s2 = sum(X.^2,2) ;
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius./sqrt(s2),1,d) + C_rep;
%% Plot 2D
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
hold on
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
hold on
plot(X(:,1), X(:,2),'r.','markersize',10);
axis equal;rotate3d off; rotate3d on;drawnow;shg;
hold on
ax = axis;
Source of the code
What I should change to be like fig. A
The OP's code computes points uniformly distributed within a d-dimensional box, projects those onto a d-dimensional sphere, then samples the radius to move them inside the d-dimensional ball. This is perfect except that the points inside the box, when projected onto the sphere, do not form a uniform distribution on that sphere. If instead you find random points distributed in a Gaussian distribution, you are guaranteed uniform angle distribution.
First compute points with a Gaussian distribution in d dimensions (I do all here with minimal changes to the OP's code):
N = 1000; % number of points
r = 0.5; % r = radius
d = 3; % dimension
C_point = 0; % center point
C = ones(1,d) * C_point;
C_rep = repmat(C,N,1);
X = randn(N,d);
Note that I use randn, not rand. randn creates a Gaussian distribution.
Next we normalize the vectors so the points move to the sphere:
nX = sqrt(sum(X.^2,2));
X = X./repmat(nX,1,d);
These points are uniformly distributed, which you can verify by scatter3(X(:,1),X(:,2),X(:,3)); axis equal and turning the display around (a 2D rendering doesn't do it justice). This is the reason I set d=3 above, and N=1000. I wanted to be able to plot the points and see lots of them.
Next we compute, as you already did, a random distance to the origin, and correct it for the dimensionality:
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius,1,d) + C_rep;
X now is distributed uniformly in the ball. Again, scatter3(X(:,1),X(:,2),X(:,3)); axis equal shows this.
However, if you set d=50 and then plot only two dimensions of your data, you will not see the data filling the circle. And you will not see a uniform distribution either. This is because you are projecting a 50-D ball onto 2 dimensions, this simply does not work. You either have to trust the math, or you have to slice the data:
figure, hold on
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
axis equal
I = all(abs(X(:,3:d))<0.1,2);
plot(X(I,1), X(I,2),'r.','markersize',10);
The I there indexes points that are close to the origin in dimensions perpendicular to the first two shown. Again, with d=50 you will have very few points there, so you will need to set N very large! To see the same density of points as in the case above, for every dimension you add, you need to multiply N by 10. So for d=5 you'd have N=1000*10*10=1e5, and for d=50 you'd need N=1e50. That is totally impossible to compute, of course.
I have polar coordinates, radius 0.05 <= r <= 1 and 0 ≤ θ ≤ 2π. The radius r is 50 values between 0.05 to 1, and polar angle θ is 24 values between 0 to 2π.
How do I interpolate r = 0.075 and theta = pi/8?
I dunno what you have tried, but interp2 works just as well on polar data as it does on Cartesian. Here is some evidence:
% Coordinates
r = linspace(0.05, 1, 50);
t = linspace(0, 2*pi, 24);
% Some synthetic data
z = sort(rand(50, 24));
% Values of interest
ri = 0.075;
ti = pi/8;
% Manually interpolate
rp = find(ri <= r, 1, 'first');
rm = find(ri >= r, 1, 'last');
tp = find(ti <= t, 1, 'first');
tm = find(ti >= t, 1, 'last');
drdt = (r(rp) - r(rm)) * (t(tp) - t(tm));
dr = [r(rp)-ri ri-r(rm)];
dt = [t(tp)-ti ti-t(tm)];
fZ = [z(rm, tm) z(rm, tp)
z(rp, tm) z(rp, tp)];
ZI_manual = (dr * fZ * dt.') / drdt
% Interpolate with MATLAB
ZI_MATLAB = interp2(r, t, z', ri, ti, 'linear')
Result:
ZI_manual =
2.737907208525297e-002
ZI_MATLAB =
2.737907208525298e-002
Based on comments you have the following information
%the test point
ri=0.53224;
ti = pi/8;
%formula fo generation of Z
g=9.81
z0=#(r)0.01*(g^2)*((2*pi)^-4)*(r.^-5).*exp(-1.25*(r/0.3).^-4);
D=#(t)(2/pi)*cos(t).^2;
z2=#(r,t)z0(r).*D(t) ;
%range of vlaues of r and theta
r=[0.05,0.071175,0.10132,0.14422,0.2053, 0.29225,0.41602,0.5922,0.84299,1.2];
t=[0,0.62832,1.2566,1.885, 2.5133,3.1416,3.7699,4.3982,5.0265,5.6549,6.2832];
and you want interplation of the test point.
When you sample some data to use them for interpolation you should consider how to sample data according to your requirements.
So when you are sampling a regular grid of polar coordinates ,those coordinates when converted to rectangular will form a circular shape that
most of the points are concentrated in the center of the cricle and when we move from the center to outer regions distance between the points increased.
%regular grid generated for r and t
[THETA R] = meshgrid(t ,r);
% Z for polar grid
Z=z2(R,THETA);
%convert coordinate from polar to cartesian(rectangular):
[X, Y] = pol2cart (THETA, R);
%plot points
plot(X, Y, 'k.');
axis equal
So when you use those point for interpolation the accuracy of the interpolation is greater in the center and lower in the outer regions where the distance between points increased.
In the other word with this sampling method you place more importance on the center region related to outer ones.
To increase accuracy density of grid points (r and theta) should be increased so if length of r and theta is 11 you can create r and theta with size 20 to increase accuracy.
In the other hand if you create a regular grid in rectangular coordinates an equal importance is given to each region . So accuracy of the interpolation will be the same in all regions.
For it first you create a regular grid in the polar coordinates then convert the grid to rectangular coordinates so you can calculate the extents (min max) of the sampling points in the rectangular coordinates. Based on this extents you can create a regular grid in the rectangular coordinates
Regular grid of rectangular coordinates then converted to polar coordinated to get z for grid points using z2 formula.
%get the extent of points
extentX = [min(X(:)) max(X(:))];
extentY = [min(Y(:)) max(Y(:))];
%sample 100 points(or more or less) inside a region specified be the extents
X_samples = linspace(extentX(1),extentX(2),100);
Y_samples = linspace(extentY(1),extentY(2),100);
%create regular grid in rectangular coordinates
[XX YY] = meshgrid(X_samples, Y_samples);
[TT RR] = cart2pol(XX,YY);
Z_rect = z2(RR,TT);
For interpolation of a test point say [ri ti] first it converted to rectangular then using XX ,YY value of z is interpolated
[xi yi] = pol2cart (ti, ri);
z=interp2(XX,YY,Z_rect,xi,yi);
If you have no choice to change how you sample the data and only have a grid of polar points as discussed with #RodyOldenhuis you can do the following:
Interpolate polar coordinates with interp2 (interpolation for gridded data)
this approach is straightforward but has the shortcoming that r and theta are not of the same scale and this may affect the accuracy of the interpolation.
z = interp2(THETA, R, Z, ti, ri)
convert polar coordinates to rectangular and then apply an interpolation method that is for scattered data.
this approach requires more computations but result of it is more reliable.
MATLAB has griddata function that given scattered points first generates a triangulation of points and then creates a regular grid on top of the triangles and interpolates values of grid points.
So if you want to interpolate value of point [ri ti] you should then apply a second interpolation to get value of the point from the interpolated grid.
With the help of some information from spatialanalysisonline and Wikipedia linear interpolation based on triangulation calculated this way (tested in Octave. In newer versions of MATLAB use of triangulation and pointLocation recommended instead of delaunay and tsearch ):
ri=0.53224;
ti = pi/8;
[THETA R] = meshgrid(t ,r);
[X, Y] = pol2cart (THETA, R);
[xi yi] = pol2cart (ti, ri);
%generate triangulation
tri = delaunay (X, Y);
%find the triangle that contains the test point
idx = tsearch (X, Y, tri, xi, yi);
pts= tri(idx,:);
%create a matrix that repesents equation of a plane (triangle) given its 3 points
m=[X(pts);Y(pts);Z(pts);ones(1,3)].';
%calculate z based on det(m)=0;
z= (-xi*det(m(:,2:end)) + yi*det([m(:,1) m(:,3:end)]) + det(m(:,1:end-1)))/det([m(:,1:2) m(:,end)]);
More refinement:
Since it is known that the search point is surrounded by 4 points we can use only those point for triangulation. these points form a trapezoid. Each diagonal of trapezoid forms two triangles so using vertices of the trapezoid we can form 4 triangles, also a point inside a trapezoid can lie in at least 2 triangles.
the previous method based on triangulation only uses information from one triangle but here z of the test point can be interpolated two times from data of two triangles and the calculated z values can be averaged to get a better approximation.
%find 4 points surrounding the test point
ft= find(t<=ti,1,'last');
fr= find(cos(abs(diff(t(ft+(0:1))))/2) .* r < ri,1,'last');
[T4 R4] = meshgrid(t(ft+(0:1)), r(fr+(0:1)));
[X4, Y4] = pol2cart (T4, R4);
Z4 = Z(fr+(0:1),ft+(0:1));
%form 4 triangles
tri2= nchoosek(1:4,3);
%empty vector of z values that will be interpolated from 4 triangles
zv = NaN(4,1);
for h = 1:4
pts = tri2(h,:);
% test if the point lies in the triangle
if ~isnan(tsearch(X4(:),Y4(:),pts,xi,yi))
m=[X4(pts) ;Y4(pts) ;Z4(pts); [1 1 1]].';
zv(h)= (-xi*det(m(:,2:end)) + yi*det([m(:,1) m(:,3:end)]) + det(m(:,1:end-1)))/det([m(:,1:2) m(:,end)]);
end
end
z= mean(zv(~isnan(zv)))
Result:
True z:
(0.0069246)
Linear Interpolation of (Gridded) Polar Coordinates :
(0.0085741)
Linear Interpolation with Triangulation of Rectangular Coordinates:
(0.0073774 or 0.0060992) based on triangulation
Linear Interpolation with Triangulation of Rectangular Coordinates(average):
(0.0067383)
Conclusion:
Result of interpolation related to structure of original data and the sampling method. If the sampling method matches pattern of original data result of interpolation is more accurate, so in cases that grid points of polar coordinates follow pattern of data result of interpolation of regular polar coordinate can be more reliable. But if regular polar coordinates do not match the structure of data or structure of data is such as an irregular terrain, method of interpolation based on triangulation can better represent the data.
please check this example, i used two for loops, inside for loop i used condition statement, if u comment this condition statement and run the program, u'll get correct answer, after u uncomment this condition statement and run the program, u'll get wrong answer. please check it.
% Coordinates
r = linspace(0.05, 1, 10);
t = linspace(0, 2*pi, 8);
% Some synthetic data
%z = sort(rand(50, 24));
z=zeros();
for i=1:10
for j=1:8
if r(i)<0.5||r(i)>1
z(i,j)=0;
else
z(i,j) = r(i).^3'*cos(t(j)/2);
end
end
end
% Values of interest
ri = 0.55;
ti = pi/8;
% Manually interpolate
rp = find(ri <= r, 1, 'first');
rm = find(ri >= r, 1, 'last');
tp = find(ti <= t, 1, 'first');
tm = find(ti >= t, 1, 'last');
drdt = (r(rp) - r(rm)) * (t(tp) - t(tm));
dr = [r(rp)-ri ri-r(rm)];
dt = [t(tp)-ti ti-t(tm)];
fZ = [z(rm, tm) z(rm, tp)
z(rp, tm) z(rp, tp)];
ZI_manual = (dr * fZ * dt.') / drdt
% Interpolate with MATLAB
ZI_MATLAB = interp2(r, t, z', ri, ti, 'linear')
Result:
z1 =
0.1632
ZI_manual =
0.1543
ZI_MATLAB =
0.1582
I have a dataset that describes a point cloud of a 3D cylinder (xx,yy,zz,C):
and I would like to make a surface plot from this dataset, similar to this
In order to do this I thought I could interpolate my scattered data using TriScatteredInterp onto a regular grid and then plot it using surf:
F = TriScatteredInterp(xx,yy,zz);
max_x = max(xx); min_x = min(xx);
max_y = max(yy); min_y = min(yy);
max_z = max(zz); min_z = min(zz);
xi = min_x:abs(stepSize):max_x;
yi = min_y:abs(stepSize):max_y;
zi = min_z:abs(stepSize):max_z;
[qx,qy] = meshgrid(xi,yi);
qz = F(qx,qy);
F = TriScatteredInterp(xx,yy,C);
qc = F(qx,qy);
figure
surf(qx,qy,qz,qc);
axis image
This works really well for convex and concave objects but ends in this for the cylinder:
Can anybody help me as to how to achieve a nicer plot?
Have you tried Delaunay triangulation?
http://www.mathworks.com/help/matlab/ref/delaunay.html
load seamount
tri = delaunay(x,y);
trisurf(tri,x,y,z);
There is also TriScatteredInterp
http://www.mathworks.com/help/matlab/ref/triscatteredinterp.html
ti = -2:.25:2;
[qx,qy] = meshgrid(ti,ti);
qz = F(qx,qy);
mesh(qx,qy,qz);
hold on;
plot3(x,y,z,'o');
I think what you are loking for is the Convex hull function. See its documentation.
K = convhull(X,Y,Z) returns the 3-D convex hull of the points (X,Y,Z),
where X, Y, and Z are column vectors. K is a triangulation
representing the boundary of the convex hull. K is of size mtri-by-3,
where mtri is the number of triangular facets. That is, each row of K
is a triangle defined in terms of the point indices.
Example in 2D
xx = -1:.05:1; yy = abs(sqrt(xx));
[x,y] = pol2cart(xx,yy);
k = convhull(x,y);
plot(x(k),y(k),'r-',x,y,'b+')
Use plot to plot the output of convhull in 2-D. Use trisurf or trimesh to plot the output of convhull in 3-D.
A cylinder is the collection of all points equidistant to a line. So you know that your xx, yy and zz data have one thing in common, and that is that they all should lie at an equal distance to the line of symmetry. You can use that to generate a new cylinder (line of symmetry taken to be z-axis in this example):
% best-fitting radius
% NOTE: only works if z-axis is cylinder's line of symmetry
R = mean( sqrt(xx.^2+yy.^2) );
% generate some cylinder
[x y z] = cylinder(ones(numel(xx),1));
% adjust z-range and set best-fitting radius
z = z * (max(zz(:))-min(zz(:))) + min(zz(:));
x=x*R;
y=y*R;
% plot cylinder
surf(x,y,z)
TriScatteredInterp is good for fitting 2D surfaces of the form z = f(x,y), where f is a single-valued function. It won't work to fit a point cloud like you have.
Since you're dealing with a cylinder, which is, in essence, a 2D surface, you can still use TriScatterdInterp if you convert to polar coordinates, and, say, fit radius as a function of angle and height--something like:
% convert to polar coordinates:
theta = atan2(yy,xx);
h = zz;
r = sqrt(xx.^2+yy.^2);
% fit radius as a function of theta and h
RFit = TriScatteredInterp(theta(:),h(:),r(:));
% define interpolation points
stepSize = 0.1;
ti = min(theta):abs(stepSize):max(theta);
hi = min(h):abs(stepSize):max(h);
[qx,qy] = meshgrid(ti,hi);
% find r values at points:
rfit = reshape(RFit(qx(:),qy(:)),size(qx));
% plot
surf(rfit.*cos(qx),rfit.*sin(qx),qy)
I am trying to implement the generalized Hough transform as presented in this paper in MATLAB. I've also tried using this document to understand the algorithm. I am stuck on figuring out how to calculate the gradient angle to find Φ to use in the R-Table.
I have tried to run this matlab implementation, but the contour function tries to access negative indices. The missing functions are below.
distance.m
function [ d ] = distance( x1, y1, x2, y2 )
d = sqrt( (x2-x1)^2 + (y2-y1)^2 );
end
barycenter.m
function [ xo, yo ] = barycenter( img )
% gravitational center coordinates of a shape
[rows, cols] = size(img);
x = ones(rows, 1)*(1:cols);
y = (1:rows)'*ones(1,cols);
area = sum(sum(img));
xo = sum(sum(double(img) .* x)) / area;
yo = sum(sum(double(img) .* y)) / area;
end
modelHough.m
function [H]=ModelHough(imgRGB)
% Generalized Hough Transform Modeling
% Image Binarization
imgBW = rgb2gray(imgRGB);
imgBI = imgBW < 255;
% Retrieving information about the contour: points and number (N)
N = contour(imgBI);
% Model initialization:
% row = beta value * 100
% column = number of the couple (alpha, distance)
% 3rd dimension: 1 = alpha, 2 = distance
H=zeros(round(100*2*pi),N,2);
% Compute of the barycenter coordinates
[ xo, yo ] = barycenter(imgBI);
% for each contour point
for i=1:N
% beta compute for ith contour point
b = beta(N, imgBI, i);
% research of the first column
k=1;
while H(b+1,k,2)~=0
k=k+1;
end
% compute of the alpha value
H(b+1, k, 1) = alpha(N, i, imgBI);
% compute of the distance value
H(b+1, k, 2) = distance( xo, yo, i, b );
end
Use a suitable edge detector. You could start off with the Sobel operator. The gradient angle is atan(Gy/Gx) as described in the wiki article.
If you use a common edge detector for detecting edges you should change countor.m on row 14 to something like below:
while (img(i,j)~=1)
How do I draw an ellipse and an ellipsoid using MATLAB?
(x^2/a^2)+(y^2/b^2)=1
n=40;
a=0; b=2*pi;
c=0; d=2*pi;
for i=1:n
u=a+(b-a)*(i-1)/(n-1);
for j=1:m
v=a+(d-c)*(j-1)/(m-1);
x(i,j)=sin(u)*cos(v);
y(i,j)=sin(u)*sin(v);
z(i,j)=cos(u);
end
end
mesh(x,y,z);
But I want the shape?
Ellipse article on Wikipedia had a simple JavaScript code to draw ellipses.
It uses the parametric form:
x(theta) = a0 + ax*sin(theta) + bx*cos(theta)
y(theta) = b0 + ay*sin(theta) + by*cos(theta)
where
(a0,b0) is the center of the ellipse
(ax,ay) vector representing the major axis
(bx,by) vector representing the minor axis
I translated the code into a MATLAB function:
calculateEllipse.m
function [X,Y] = calculateEllipse(x, y, a, b, angle, steps)
%# This functions returns points to draw an ellipse
%#
%# #param x X coordinate
%# #param y Y coordinate
%# #param a Semimajor axis
%# #param b Semiminor axis
%# #param angle Angle of the ellipse (in degrees)
%#
narginchk(5, 6);
if nargin<6, steps = 36; end
beta = -angle * (pi / 180);
sinbeta = sin(beta);
cosbeta = cos(beta);
alpha = linspace(0, 360, steps)' .* (pi / 180);
sinalpha = sin(alpha);
cosalpha = cos(alpha);
X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta);
Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta);
if nargout==1, X = [X Y]; end
end
and an example to test it:
%# ellipse centered at (0,0) with axes length
%# major=20, ,minor=10, rotated 50 degrees
%# (drawn using the default N=36 points)
p = calculateEllipse(0, 0, 20, 10, 50);
plot(p(:,1), p(:,2), '.-'), axis equal
The answers from Jacob and Amro are very good examples for computing and plotting points for an ellipse. I'll address some easy ways you can plot an ellipsoid...
First, MATLAB has a built-in function ELLIPSOID which generates a set of mesh points given the ellipsoid center and the semi-axis lengths. The following creates the matrices x, y, and z for an ellipsoid centered at the origin with semi-axis lengths of 4, 2, and 1 for the x, y, and z directions, respectively:
[x, y, z] = ellipsoid(0, 0, 0, 4, 2, 1);
You can then use the function MESH to plot it, returning a handle to the plotted surface object:
hMesh = mesh(x, y, z);
If you want to rotate the plotted ellipsoid, you can use the ROTATE function. The following applies a rotation of 45 degrees around the y-axis:
rotate(hMesh, [0 1 0], 45);
You can then adjust the plot appearance to get the following figure:
axis equal; %# Make tick mark increments on all axes equal
view([-36 18]); %# Change the camera viewpoint
xlabel('x');
ylabel('y');
zlabel('z');
Also, if you want to use the rotated plot points for further calculations, you can get them from the plotted surface object:
xNew = get(hMesh, 'XData'); %# Get the rotated x points
yNew = get(hMesh, 'YData'); %# Get the rotated y points
zNew = get(hMesh, 'ZData'); %# Get the rotated z points
I've adapted this excellent ellipse plotting script from MATLAB Central for your requirement of
function plotEllipse(a,b,C)
% range to plot over
%------------------------------------
N = 50;
theta = 0:1/N:2*pi+1/N;
% Parametric equation of the ellipse
%----------------------------------------
state(1,:) = a*cos(theta);
state(2,:) = b*sin(theta);
% Coordinate transform (since your ellipse is axis aligned)
%----------------------------------------
X = state;
X(1,:) = X(1,:) + C(1);
X(2,:) = X(2,:) + C(2);
% Plot
%----------------------------------------
plot(X(1,:),X(2,:));
hold on;
plot(C(1),C(2),'r*');
axis equal;
grid;
end
Note: change N to define the resolution of your ellipse
Here's an ellipse centered at (10,10) with a = 30 and b = 10
Ellipse article on Wikipedia and Rotation matrix.
Rewrite that functions:
rotate by rotAngle counter-clockwise around (0,0)
Coordinate transform to (cx, cy)
function [X,Y] = calculateEllipse(cx, cy, a, b, rotAngle)
%# This functions returns points to draw an ellipse
%#
%# #param x X coordinate
%# #param y Y coordinate
%# #param a Semimajor axis
%# #param b Semiminor axis
%# #param cx cetner x position
%# #param cy cetner y position
%# #param angle Angle of the ellipse (in degrees)
%#
steps = 30;
angle = linspace(0, 2*pi, steps);
% Parametric equation of the ellipse
X = a * cos(angle);
Y = b * sin(angle);
% rotate by rotAngle counter clockwise around (0,0)
xRot = X*cosd(rotAngle) - Y*sind(rotAngle);
yRot = X*sind(rotAngle) + Y*cosd(rotAngle);
X = xRot;
Y = yRot;
% Coordinate transform
X = X + cx;
Y = Y + cy;
end
and an example to test it:
[X,Y] = calculateEllipse(0, 0, 20, 10, 0);
plot(X, Y, 'b'); hold on; % blue
[X,Y] = calculateEllipse(0, 0, 20, 10, 45);
plot(X, Y, 'r'); hold on; % red
[X,Y] = calculateEllipse(30, 30, 20, 10, 135);
plot(X, Y, 'g'); % green
grid on;
Create two vectors, one of the x-coordinates of the points of the circumference of the ellipsoid, one of the y-coordinates. Make these vectors long enough to satisfy your accuracy requirements. Plot the two vectors as (x,y) pairs joined up. I'd drop the for loops from your code, much clearer if you use vector notation. Also I'd format your question using the SO markup for code to make it all clearer to your audience.
The simplest way might be to use the Matlab function
pdeellip(xc,yc,a,b,phi)
For example:
pdeellip(0,0,1,0.3,pi/4)
However, this is simple solution is good to have a quick glance how the ellipse looks like. If you want to have a nice plot, look at the other solutions.
I don't know in which version of Matlab this was added, but it's available at least from version R2012b on.