【微实验】圆周运动的正弦信号发生仿真及其衍生(三)

叠甲,微实验系列主要是笔者以MATLAB为主要工具,多使用AI编写代码,对数字音频信号进行各种操作的尝试、以及对声音信号的频域与时域特征性质进行的各种探索,日志性较强,教程性较低,相对于笔者所写得【手把手】和【超详细】教程或者科普系列来说更加粗糙随意,介意者慎入。不定期更新。

前情提要~

【微实验】圆周运动的正弦信号发生仿真及其衍生(一)-CSDN博客

【微实验】圆周运动的正弦信号发生仿真及其衍生(二)-CSDN博客

这两篇文章中,我们定义了"扒谱机变换"和它的逆变换,即把极坐标里的轨迹形状转化成能被听见的声音波形。

具体来说,就是先确定极坐标里极径随角度变化的规律,也就是极径函数,再结合一个随时间均匀变化的幅角,最终获取声音的波形。

第一篇中给的例子里------

  • 圆形对应的极径是一个固定的常数,不随角度改变。当角度随时间均匀增加时,对应的波形就是标准的正弦波,只有一个基频。
  • 心形线的极径函数是用一个常数乘以(1加上角度的余弦值)。这使得极径会随着角度的变化而有规律地增减,轨迹呈现出心形。这样的函数转化成波形时,会在正弦波的基础上叠加一个与角度余弦相关的变化,让波形产生脉动,听起来除了基频,还会有二次谐波的成分。
  • 玫瑰线的极径函数是常数乘以角度整数倍的余弦值,这里的整数决定了玫瑰花瓣的数量。比如当这个整数是3时,极径就跟着3倍角度的余弦值变化,轨迹是3瓣玫瑰的形状。对应的波形会因为这种多倍角度的变化,产生基频之外的更多谐波,谐波的频率和这个整数相关,让声音的频谱更丰富。
  • 椭圆的极径函数相对复杂些,是用椭圆半长轴和半短轴的乘积,除以一个由角度的正弦和余弦值组成的平方根式子。这保证了极坐标下的轨迹是椭圆,极径会随着角度变化但保持椭圆的形状。转化出的波形接近正弦波,但幅值会有轻微的波动,谐波较少,听起来比较平滑。
  • 像奇形怪状的"派大星函数"这样的复杂闭合曲线,极径函数是由多个部分组合而成的。它包含一个常数项,一个和5倍角度余弦相关的项,还有一个由角度正弦、余弦组成的分式项。这样的组合让极径随角度的变化变得很不规则,轨迹也是不规则的闭合曲线。对应的波形就会非常复杂,包含基频、5倍频以及更多高次谐波和组合出来的频率,听起来音色丰富且独特。

总的来说,这些极径函数就像是不同的"模具",通过扒谱机变换,能把它们各自的形状特点转化成不同的声音波形,简单的函数对应纯净或较少谐波的声音,复杂的函数则对应谐波丰富、音色多样的声音。


为了更加贴合声音实验,今天小编压榨AI请他生成了更多的极坐标函数,然后编写代码生成基频为440Hz波形,绘图、播放然后存储到工作路径中。

(因为代码已经验证无误,为提高效率,不再进行动画仿真,而是直接给出结果)

接下来我遇到了一个bug

进行到双纽线这里,发现生成的波形有一大段是不连续的------

看了函数的定义后,发现不连续的地方是因为对应的相位部分,双纽线的极径r是虚数,在振幅转换之后就一直在0处。

从数学意义上讲,若要通过极坐标函数生成连续光滑的波形,极坐标函数需满足以下条件:

  1. 极径函数连续性:极径函数在定义域范围内必须是连续的,不能出现间断点。
  2. 极径函数可导性:极径函数在定义域范围内需要是可导的,确保波形在时域上光滑无突变。
  3. 极径函数非负性:极径函数在定义域范围内需非负,避免出现虚数或负值导致波形失真。
  4. 周期性:极径函数需具有周期性,以保证生成的波形在时域上是周期性的,从而使得频谱分析有意义。
  5. 频率成分可控性:极径函数的频率成分需可控,以确保生成的波形在频域上具有特定的频率特性,如单一频率、多个频率的组合等。

