3D logaritmic spirals on surface

17 views (last 30 days)
Pseudoscientist
Pseudoscientist on 29 Mar 2023
Edited: Walter Roberson on 30 Mar 2023
I'm attempting to plot twelve equally spaced 3D logaritmic spirals that start from the circumfrence of my surface and then converge to the tip of the surface. The surface is plotted followingly:
function plot_rotated_curve()
% Curve y = 1/x
curve_func = @(x) 1./x;
x_min = 1/3;
x_max = 3;
n_points = 100;
x_values = linspace(x_min, x_max, n_points);
y_values = curve_func(x_values);
% Create 3D surface
[X, Y, Z] = create_rotated_surface(x_values, y_values, x_min);
% Plot surface
surf(X, Y, Z);
xlabel('X');
ylabel('Y');
zlabel('Z');
hold on;
axis equal;
end
function [X, Y, Z] = create_rotated_surface(x_values, y_values, x_rotation)
theta = linspace(0, 2*pi, numel(x_values));
[R, ~] = meshgrid(x_values - x_rotation, theta);
[Y_values, T] = meshgrid(y_values, theta);
X = R .* cos(T) + x_rotation;
Y = R .* sin(T);
Z = Y_values;
end
I have another function to plot spirals but I cant quite get them to work together..
function plot_logarithmic_spirals()
n_spirals = 12;
circle_radius = 3;
convergence_point = [0, 0, 10]; % Adjust this value to change the convergence point
n_points = 100;
figure;
hold on;
for i = 1:n_spirals
start_angle = (i - 1) * (360 / n_spirals);
[x, y, z] = logarithmic_spiral_3d(circle_radius, start_angle, convergence_point, n_points);
plot3(x, y, z, 'LineWidth', 2);
end
hold off;
axis equal;
end
function [x, y, z] = logarithmic_spiral_3d(radius, start_angle, convergence_point, n_points)
% Calculate the starting point on the circle
start_x = radius * cosd(start_angle);
start_y = radius * sind(start_angle);
start_z = 0;
% Calculate the t parameter for the spiral
t = linspace(0, 1, n_points);
% Calculate the logarithmic spiral in the xy-plane
growth_factor = 3; % Adjust this value to control the tightness of the spirals
r = radius * exp(-growth_factor * t);
theta = start_angle + 2 * pi * t;
x = r .* cos(theta);
y = r .* sin(theta);
% Project the xy-plane logarithmic spiral onto the 3D space
line_vector = convergence_point - [start_x, start_y, start_z];
z = start_z + t * line_vector(3);
end

Answers (3)

Jack
Jack on 29 Mar 2023
Hi,
To plot twelve equally spaced 3D logarithmic spirals that start from the circumference of the surface and converge to the tip, you can modify the plot_rotated_curve function to call the logarithmic_spiral_3d function and plot the spirals along the surface.
Here's an example implementation of the modified plot_rotated_curve function:
function plot_rotated_curve()
% Curve y = 1/x
curve_func = @(x) 1./x;
x_min = 1/3;
x_max = 3;
n_points = 100;
x_values = linspace(x_min, x_max, n_points);
y_values = curve_func(x_values);
% Create 3D surface
[X, Y, Z] = create_rotated_surface(x_values, y_values, x_min);
% Plot surface
surf(X, Y, Z);
xlabel('X');
ylabel('Y');
zlabel('Z');
hold on;
% Plot logarithmic spirals
n_spirals = 12;
circle_radius = 3;
convergence_point = [0, 0, max(y_values)]; % Converge to the tip of the surface
n_points = 100;
for i = 1:n_spirals
start_angle = (i - 1) * (360 / n_spirals);
[x, y, z] = logarithmic_spiral_3d(circle_radius, start_angle, convergence_point, n_points);
% Shift spiral along surface
[u, v] = pol2cart(deg2rad(start_angle), circle_radius);
u = u + x_min;
v = v + curve_func(u);
[X_spiral, Y_spiral, Z_spiral] = create_rotated_surface(u, v, x_min);
plot3(X_spiral, Y_spiral, Z_spiral, 'LineWidth', 2);
end
hold off;
axis equal;
end
In this modified function, we first plot the surface using the create_rotated_surface function as before. Then, we define the parameters for the logarithmic spirals, including the number of spirals, the circle radius, and the convergence point. We set the convergence point to the maximum y value of the surface, so the spirals converge to the tip of the surface.
We then loop over the number of spirals and calculate the starting angle for each spiral. We call the logarithmic_spiral_3d function to calculate the coordinates for the spiral, and then shift the spiral along the surface using the create_rotated_surface function. Finally, we plot the spiral along the surface using the plot3 function.
Note that in this implementation, we assume that the curve function curve_func defines the surface such that the y values increase monotonically along the x axis. If this is not the case, you may need to modify the shift calculation to correctly position the spirals along the surface.

