I have a problem which is twofold:
How do I plot a toroidal surface in MATLAB, given a major radius R and a minor radius a? To avoid confusion, it is the toroidal/poloidal coordinate system, illustrated in the picture below, that I'm talking about.
Now, in any point (phi, theta) on this surface, the minor radius will be distorted by some value that I have stored in a matrix. How do I plot this distorted surface? This might be easy once I have the answer to part 1, but this is my actual goal, so any solution to part 1 that cannot handle this is pretty useless to me.
If anyone can tell me how to make the image appear smaller here, please do =)
Addressing your first question: first you will need to define the coordinates of your torus in toroidal coordinates (seems natural!) and then convert to Cartesian coordinates, which is how MATLAB expects all plots to be constructed (unless you are making a polar plot, of course). So we start of by defining our toroidal coordinates:
aminor = 1.; % Torus minor radius
Rmajor = 3.; % Torus major radius
theta = linspace(-pi, pi, 64) ; % Poloidal angle
phi = linspace(0., 2.*pi, 64) ; % Toroidal angle
We just want a single surface of the torus, so the minor radius is a scalar. We now make a 2D mesh of these coordinates:
[t, p] = meshgrid(phi, theta);
and convert to 3D Cartesian coordinates using the formulas given on the Wikipedia page linked to in the question:
x = (Rmajor + aminor.*cos(p)) .* cos(t);
y = (Rmajor + aminor.*cos(p)) .* sin(t);
z = aminor.*sin(p);
Now we have our torus defined in 3D, we can plot it using surf
:
surf(x, y, z)
axis equal
Edit: To address your second question, it depends how you have your distortions stored, but say you have a matrix defined at each toroidal and poloidal point, you will just have to multiply the constant that is the minor radius by the distortion. In the following I create a distortion matrix that is the same dimensions as my toroidal and poloidal angle coordinate matrices and that is normally distributed about a mean of 1 with a FWHM of 0.1:
distortion = 1. + 0.1 * randn(64, 64);
x = (Rmajor + aminor .* distortion .*cos(p)) .* cos(t);
y = (Rmajor + aminor .* distortion .* cos(p)) .* sin(t);
z = aminor.* distortion .* sin(p);
surf(x, y, z)
The result of which is:
You can do this with surf
- just create matrices with the x,y,z coordinates. The page you linked to has the trig equations to do this (they are exactly what you'd come up with on your own - I wrote the code below before checking your link).
R = 10;
a = 3;
tx=nan(41,21);
ty=nan(41,21);
tz=nan(41,21);
for j=1:21
for i=1:41
phi = (i-1)*2*pi/40;
theta = (j-1)*2*pi/20;
tx(i,j)= cos(phi) * (R+cos(theta)*a);
ty(i,j)= sin(phi) * (R+cos(theta)*a);
tz(i,j)= sin(theta)*a;
end
end
figure
surf(tx,ty,tz)
axis equal
To distort the surface, replace the constant a
with a matrix of the desired minor radius values, and index into that matrix - i.e. tz(i,j) = sin(theta)*distortion(i,j)
(but in all dimensions, obviously).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With