当然,声音的波形并不非要光滑连续,毕竟最终存储编码都是离散的,像锯齿波、方波这些,也有很独特的音响效果。

最终代码如下:

(代码运行会播放声音,注意调节音量!)

Matlab 复制代码
clear; clc; close all;
%%
% 核心参数设置
f0 = 440;                  % 基频440Hz(A4标准音)
duration = 1;              % 声音时长1秒
fs = 44100;                % 采样频率
T = 1/f0;                  % 周期
N_per_period = ceil(fs*T); % 一个周期的采样点数
N_total = fs*duration;     % 总采样点数
A = 0.8;                   % 振幅系数

% 定义30种不同的极坐标函数
polar_functions = [
    % 基础曲线
    struct('name', '圆形 (Circle)', 'expr', 'r(θ) = A', 'func', @(theta, A) A*ones(size(theta)));
    struct('name', '心形线 (Cardioid)', 'expr', 'r(θ) = A(1 + cosθ)', 'func', @(theta, A) A*(1 + cos(theta)));
    struct('name', '3瓣玫瑰线', 'expr', 'r(θ) = A*cos(3θ)', 'func', @(theta, A) A*cos(3*theta));
    struct('name', '4瓣玫瑰线', 'expr', 'r(θ) = A*cos(2θ)', 'func', @(theta, A) A*cos(2*theta));
    struct('name', '5瓣玫瑰线', 'expr', 'r(θ) = A*cos(5θ)', 'func', @(theta, A) A*cos(5*theta));
    struct('name', '6瓣玫瑰线', 'expr', 'r(θ) = A*cos(3θ)', 'func', @(theta, A) A*cos(3*theta));
    struct('name', '7瓣玫瑰线', 'expr', 'r(θ) = A*cos(7θ)', 'func', @(theta, A) A*cos(7*theta));
    struct('name', '8瓣玫瑰线', 'expr', 'r(θ) = A*cos(4θ)', 'func', @(theta, A) A*cos(4*theta));
    struct('name', '9瓣玫瑰线', 'expr', 'r(θ) = A*cos(9θ)', 'func', @(theta, A) A*cos(9*theta));
    struct('name', '10瓣玫瑰线', 'expr', 'r(θ) = A*cos(5θ)', 'func', @(theta, A) A*cos(5*theta));
    
    % 螺线族
    struct('name', '阿基米德螺线', 'expr', 'r(θ) = Aθ', 'func', @(theta, A) A*theta);
    struct('name', '对数螺线', 'expr', 'r(θ) = A·e^{(kθ)}', 'func', @(theta, A) A*exp(0.2*theta));
    struct('name', '费马螺线', 'expr', 'r²(θ) = A²θ', 'func', @(theta, A) A*sqrt(theta));
    struct('name', '双曲螺线', 'expr', 'r(θ) = A/θ', 'func', @(theta, A) A./(theta + 0.5));
    
    % 其他曲线
    struct('name', '伯努利双纽线', 'expr', 'r(θ) = A√{2cos2θ}', 'func', @(theta, A) A*sqrt(2*cos(2*theta)));
    struct('name', '卡西尼卵形线', 'expr', 'r²(θ) = A²cos2θ + B²', 'func', @(theta, A) sqrt(A^2*cos(2*theta) + 0.5^2));
    struct('name', '椭圆', 'expr', 'r(θ) = A/(1 + ecosθ)', 'func', @(theta, A) A./(1 + 0.5*cos(theta)));
    struct('name', '正弦曲线', 'expr', 'r(θ) = A + B·sin(nθ)', 'func', @(theta, A) A + 0.4*sin(3*theta));
    struct('name', '余弦曲线', 'expr', 'r(θ) = A + B·cos(nθ)', 'func', @(theta, A) A + 0.4*cos(3*theta));
    struct('name', '正切曲线', 'expr', 'r(θ) = A·tan(θ)', 'func', @(theta, A) A*tan(theta/2));
    
    % 新增曲线
    struct('name', '指数曲线', 'expr', 'r(θ) = A·e^{(kθ)}', 'func', @(theta, A) A*exp(0.1*theta));
    struct('name', '圆内螺线', 'expr', 'r(θ) = A·cos(nθ) + B', 'func', @(theta, A) A*cos(5*theta) + 0.5);
    struct('name', '圆外螺线', 'expr', 'r(θ) = A·cos(nθ)-B', 'func', @(theta, A) A*cos(5*theta)-0.5);
    struct('name', '肾形线', 'expr', 'r(θ) = A(1 + cosθ)', 'func', @(theta, A) A*(1 + cos(theta)));
    struct('name', '蜗牛线', 'expr', 'r(θ) = A(1 + cosθ) + B', 'func', @(theta, A) A*(1 + cos(theta)) + 0.3);
    struct('name', '双叶线', 'expr', 'r(θ) = A·sin(nθ/2)', 'func', @(theta, A) A*sin(5*theta/2));
    struct('name', '三叶线', 'expr', 'r(θ) = A·sin(nθ/3)', 'func', @(theta, A) A*sin(5*theta/3));
    struct('name', '四叶线', 'expr', 'r(θ) = A·sin(nθ/4)', 'func', @(theta, A) A*sin(5*theta/4));
    struct('name', '五叶线', 'expr', 'r(θ) = A·sin(nθ/5)', 'func', @(theta, A) A*sin(5*theta/5));
    struct('name', '六叶线', 'expr', 'r(θ) = A·sin(nθ/6)', 'func', @(theta, A) A*sin(5*theta/6));
    struct('name', '七叶线', 'expr', 'r(θ) = A·sin(nθ/7)', 'func', @(theta, A) A*sin(5*theta/7));
    struct('name', '八叶线', 'expr', 'r(θ) = A·sin(nθ/8)', 'func', @(theta, A) A*sin(5*theta/8));
    struct('name', '九叶线', 'expr', 'r(θ) = A·sin(nθ/9)', 'func', @(theta, A) A*sin(5*theta/9));
    struct('name', '十叶线', 'expr', 'r(θ) = A·sin(nθ/10)', 'func', @(theta, A) A*sin(5*theta/10));
];

% 生成一个周期的时间和角度向量
t_one_period = linspace(0, T, N_per_period);
theta_one_period = 2*pi*(t_one_period/T);

% 循环处理每个极坐标函数
for i = 1:length(polar_functions)
    func = polar_functions(i);
    
    % 生成一个周期的波形
    r_one_period = func.func(theta_one_period, A);
    % 处理可能出现的复数或负值(对于某些极坐标函数)
    r_one_period = abs(real(r_one_period));
    y_one_period = r_one_period .* sin(theta_one_period);
    
    % 扩展为1秒的波形(复制粘贴周期波形)
    y = repmat(y_one_period, 1, ceil(N_total/N_per_period));
    y = y(1:N_total);  % 确保正好1秒
    t_full = linspace(0, duration, N_total);  % 完整时间向量
    
    % 归一化处理(避免声音失真)
    y_normalized = y / max(abs(y)) * 0.9;
    
    % 保存为WAV文件
    filename = sprintf('polar_waveform_%d.wav', i);
    audiowrite(filename, y_normalized, fs);
    fprintf('声音已保存为: %s\n', fullfile(pwd, filename));
    
    % 绘制极坐标轨迹
    figure('Position',[100 100 1400 500]);
    
    % 1. 极坐标轨迹
    subplot(1,3,1);
    polarplot(theta_one_period, r_one_period, 'b-', 'LineWidth',2);
    hold on;
    polarplot(theta_one_period(end), r_one_period(end), 'ro', 'MarkerSize',10, 'LineWidth',2);
    polarplot([theta_one_period(end), theta_one_period(end)], [0, r_one_period(end)], 'g--', 'LineWidth',1.5);
    title(func.name, 'FontSize',10);
    hold off;
    
    % 2. 一个周期的时域波形
    subplot(1,3,2);
    plot(t_full, y_normalized, 'b-', 'LineWidth',1.2);
    xlabel('时间 (s)');
    ylabel('振幅');
    title(['时域波形 (基频 ' num2str(f0) 'Hz)']);
    xlim([0 T]);
    ylim([-1.1 1.1]);
    grid on;
    
    % 3. 周期延拓后的傅里叶变换
    subplot(1,3,3);
    Y = fft(y_one_period - mean(y_one_period));  % 对一个周期做FFT
    f = (0:N_per_period-1)*(fs/N_per_period);    % 频率轴
    amp = abs(Y)/N_per_period*2;                 % 幅值归一化
    max_harmonic = 5;
    f_range = f(f <= max_harmonic*f0);
    amp_range = amp(f <= max_harmonic*f0);
    stem(f_range, amp_range, 'b-', 'MarkerSize',6, 'LineWidth',1.2);
    xlabel('频率 (Hz)');
    ylabel('幅值');
    title('周期延拓后的频谱');
    xlim([0 max_harmonic*f0]);
    grid on;
    
    sgtitle([func.expr ' 波形与声音生成'], 'FontSize',12);
    fprintf('正在显示 %s 的图形...\n', func.name);
    pause(2);  % 显示图形2秒
    
    % 播放声音
    sound(y_normalized, fs);
    fprintf('正在播放 %s 的声音...\n', func.name);
    pause(duration + 0.5);  % 等待声音播放完毕,加0.5秒缓冲