Pseudoscientist
Pseudoscientist on 29 Mar 2023
Do you mean like this? I dont quite understand, for example [x, y, z] = logarithmic_spiral_3d() are unused
function plot_rotated_curve()
% Curve y = 1/x
curve_func = @(x) 1./x;
x_min = 1/3;
x_max = 3;
n_points = 100;
x_values = linspace(x_min, x_max, n_points);
y_values = curve_func(x_values);
% Create 3D surface
[X, Y, Z] = create_rotated_surface(x_values, y_values, x_min);
% Plot surface
surf(X, Y, Z);
xlabel('X');
ylabel('Y');
zlabel('Z');
hold on;
% Plot logarithmic spirals
n_spirals = 12;
circle_radius = 3;
convergence_point = [0, 0, max(y_values)]; % Converge to the tip of the surface
n_points = 100;
for i = 1:n_spirals
start_angle = (i - 1) * (360 / n_spirals);
[x, y, z] = logarithmic_spiral_3d(circle_radius, start_angle, convergence_point, n_points);
% Shift spiral along surface
[u, v] = pol2cart(deg2rad(start_angle), circle_radius);
u = u + x_min;
v = v + curve_func(u);
[X_spiral, Y_spiral, Z_spiral] = create_rotated_surface(u, v, x_min);
plot3(X_spiral, Y_spiral, Z_spiral, 'LineWidth', 2);
end
hold off;
axis equal;
function [X, Y, Z] = create_rotated_surface(x_values, y_values, x_rotation)
theta = linspace(0, 2*pi, numel(x_values));
[R, ~] = meshgrid(x_values - x_rotation, theta);
[Y_values, T] = meshgrid(y_values, theta);
X = R .* cos(T) + x_rotation;
Y = R .* sin(T);
Z = Y_values;
end
function [x, y, z] = logarithmic_spiral_3d(radius, start_angle, convergence_point, n_points)
% Calculate the starting point on the circle
start_x = radius * cosd(start_angle);
start_y = radius * sind(start_angle);
start_z = 0;
% Calculate the t parameter for the spiral
t = linspace(0, 1, n_points);
% Calculate the logarithmic spiral in the xy-plane
growth_factor = 3; % Adjust this value to control the tightness of the spirals
r = radius * exp(-growth_factor * t);
theta = start_angle + 2 * pi * t;
x = r .* cos(theta);
y = r .* sin(theta);
% Project the xy-plane logarithmic spiral onto the 3D space
line_vector = convergence_point - [start_x, start_y, start_z];
z = start_z + t * line_vector(3);
end
end
  2 Comments
Jack
Jack on 30 Mar 2023
Yes, exactly. In the code you provided, the variables x, y, and z are not used in the logarithmic_spiral_3d function. You can remove them and adjust the function signature accordingly, like this:
function [x_values, y_values, z_values] = logarithmic_spiral_3d(radius, start_angle, convergence_point, n_points)
This way, the function will return the values of x, y, and z as x_values, y_values, and z_values, respectively, which can then be used in the plot_rotated_curve function as follows:
[x, y, z] = logarithmic_spiral_3d(circle_radius, start_angle, convergence_point, n_points);
[u, v, w] = create_rotated_surface(x, y, x_min);
plot3(u, v, w, 'LineWidth', 2);

Sign in to comment.


Pseudoscientist
Pseudoscientist on 30 Mar 2023
I have made some progress:
function plot_spiral_on_surface()
% Curve y = 1/x
curve_func = @(x) 1./x;
x_min = 1/3;
x_max = 3;
n_points = 100;
x_values = linspace(x_min, x_max, n_points);
y_values = curve_func(x_values);
% Create 3D surface
[X, Y, Z] = create_rotated_surface(x_values, y_values, x_min);
% Add spiral to surface
spiral_turns = 3; % number of turns of the spiral
spiral_base_radius = x_min; % radius of the spiral at the base
spiral_top_radius = x_max; % radius of the spiral at the top
spiral_height = max(y_values); % height of the spiral
spiral_pitch = spiral_height / (spiral_turns * 2*pi); % pitch of the spiral
spiral_theta = linspace(0, spiral_turns*2*pi, 500);
spiral_radius = spiral_base_radius * exp(spiral_theta / (spiral_turns*2*pi) * log(spiral_top_radius / spiral_base_radius));
spiral_x = spiral_radius .* cos(spiral_theta);
spiral_y = spiral_radius .* sin(spiral_theta);
spiral_z = max(Z(:)) - (spiral_theta / (2*pi) * spiral_pitch); % compute spiral z values
% Plot surface and spiral
hold on;
surf(X, Y, Z);
plot3(spiral_x, spiral_y, spiral_z, 'r', 'LineWidth', 2);
xlabel('X');
ylabel('Y');
zlabel('Z');
axis equal;
end
function [X, Y, Z] = create_rotated_surface(x_values, y_values, x_rotation)
theta = linspace(0, 2*pi, numel(x_values));
[R, ~] = meshgrid(x_values - x_rotation, theta);
[Y_values, T] = meshgrid(y_values, theta);
X = R .* cos(T) + x_rotation;
Y = R .* sin(T);
Z = Y_values;
end

Community Treasure Hunt

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

Start Hunting!