我有一个l_1
行,其中有一个点系列p_1,...,p_n
。我现在想要一个新l_2
行k
点q_1,...,q_k.
但是对于所有i \in {1,...,k-1}: abs( q_i - q_i+1 ) = const
,意味着l_2
的段是等距或均匀的。
k >= 2
p_1
和p_n应位于l_2
。abs( p_i - p_i+1 )
不是const 一种解决方案是使用样条曲线逼近一条线,然后再次对其进行二次采样,以获得均匀的长度段。我可以做得更好吗?那有什么C ++代码吗?
啊,我错过了一个具体的细节:q_i
应该在l_1
,这意味着它们位于l_1
的线段上,或者它们是{{的样本点1}}。
答案 0 :(得分:7)
您可以定义分段参数函数:
f[t_] := Piecewise[
When x[i] <= t <= x[i + 1]
f[t]= (y[i+1]-y[i]) (t - x[i]) / (x[i+1]-x[i]) + y[i],
For {i, 1 ... N};
然后选择你的点q,理想情况下间距小于最小p [i + 1] -p [i]
最后以相等的t间隔对f [q]进行采样。
示例结果:
在这里,您可以看到原始样本中将间隔大小从最大值减小到最小值的效果:
您可以评估近似的优点,将原始曲线和重新采样曲线之间的区域(积分)相加:
如果您绘制不同间隔大小的积分,您可以决定什么是良好的采样:
仅为了记录,Mathematica中的代码是:
a = 0;
p = Table[{ a = a + RandomReal[], RandomReal[]}, {10}];
f[t_, h_] := Piecewise[Table[{(h[[i + 1, 2]] - h[[i, 2]]) (t - h[[i, 1]]) /
(h[[i + 1, 1]] - h[[i, 1]]) + h[[i, 2]],
h[[i, 1]] <= t <= h[[i + 1, 1]]},
{i, 1, Length[h] - 1}]];
minSeg[h_] := Min[Table[Norm[h[[i, 1]] - h[[i + 1, 1]]], {i, Length[h] - 1}]];
newSegSize[h_] := (h[[Length@h, 1]] - h[[1, 1]])/
Ceiling[(h[[Length@h, 1]] - h[[1, 1]])/minSeg[h]]
qTable = Table[{t, f[t, p]}, {t, p[[1, 1]], p[[Length@p, 1]], newSegSize[p]}];
编辑:回答您的评论
评论pgm代码:
a = 0; (* Accumulator to ensure an increasing X Value*)
p = Table[{a = a + RandomReal[],
RandomReal[]}, {10}]; (*Generates 10 {x,y} Rnd points with \
increasing x Value*)
f[t_, h_] := (* Def. a PWise funct:
Example of resulting function:
f[t,{{1,2},{2,2},{3,4}}]
Returns teh following function definition:
Value for Range
2 1<=t<=2
2+2*(-2+t) 2<=t<=3
0 True
*)
Piecewise[
Table[{(h[[i + 1, 2]] -
h[[i, 2]]) (t - h[[i, 1]])/(h[[i + 1, 1]] - h[[i, 1]]) + h[[i, 2]],
h[[i, 1]] <= t <= h[[i + 1, 1]]},
{i, 1, Length[h] - 1}]];
minSeg[h_] := (* Just lookup the min input point separation*)
Min[Table[Norm[h[[i, 1]] - h[[i + 1, 1]]], {i, Length[h] - 1}]];
newSegSize[h_] := (* Determine the new segment size for having
the full interval length as a multiple of the
segment size *)
(h[[Length@h, 1]] - h[[1, 1]])/
Ceiling[(h[[Length@h, 1]] - h[[1, 1]])/minSeg[h]]
qTable = (*Generates a table of points using the PW function *)
Table[
{t, f[t, p]},
{t, p[[1, 1]], p[[Length@p, 1]],newSegSize[p]}];
ListLinePlot[{qTable, p}, PlotStyle -> {Red, Blue}] (*Plot*)
答案 1 :(得分:2)
这取决于你的要点 - 它们是什么?如果他们定义了一条平滑线,那么重新采样三次样条是一个不错的选择。
基本上,如果你使得点等距离,你需要定义你想要在点之间看到的东西 - 平滑度比坚持原始线更重要吗?有速度限制吗?
据我所知,你可能会在这里得到一个迭代过程,因为如果你的原始点定义了一条平滑线,那么计算该线的长度并不简单,更不用说将它分开了。分成相等的部分并确定这些点的坐标。
如果使用三次样条曲线,对于每个样条曲线,您应该能够通过Wikipedia's Arc Length article上的公式计算其长度。但是,它需要您进行集成 - 当您进行数值积分时,它被称为“quadrature”。对于三次方(计算两个原始点之间的线段长度),这应该最终为三次样条系数的加权和 - 特别是如果使用高斯求积法。
然而,您可以使用分段三次多项式(从2个点生成一个三次多项式,在它们两侧生成2个点)和一个迭代算法来获得合理的答案,该算法可以改善xi的猜测值以给出等距点。但这是假设你想要速度而不是准确性。