我需要在Matlab中绘制这个函数:
必须连接线,我的意思是在减少线的末尾,增加一个必须开始等。它看起来像这样:
有什么想法吗?我需要在很长的时间间隔内,例如t从零到10
答案 0 :(得分:1)
它没有按预期工作的原因是因为对于每条曲线,您在0.1
秒的倍数之间绘制,y
- 截距未正确计算,因此曲线没有放在正确的位置。对于曲线的第一部分y = -57.5t
,y
- 截距位于原点,因此您的曲线符合预期y = -57.5t
。但是,当你达到0.1
秒时,你需要求解y
- 这条带有新斜率的新线的截距,因为它已经转移了。具体做法是:
y = 42.5t + b
我们知道在t = 0.1
秒,y = -5.75
给出了前一曲线。求解y
- 拦截给我们:
-5.75 = (42.5)(0.1) + b
b = -10
因此,在0.1s <= t <= 0.2s
之间,您的等式实际上是:
y = 42.5t - 10
现在,在t = 0.2s
重复相同的程序,我们有一个新的线方程,即使它与原点具有相同的斜率:
y = -57.5t + b
从上一条曲线,我们知道t = 0.2
秒,y = (42.5)(0.2) - 10 = -1.5
。因此,这条新曲线的截距是:
-1.5 = -(57.5)(0.2) + b
b = 10
因此,y = -57.5t + 10
是0.2s <= t <= 0.3s
之间的曲线。如果您不断重复这些计算,您会发现下一个y
- 拦截是-20
,然后是下一个20
,那么下一个-30
之后是y
等等。对于这些计算,您会看到10个模式的很好的倍数,并且您将看到具有正斜率的曲线始终具有负10
- 截距是y
的倍数,并且负斜率的曲线具有正斜率,其-10
- 截距是0.01
的倍数。
这是绘制此曲线时需要牢记的模式。因为当您在MATLAB中进行绘图时,我们必须离散地绘制点,您需要定义采样时间来定义每个点之间的时间分辨率。因为这些是线性曲线,所以您不需要那么短的采样时间,但为了简单起见,我们选择y
秒。这意味着每条新曲线之间我们将有10个点。
因此,对于我们图中的每10个点,我们将绘制一条不同的曲线,每条曲线具有不同的0
- 截距。因为您想在10
到(100)(10) = 1000
秒之间绘制点数,这意味着我们需要t
点。但是,这不包括原点,因此您实际需要 1001 点。因此,您可以像这样定义t = linspace(0,10,1001);
向量:
y
现在,每10分,我们需要不断更改y
拦截。在第一个分段,y
截距为0,第二个分段,10
截距为for
,依此类推。现在,许多MATLAB纯粹主义者会告诉你for
循环是禁忌,但是当涉及索引操作时,与其他更多矢量化解决方案相比,for
循环是时间最快的。例如,take a look at this post,我实现了一个带有0.1
循环的解决方案,它是其他提议解决方案中最快的。
首先让我们定义一个斜率数组,其中每个元素告诉我们每个段的斜率。因为我们有10秒的段,并且每个段的长度为-57.5
秒,包括原点,我们有101个段。在原点,我们的斜率为42.5
。在此之后,我们的斜坡在-57.5
和m = [-57.5 repmat([42.5 -57.5], 1, 50)];
之间交替。实际上,这交替进行了50次。要创建此数组,我们执行:
[42.5 -57.5]
我使用repmat
重复-57.5
数组50次,共计100次,加上原点y
。
现在,让我们定义一个y
- 拦截向量,告诉我们每个段y = zeros(1,101);
y(2:2:101) = 1;
y = 10*cumsum(y);
y(2:2:101) = -y(2:2:101);
拦截是什么。
y
上面的代码会生成一个0
- 截距矢量,使其从-10, 10
开始,然后系数为-20, 20
,然后是[0 1 0 1 0 1 0 1 0 1...]
,等等。这段代码是我首先生成cumsum
的序列。之后,我使用cumsum
进行累积求和,对于数组中的每个点,它会从开头直到该点添加值。因此,如果我们对此二进制序列执行[0 1 1 2 2 3 3 4 4...]
,则会给我们[0 10 10 20 20 30 30 40 40...]
。当我们乘以10时,得到[0 -10 10 -20 20 -30 30 -40 40...]
。最后,为了完成斜率,我们只是否定此数组中的每个偶数位置,因此我们最终得到y
。
现在,我们将使用这些代码生成曲线。我们将迭代每个段,并生成我们的输出值,并考虑%// Define time vector
t = linspace(0,10,1001);
%// Define slopes
m = [-57.5 repmat([42.5 -57.5], 1, 50)];
%// Define y-intercepts
y = zeros(1,101);
y(2:2:101) = 1;
y = 10*cumsum(y);
y(2:2:101) = -y(2:2:101);
%// Calculate the output curves for each segment
out = zeros(1, numel(t));
for idx = 1 : numel(y)-1
%// Compute where in the time array and output array
%// we need to write to
vals_to_access = (idx - 1)*10 + 1 : idx*10;
%// Create the curve for this segment
out(vals_to_access) = m(idx)*t(vals_to_access) + y(idx);
end
%// Copy second last value over to last value
out(end) = out(end-1);
%// Plot the curve
plot(t,out);
axis tight;
- 截距。我们首先需要分配一个存储我们的值的输出数组,然后我们将填充每个段的值。我们还需要跟踪我们要访问的时间值以计算输出值。
因此:
for
vals_to_access
循环的技巧是知道 where 来访问每个段的时间值,以及将这些值写入的位置。这是for
的目的。另请注意,1000th
循环仅在数组中填充从第一个索引到1001th
索引的值,但不计算out(end) = out(end-1);
元素。为简单起见,我们只是将元素从倒数第二点复制到最后一点,这就是{{1}}存在的原因。上面的代码也将绘制曲线并确保轴紧密绑定。因此,这就是我得到的: