簡體   English   中英

兩個不同長度向量arrays的線性插值

[英]Linear interpolation of two vector arrays with different lengths

PenInput & PenSmoot 我有兩條曲線。 一個手繪,一個是手繪的平滑版本。 每條曲線的數據存儲在 2 個單獨的向量 arrays 中。 時間增量也存儲在手繪曲線矢量中,因此我可以重播繪圖過程,使其看起來自然。

現在我需要將時間增量從曲線 1(原始輸入)轉移到曲線 2(已經平滑的曲線)。

有時第一個向量的大小比第二個向量大,有時比第二個向量小。
(取決於輸入繪制速度)

所以我的問題是:如何用正確的值填充向量 PenSmoot.time?

案例1:輸入向量較大

PenInput.time[0] = 0         PenSmoot.time[0] = 0
PenInput.time[1] = 5         PenSmoot.time[1] = ?
PenInput.time[2] = 12        PenSmoot.time[2] = ?
PenInput.time[3] = 2         PenSmoot.time[3] = ?
PenInput.time[4] = 50        PenSmoot.time[4] = ?
PenInput.time[5] = 100
PenInput.time[6] = 20
PenInput.time[7] = 3
PenInput.time[8] = 9
PenInput.time[9] = 33

案例2:輸入向量更小

PenInput.time[0] = 0         PenSmoot.time[0] = 0
PenInput.time[1] = 5         PenSmoot.time[1] = ?
PenInput.time[2] = 12        PenSmoot.time[2] = ?
PenInput.time[3] = 2         PenSmoot.time[3] = ?
PenInput.time[4] = 50        PenSmoot.time[4] = ?
                             PenSmoot.time[5] = ?
                             PenSmoot.time[6] = ?
                             PenSmoot.time[7] = ?
                             PenSmoot.time[8] = ?
                             PenSmoot.time[9] = ?

簡化表示:

PenInput holds the whole data of a drawn curve (Raw Input)

PenInput.x         // X coordinate)
PenInput.y         // Y coordinate)
PenInput.pressure  // The pressure of the pen)
PenInput.timetotl  // Total elapsed time)
PenInput.timepart  // Time fragments)

PenSmoot holds the data of the massaged (smoothed,evenly distributed) curve of PenInput

PenSmoot.x         // X coordinate)
PenSmoot.y         // Y coordinate)
PenSmoot.pressure  // Unknown - The pressure of the pen)
PenSmoot.timetotl  // Unknown - Total elapsed time)
PenSmoot.timepart  // Unknown - Time fragments)


這是我擁有的結構。

struct Pencil 
{
    sf::VertexArray vertices;
    std::vector<int> pressure;
    std::vector<sf::Int32> timetotl;
    std::vector<sf::Int32> timepart;
};

[此答案已根據對問題的編輯進行了廣泛修改。]

好的,在我看來,您只需要與這些點平行地插入時間戳。

我猜測傳入的數據是點數組(例如,X,Y 坐標)和時間增量數組的順序,每個數組的數量相同,所以 time-delta N 告訴你時間從N-1點到N點花了。

當您插入點時,您可能會想要智能地進行。 例如,在問題所示的形狀中,我們有兩條近似直線,一條斜率為正,另一條斜率為負。 根據圖片,那是由263個點組成的。 通過選擇兩個端點加上兩條線相交的一個點,我們可以將其減少到三個點,並且仍然可以相當合理地表示原始形狀。

不過,我們可能不需要 go 這么遠。 特別是考慮到時間,我們可能希望使用至少 7 個點作為輸出——每個彩色段的每個端點一個。 這將給我們 6 條直線段。 假設它們位於點 0、30、140、180、200、250 和 263。

然后,我們將在時間增量上使用完全相同的分段。 將 0 到 30 的增量相加,得到第一段的平均速度。 將 31 到 140 的增量相加,得到第二段的平均速度(依此類推到最后)。

增加點數的方法大致相同。 我們需要查看究竟使用了哪些輸入點來創建一對 output 點。 舉個簡單的例子,假設我們生產的 output 正好是輸入點數的兩倍。 然后,我們將在每對輸入點之間精確地插入時間增量。

在問題所示的情況下,我們從不均勻分布的輸入開始,但產生均勻分布的輸出。 所以第二個 output 點可能是前四個輸入點的平均值。 下一個 output 點可能是三個輸入點的平均值(以此類推)。 在許多情況下,output 中的段的兩個端點都可能與輸入中的任何點都不精確對應。

那也很好。 我們在輸入的兩點之間進行插值,以計算出 output 段起點的時間間隔。 對於終點也是如此。 然后我們可以根據點之間的時間增量計算它們之間應該花費的總時間。

如果你想變得花哨,你可以使用更高階的插值而不是線性的。 這確實需要每個插值更多的輸入點,但看起來你可能有很多事情要做,比如二次或三次插值(在大多數情況下)。 這可能會在轉換時產生最大的差異——“筆”快速加速或減速的地方。 在這樣的地方,線性插值可能會產生一些誤導性的結果(盡管考慮到您似乎正在使用的點數,它可能不會產生足夠的差異來引起注意)。

作為說明,讓我們考慮一條直線。 我們將從 5 個輸入點開始,生成 7 個 output 點。

因此,輸入點為 [0, 2, 7, 10, 15],相關的時間增量為 [0, 1, 4, 8, 3]。

因此,總行駛距離為 16,我們希望 output 點均勻分布。 因此,output 點之間的距離將為 16/7 =(大約)2.29。

所以,顯然第一個 output 點和時間都是 0。第二個 output 點是 2.29。 為了計算 output 時間,我們將整個時間帶到第一個輸入點 (0->2),加上.29 / (7-2) * (4-1)。 該插值部分給出 1.37,因此我們的第一個 output 時間增量為 2.37。

下一個 output 點應該在 4.58 的距離處。 由於第二個輸入段從 2 變為 7,我們的整個第二個 output 段將位於第二個輸入段內。 所以,我們取 2.29 / (7-2),告訴我們這個 output 段占據了輸入段的 458 個。 然后我們將其乘以第二個輸入段的時間,得到第二個 output 段的時間增量:.458 * (4-1) = 1.374。

[......它繼續以同樣的方式直到我們到達終點。]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM