如何在Maple中固定动画的两个斜边界?若不行如何用Matlab实现?
Hey there! Let's break down how to fix those two converging edges in your 3D animation—first in Maple, then in MATLAB if you need an alternative.
Fixing the Edges in Maple
Your original code creates a surface where the y-bounds slope inward between x=0 and x=2, converging at x=2. To keep those sloped edges fixed while the rest of the surface animates, we can draw those edges as separate static curves and layer them on top of the animated surface.
Here's the modified code:
with(plots): with(plottools): # Draw the fixed upper sloped edge (x from 0 to 2, y = 1/2 + x/4) # We'll set z=0 here, but you can replace this with the initial frame's z-value if you prefer upper_fixed_edge := spacecurve([x, 1/2 + x/4, 0], x=0..2, color=red, thickness=3): # Draw the fixed lower sloped edge (x from 0 to 2, y = 1/2 - x/4) lower_fixed_edge := spacecurve([x, 1/2 - x/4, 0], x=0..2, color=blue, thickness=3): # Create the animated surface as before animated_surface := animate(plot3d, [ sin(Pi*(t-x))*sin(Pi*y)*Heaviside(t-x) - sin(Pi*(t+x))*sin(Pi*y)*Heaviside(t+x), x=0..4, y=piecewise(x>=0 and x<2, 1/2-x/4, 0)..piecewise(x>=0 and x<2, 1/2+x/4, 1) ], t=-2*Pi..2*Pi, frames=90): # Combine the animation and fixed edges so they show up together display(animated_surface, upper_fixed_edge, lower_fixed_edge, axes=boxed);
Quick tweak if you want edges to match the initial frame:
If you don't want the edges to sit at z=0, replace the 0 in the spacecurve z-values with the function's value at your starting time (e.g., t=-2π):
initial_t := -2*Pi; upper_z := sin(Pi*(initial_t - x))*sin(Pi*(1/2 + x/4))*Heaviside(initial_t - x) - sin(Pi*(initial_t + x))*sin(Pi*(1/2 + x/4))*Heaviside(initial_t + x): upper_fixed_edge := spacecurve([x, 1/2 + x/4, upper_z], x=0..2, color=red, thickness=3):
Do the same for the lower edge, swapping 1/2 + x/4 with 1/2 - x/4.
Fixing the Edges in MATLAB
If Maple isn't working out for you, MATLAB handles this just as easily. The idea is to draw the fixed edges first, then update the surface frame by frame while keeping those edges visible.
Here's the full implementation:
% Define parameter ranges x = linspace(0, 4, 100); t = linspace(-2*pi, 2*pi, 90); % Define the y-bounds for the surface y_upper = @(x_val) piecewise(x_val >= 0 & x_val < 2, 0.5 + x_val/4, 1); y_lower = @(x_val) piecewise(x_val >= 0 & x_val < 2, 0.5 - x_val/4, 0); % Create coordinates for the fixed sloped edges x_edge = linspace(0, 2, 50); y_upper_edge = 0.5 + x_edge/4; y_lower_edge = 0.5 - x_edge/4; % Set z to 0, or replace with initial frame values (see note below) z_upper_edge = zeros(size(x_edge)); z_lower_edge = zeros(size(x_edge)); % Set up the figure figure; hold on; axis([0 4 0 1 -2 2]); % Adjust bounds based on your function's range grid on; xlabel('x'); ylabel('y'); zlabel('z'); % Plot the fixed edges first (they won't change during animation) plot3(x_edge, y_upper_edge, z_upper_edge, 'r-', 'LineWidth', 3); plot3(x_edge, y_lower_edge, z_lower_edge, 'b-', 'LineWidth', 3); % Initialize the surface object surf_handle = surf([], [], []); shading interp; % Custom heaviside function if you don't have the Symbolic Math Toolbox heaviside = @(val) (val >= 0) + 0; % Loop through each frame to update the surface for frame_idx = 1:length(t) current_t = t(frame_idx); % Create a grid of x and y values [X, Y] = meshgrid(x, linspace(0, 1, 50)); % Calculate the z-values for the surface Z = sin(pi*(current_t - X)).*sin(pi*Y).*heaviside(current_t - X) ... - sin(pi*(current_t + X)).*sin(pi*Y).*heaviside(current_t + X); % Filter out points outside the y-bounds for each x for x_idx = 1:length(x) yl = y_lower(x(x_idx)); yu = y_upper(x(x_idx)); Z(Y(:, x_idx) < yl | Y(:, x_idx) > yu, x_idx) = NaN; end % Update the surface with new frame data set(surf_handle, 'XData', X, 'YData', Y, 'ZData', Z); drawnow; end
Note on matching initial frame z-values:
To make the fixed edges match the surface's starting state, calculate their z-values at t=-2π instead of using zeros:
initial_t = -2*pi; z_upper_edge = sin(pi*(initial_t - x_edge)).*sin(pi*y_upper_edge).*heaviside(initial_t - x_edge) ... - sin(pi*(initial_t + x_edge)).*sin(pi*y_upper_edge).*heaviside(initial_t + x_edge); z_lower_edge = sin(pi*(initial_t - x_edge)).*sin(pi*y_lower_edge).*heaviside(initial_t - x_edge) ... - sin(pi*(initial_t + x_edge)).*sin(pi*y_lower_edge).*heaviside(initial_t + x_edge);
内容的提问来源于stack exchange,提问作者Jerry