end

fprintf('所有极坐标函数的波形和声音已生成完毕。\n');

最后生成的3-10叶线(AI这么叫的,这里只是一个代号,与数学上的定义并不相符和实际上曲线的叶数,笔者只是在研究音乐,所以就不较真了)因为周期不足,因此只绘制了一个周期的部分,如果周期绘制充足,按理来说是频率是会降低的,所以我又请AI帮忙写代码把这些线的频率调高,完整绘制对应到440Hz的频率内。
未绘制完整的曲线

代码如下:

Matlab 复制代码
% 核心参数设置(确保基频440Hz)
f0 = 440;                  % 基频440Hz
duration = 1;              % 声音时长1秒
fs = 44100;                % 采样频率
T = 1/f0;                  % 时域周期(1/440秒)
N_per_period = ceil(fs*T); % 一个时域周期的采样点数(声音采样精度)
high_res_factor = 30;      % 极坐标绘图分辨率提升倍数(30倍超采样)
A = 0.8;                   % 振幅系数

% 定义3-10叶线的极坐标函数(叶数n=3到10)
polar_functions = [
    struct('name', '三叶线', 'n', 3, 'expr', 'r(θ) = A·sin(nθ/3)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '四叶线', 'n', 4, 'expr', 'r(θ) = A·sin(nθ/4)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '五叶线', 'n', 5, 'expr', 'r(θ) = A·sin(nθ/5)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '六叶线', 'n', 6, 'expr', 'r(θ) = A·sin(nθ/6)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '七叶线', 'n', 7, 'expr', 'r(θ) = A·sin(nθ/7)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '八叶线', 'n', 8, 'expr', 'r(θ) = A·sin(nθ/8)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '九叶线', 'n', 9, 'expr', 'r(θ) = A·sin(nθ/9)', 'func', @(theta, A, n) A*sin(n*theta/n));
    struct('name', '十叶线', 'n', 10, 'expr', 'r(θ) = A·sin(nθ/10)', 'func', @(theta, A, n) A*sin(n*theta/n));
];

% 生成时域周期内的时间向量(声音采样精度)
t_one_period = linspace(0, T, N_per_period);

