I need to plot this function
theta = (-pi:0.01:pi);
f = 3*10^9;
c = 299792458;
da = 2;
Here's my code, but I'm not sure it's correct. I dont know where exactly dot mark should be. How to set X-Axis in degress?
beta = (2*pi*f)/c;
const= (da*beta)/2;
j= (cos(theta)+1).*(besselj(1,const*sin(theta))./(const*sin(theta)));
My another question is how to plot this function in polar coordinates.
I made something like this.
polar(theta,j);
Is it possible to rotate that function(by y-axis) to get 3D plot?
Things are quite right to me, although I wouldn't use the symbol j as a variable because (as i does) it is the symbol for the imaginary unit (sqrt(-1)). Doing so you are overriding it, thus things will work until you don't need complex numbers.
You should use element-wise operations such as (.*) when you aim at combining arrays entries element by element, as you correctly did to obtain F(\theta). In fact, cos(theta) is the array of the cosines of the angles contained in theta and so on.
Finally, you can rotate the plot using the command Rotate 3D in the plot window. Nonetheless, you have a 2D curve (F(\theta)) therefore, you will keep on rotating a 2D graph obtaining some kind of perspective view of it, nothing more. To obtain genuine information you need an additional dependent variable (Or I misunderstood your question?).
EDIT: Now I see your point, you want the Surface of revolution around some axis, which I suppose by virtue of the symmetry therein to be theta=0. Well, revolution surfaces can be obtained by a bit of analytic geometry and plotted e.g. by using mesh. Check this out:
% // 2D polar coordinate radius (your j)
Rad= (cos(theta)+1).*(besselj(1,const*sin(theta))./(const*sin(theta)));
Rad = abs(Rad); % // We need its absolute value for sake of clarity
xv = Rad .* cos(theta); % // 2D Cartesian coordinates
yv = Rad .* sin(theta); % // 2D Cartesian coordinates
phi = -pi:.01:pi; % // 3D revolution angle around theta = 0
% // 3D points of the surface
xf = repmat(xv',size(phi));
yf = yv' * cos(phi);
zf = yv' * sin(phi);
mesh(xf,yf,zf)
You can also add graphics effects
this is done via
mesh(xf,yf,zf,'FaceColor','interp','FaceLighting','phong')
camlight right
and a finer angular discretization (1e-3).
Related
I have made a function that allows a user to draw several points and interpolate those points. I want the function to calculate the centre of mass using this vector :
I think I should therefore first calculate the area of the figure (I drew this example to illustrate the function output). I want to do this using Green's theorem
However since I'm quite a beginner in MATLAB I'm stuck at how to implement this formula in order to find the centre of mass. I'm also not sure how to get the data as my output so far is only the x- and y cordinates of the points.
function draw
fig = figure();
hax = axes('Parent', fig);
axis(hax, 'manual')
[x,y] = getpts();
M = [x y]
T = cumsum(sqrt([0,diff(x')].^2 + [0,diff(y')].^2));
T_i = linspace(T(1),T(end),1000);
X_i = interp1(T,x',T_i,'cubic');
Y_i = interp1(T,y',T_i,'cubic');
plot(x,y,'b.',X_i,Y_i,'r-')
end
The Center Of Mass for a 2D coordinate system should just be the mean of the interpolated x-coordinates and y-coordinates. The Interpolation should give you evenly spaced coordinates which you can use to your advantage. So simply add to your existing function:
CenterOfMass= [mean(X_i),mean(Y_i)]
plot(x,y,'b.',X_i,Y_i,'r-')
hold on
plot(CenterOfMass(1),CenterOfMass(2),'ro')
should give you the center of mass assuming that all points are weighted equally.
I have a set of points in 3D in cartesian coordinates X,Y,Z. To every such point I associate a value which is stored in a vector C. I want to be able to colour the surface given by X,Y,Z with colors given by C. Alternatively, if possible, I would like to associate to each point a color from a finite number of given colors. In Matlab this is possible with surf(X,Y,Z,C), but X,Y must be in grid form (generated by meshgrid), not in general form, like in my case.
I managed to do this in the case of the sphere, but the procedure is not pretty, and it uses heavily the parametrization of the sphere. Here's an example of what I want to do (in the case of the sphere).
Is there a way to do this type of surface coloring in Matlab? (if it helps, I can also provide a triangulation of the surfaces in addition to the points X,Y,Z)
Is there another piece of software which can do similar things and can interface in some way with Matlab?
I based this off of Matlab's Representing Data as a Surface. Does this work?
xlin = linspace(min(x),max(x),33);
ylin = linspace(min(y),max(y),33);
[X,Y] = meshgrid(xlin,ylin);
f = scatteredInterpolant(x,y,z);
Z = f(X,Y);
g = scatteredInterpolant(x,y,c);
C = g(X,Y);
surf(X, Y, Z, C)
Thanks Ander Biguri for suggesting patch. Here's what I've come up with, and it seems to work fine.
function patch_color_plot(struc)
% struc is a structure containing at least the following:
% points - the coordinate of the points in a 3xN matrix
% t - the triangulation matrix
% x_0s - the point values
fac = struc.t;
vert = struc.points;
fvc = struc.x_0s;
p = patch('Faces',fac,'Vertices',vert,'FaceVertexCData',...
fvc,'FaceColor','interp');
set(p,'EdgeColor','none')
axis equal
axis off`
Here's a sample result:
and another one with a torus:
here's another example:
I have the probelm connected with vector field on sphere. I have six 2d arrays: first three for coordinates and second three for vector components.
I need to draw streamlines of this vector field on sphere. I have tried streamlines and streamslice, but they dont support spherical surfacec. Do you have any suggestions how I can plost streamlines of this vector field?
First define the flow arena with meshgrid. This creates a 3D array of points at which the velocity magnitudes and directions can be calculated.
[x,y,z] = meshgrid(-1.01:0.02:1.01,-1.01:0.02:1.01,-1.01:0.02:1.01);
Define your flow parameters.
U = 1; % x-wise free stream velocity
a = 0.5; % sphere radius
mu = -2*pi*a^3*U; % doublet strength required to create spherical streamlines
The x,y,z velocity components for an x-wise (streamwise) doublet superimposed with an x-direction flow is:
ux = U+mu.*(2.*x.^2-y.^2-z.^2)./(4*pi.*(x.^2+y.^2+z.^2).^(5/2));
uy = 3*mu.*x.*y./(4*pi.*(x.^2+y.^2+z.^2).^(5/2));
uz = 3*mu.*x.*z./(4*pi.*(x.^2+y.^2+z.^2).^(5/2));
The start point of the streamlines needs to be defined. For this case a small 2D mesh of points on the upstream side of the flow field centred around the stagnation streamline is a good choice.
[startx, starty, startz] = meshgrid(-1,-0.1:0.02:0.1,-0.1:0.02:0.1);
Generate the streamline plot.
streamline(x,y,z,ux,uy,uz,startx,starty,startz)
The result looks a bit like an onion but represents the 3D potential flow around a sphere.
I have generated a rectangular matrix with the azimouth angle changing with rows and the radius changing as you change column. These are meant to represent the relative velocities experienced by a rotating helicopter blade. This produces a matrix called Vmat. I want to plot this to appears in a circle (representing the rotation of the blade)
So far I have tried
[R,T] = meshgrid(r,az);
[x,y] = pol2cart(T,R);
surf(x,y,Vmat(r,az));
which should produce a contoured surface showing velocity as it changes with azimouth angle and radius but it comes up with dimension errors.
I don't mind if it is a 2d contour plot or 3d plot i guess both would be written in a similar way.
Thanks
James
The error is in writing Vmat(r,az), presuming that these are actual values of radius and azimuth, not indexes into your radius and azimuth. If you want to take only a subset of Vmat that's a slightly different matter, but this should work:
[R,T] = meshgrid(r,az); % creates a grid in polar coordinates
[x,y] = pol2cart(T,R); % changes those to cartesian for surf
surf(x,y,Vmat);
Alternatively you could do a contour plot:
h = polar([0 2*pi], [0 max(r)]); % set up polar axes with right scale
delete(h) % remove line
hold on
contour(x,y,Vmat);
I am using ray tracing and at the beginning I assumed a plane surface so I used the equation of the plane surface which is :
Ax + BY + CZ +d = 0
while A,B and C are the component of the normal vector of the Plane Normal = [A B C]
and using the Ray equation : Ray = Source + t*Direction
And then solve it for t and I can find the intersection points.
My question now that I have function in matlab to read the surface of the object but the object may not be plane surface and I am getting the data of the surface [X Y Z] of the surface but I don't know which equation should I use to find t and then the intersection point. And I even have a function to give me the normal vector at each point
If you can edit the tags the get the right ones please do it.
It might not be a plane, but you can always calculate a normal vector at each point. You'll just have to work harder to do it. Take two partial derivatives in planar coordinates, cross those vectors, and that's the normal at the point.
If your surface is defined as a height Z on a some X-Y grid, you can solve it easily using fzero. This would exclude some complex shapes, but might work for standard optics problems like a ray hitting a lens. Assume that X, Y and Z are 2-d matrices with the same shape. You can then do a 2d interpolation like
z_interp = interp2(X,Y,Z,x_interp,y_interp)
If this is not the case, you should try to define your own function that can calculate z based on x and y.
For the line, we have
x_ray = x_source + t * x_dir
y_ray = y_source + t * y_dir
z_ray = z_source + t * z_dir
So you can now define a function that calculates the height above the surface as a function of t as
height_above_plane = #(t) z_source + t * z_dir - interp2(X, Y, Z, ...
x_source + t*x_dir, y_source + t*y_dir)
Note that this might not be the shortest distance from the point to the plane, it is just the height measured along the z-direction. The time the ray hits the surface can now be found by searching for the t for which the height is zero. This can be done for arbitrary functions using fzero:
t_intercept = fzero(height_above_plane, 0);
This should work well for simple cases where the function defining the surface is relatively smooth and the ray crosses the surface only once. It might be possible to transform cases with more complex geometry into such a simple case.
If you can get the X Y Z of the surface and you said you can get the normal vector in each point so what is your problem now?
The X Y Z of the surface are the intersection points and if you have the normal vector in each point so you can calculate whatever you want ( the reflected or the refracted rays).
I think you have no troubles at all