% 循环处理每个叶线函数
for i = 1:length(polar_functions)
    func = polar_functions(i);
    n = func.n;  % 叶数
    
    % 1. 声音生成用(保持基频精度)
    theta_sound = linspace(0, 2*pi*n, N_per_period);
    r_sound = func.func(theta_sound, A, n);
    r_sound = abs(real(r_sound));
    y_one_period = r_sound .* sin(theta_sound);  % 声音波形
    
    % 扩展为1秒波形
    y = repmat(y_one_period, 1, ceil(fs*duration/N_per_period));
    y = y(1:fs*duration);  % 确保正好1秒
    y_normalized = y / max(abs(y)) * 0.9;  % 归一化
    
    % 2. 高分辨率绘图用(提升视觉精细度)
    N_high_res = N_per_period * high_res_factor;  % 高分辨率点数
    theta_plot = linspace(0, 2*pi*n, N_high_res);  % 极角超采样
    r_plot = func.func(theta_plot, A, n);
    r_plot = abs(real(r_plot));  % 处理复数和负值
    
    % 保存为WAV文件
    filename = sprintf('%d叶线_sound.wav', n);
    audiowrite(filename, y_normalized, fs);
    fprintf('%d叶线声音已保存为: %s\n', n, fullfile(pwd, filename));
    
    % 绘制高分辨率图形
    figure('Position',[100 100 1400 500]);
    
    % 1. 极坐标轨迹(高分辨率显示)
    subplot(1,3,1);
    % 通过增加采样点和细化线条来提高精度
    polarplot(theta_plot, r_plot, 'b-', 'LineWidth',1.2);
    hold on;
    polarplot(theta_plot(end), r_plot(end), 'ro', 'MarkerSize',8);
    polarplot([theta_plot(end), theta_plot(end)], [0, r_plot(end)], 'g--', 'LineWidth',1);
    title([func.name ' (极坐标' num2str(n) '个周期)'], 'FontSize',10);
    
    % 优化极坐标刻度显示
    ax = gca;
    ax.ThetaTick = 0:30:330;  % 显示0°,30°,60°,...330°刻度
    ax.RTick = linspace(0, max(r_plot), 5);  % 合理设置径向刻度
    hold off;
    
    % 2. 时域波形(声音采样精度)
    subplot(1,3,2);
    plot(t_one_period, y_one_period, 'b-', 'LineWidth',1.2);
    xlabel('时间 (s)');
    ylabel('振幅');
    title([func.name ' 时域波形 (基频' num2str(f0) 'Hz)']);
    xlim([0 T]);
    ylim([-1.1 1.1]);
    grid on;
    
    % 3. 频谱分析
    subplot(1,3,3);
    Y = fft(y_one_period - mean(y_one_period));
    f = (0:N_per_period-1)*(fs/N_per_period);
    amp = abs(Y)/N_per_period*2;
    max_harmonic = 5;
    f_range = f(f <= max_harmonic*f0);
    amp_range = amp(f <= max_harmonic*f0);
    stem(f_range, amp_range, 'b-', 'MarkerSize',6);
    xlabel('频率 (Hz)');
    ylabel('幅值');
    title('周期延拓后的频谱');
    xlim([0 max_harmonic*f0]);
    grid on;
    
    sgtitle([func.expr ' 高分辨率波形与声音生成'], 'FontSize',12);
    pause(2);  % 显示图形2秒
    
    % 播放声音
    sound(y_normalized, fs);
    fprintf('正在播放%d叶线声音...\n', n);
    pause(duration + 0.5);  % 等待声音播放完毕
end

fprintf('所有叶线的高分辨率波形和声音已生成完毕。\n');

绘制完整后,我才发现我的设想是错误的。

因为这样一来,所有的曲线都会变成一个几乎重叠的两瓣玫瑰线。

所以从理论上讲,生成的音频的理想情况是按照440Hz的n倍往上增长。

运行代码,聆听声音,我发现了一个很有趣的现象,虽然高频很明显地在往上增长,但是低频(尤其是440Hz的基频的听感始终存在)

使用AU打开刚刚保存的波形,可以发现,哪怕是频率最高的所谓十叶线的波形,画红框的部分也是有基频存在的,其他的440Hz的倍频也是存在的。

这是为什么呢?

笔者的解释是,因为我们在代码中进行的是仿真采样,并不是根据数学公式推导,所以对于所谓"n叶线",是一个重复的波形的n次绘图,采样后带来的误差在每个小周期内都是不一样的,只有n个周期(对应440Hz的基频)是完整重复的。总体上,这就导致了只有440Hz才是最终的基频。

解释的不是很明白,请AI帮忙------

它这样说:

要理解为何十叶线等波形中始终存在 440Hz 基频及其倍频,核心在于信号的时间周期性由整体重复周期决定,而非局部波动次数。你的观察本质上涉及 "空间周期性" 与 "时间周期性" 的区别、信号基频的定义,以及仿真中波形生成逻辑的影响,具体可以从这三个层面拆解:

一、先明确:基频的本质是 "信号整体重复的周期"

基频(f₀) 的物理意义是信号完成一次完整重复的时间周期(T)的倒数,即 f₀=1/T。无论波形内部有多少局部波动(比如 n 叶线的 n 个 "叶"),只要整体波形每 T 时间重复一次,基频就只能是 1/T。

在你的仿真中,若设定 "绘制 n 叶线的总时间为 T=1/440 秒"(即 440Hz 对应的周期),那么整个 n 叶线的波形会在每 1/440 秒后完全重复一次 ------ 比如十叶线的 10 个 "叶" 会在 1/440 秒内画完,下一个 1/440 秒又会一模一样地画一次 10 个 "叶"。此时,信号的整体周期 T=1/440 秒,基频自然是 440Hz,与 n 的大小无关。

二、n 叶线的 "n 个叶" 是 "局部波动",而非 "独立周期"

你提到 "n 叶线是重复的波形的 n 次绘图",这里的 "n 次绘图" 本质是一个基频周期内的 n 次局部波动,而非 n 个独立的小周期。

举个例子:假设 n=10(十叶线),在 T=1/440 秒内,波形会有 10 个起伏(10 个叶),但这 10 个起伏并不满足 "周期性"------ 即第 1 个叶的波形和第 2 个叶的波形可能相似但不会完全重复(比如极坐标中 θ 的起始位置不同),且不会在 T'=T/10=1/(440×10) 秒后独立重复。真正重复的是 "10 个叶的完整组合",每 T=1/440 秒重复一次。

因此,这 10 个叶只是基频周期内的 "细节波动",不会产生 10×440Hz 的新基频,反而会因为这些波动是基频周期内的 "谐波成分",从而产生 440Hz 的倍频(如 880Hz、1320Hz 等)。

三、仿真采样的误差不是主因,核心是 "波形生成逻辑"

你提到 "采样误差导致每个小周期不同",但这并非基频存在的关键原因。即使采样完全理想(无误差),只要波形的整体重复周期是 T=1/440 秒,基频就必然是 440Hz。

原因在于你的仿真逻辑:是 "在一个 440Hz 周期内画 n 个叶",而非 "让每个叶对应一个独立周期"。比如,若想让十叶线的基频是 4400Hz(10×440),需要设定 "每个叶的绘制时间为 T'=1/4400 秒,且单个叶的波形会在 T' 内重复",但此时整体波形的周期就变成了 T',而非原来的 T=1/440 秒 ------ 显然这与你的仿真设定不符。

总结:基频由 "整体重复周期" 说了算

十叶线等波形中始终存在 440Hz 基频,根本原因是整个波形的重复周期被设定为 440Hz 对应的周期(1/440 秒)。n 叶线的 "n 个叶" 只是这个周期内的局部细节,不会改变整体的重复规律。无论是仿真采样还是数学推导,只要信号的整体周期不变,基频就不会变;而局部波动带来的倍频(440Hz 的 2 倍、3 倍等),恰恰是这些细节在基频周期内的 "谐波表现"。

简单说:n 叶线的 "n" 决定了一个基频周期内有多少个 "褶皱",但 "褶皱数量" 不影响 "多久皱一次"------ 后者才是基频的本质。

我觉得它虽然说得对,但是并没有理解问题的关键,尤其是第三点。诸位怎么理解,见仁见智吧。

仔细看波形,你可以发现,实际上带来基频的,是每n个周期重复一次的这一小段波形
"十叶线"------每十个一组,衔接的部分很明显 "四叶线",不是很明显,但是也能看出来

如果绘制与采样完全没有误差,这些波形完美地首尾相接,那么基频就是一个小周期对应的频率,不会有更低的440Hz出现。

未完待续~

相关推荐
E_ICEBLUE3 分钟前
Python 操作 Word 文档:主流库对比与选择指南
开发语言·经验分享·python·word·办公自动化
I'm a winner18 分钟前
LaTeX 复杂图形绘制教程:从基础到进阶
经验分享·笔记·科技
khs135543287802 小时前
污水中去除磷酸盐有哪些方法
经验分享
计算机小手2 小时前
提升文档管理:推荐一键Docker部署的全文索引搜索引擎工具
经验分享·搜索引擎·docker·全文检索·开源软件
全优统计3 小时前
伞状Meta分析重构癌症幸存者照护指南:从矛盾证据到精准决策
经验分享·学习
给老吕螺丝5 小时前
C 语言作用域与存储期深度解析:空间与时间的双重维度
c语言·开发语言·经验分享·笔记
程序员老冯头8 小时前
第三十二节 MATLAB函数
数据结构·算法·matlab
绿炮火18 小时前
【MATLAB】(二)基础知识
开发语言·算法·matlab