該如何作一條已知曲線的等距曲線?

我目前的作法是這樣:

有一條曲線。

在該曲線的端點及控制點上作等長的垂線。

通過垂線上的點得到新的曲線。但是…我想要的並不是這樣的曲線啊,而是這樣的 ↓

要如何才能得到這樣的曲線呢?新曲線的控制點與原有曲線的控制點之間的偏移量該如何計算呢?


搜到了一個簡便的演算法:

Via:Control points of offset bezier curve


所需要的曲線稱作平行曲線( Parallel Curve )。

從原曲線法線方向偏移所需的距離,就可以得到這些平行曲線。

對於參數曲線mathbf{r}(t),其切線速度就是其第一導數

mathbf{v}(t)=mathbf{r}

歸一化後得單位切線矢量

mathbf{T}(t)=frac{mathbf{v}(t)}{|mathbf{v}(t)|}

在二維中,垂直於切綫的單位法矢量只需旋轉切線90度,設mathbf{T}(t)=(T_x(t), T_y(t)),則

mathbf{N}(t)=(-T_y(t), T_x(t))

那麼,設偏移距離為amathbf{r}(t)的兩條平行曲線為

mathbf{s}(t) = mathbf{r}(t) pm a mathbf{N}(t)

我們可以簡單地求出貝塞爾曲線(Bézier curve)的導數。然而,偏移後已不是貝塞爾曲線。如果在應用上只需要以直線渲染,就可直接對mathbf{s}(t)求值。如果結果需為貝塞爾曲線,簡單的方法是分段擬合。


Update:

原來是要以演算法方式實現。

那麼下面的答案也就當是給有需要的人參考吧。

-----------------

想到一個 dirty hack. 用的是 Adobe Illustrator,以向兩側作距離為 1cm 的等距曲線為例。

  1. 原始曲線。
  2. 將曲線的粗細設為 20mm.
  3. 使用 Outline Stroke 功能,將路徑轉化為形狀。
  4. 刪除多餘部分,即得兩條等距曲線。

這個方法作出來的曲線錨點數和原曲線會有不同,應該還是算擬合的方式吧。不過差別應該較小。


如果不是嚴格的繪製,可以這樣:

比如我有一條曲線:

在一端繪製一個圓:

再使用路徑陣列:

建立陣列之後,沿著圓描邊(這裡會有一點不精確),就得到新的曲線:

希望能有所幫助。


當然是用 rhino 啊!

佔個坑先,詳情再補

---------------------------------

Rhino下面,offest(偏移曲線)


cad里這就是個命令 它根本就不是個問題


用Rhino,導入進去用曲線菜單/偏移曲線,輸入距離就好了,我覺得Rhino畫曲線比AI方便強大的多,支持格式也全


3階bezier的offset曲線不是bezier。

用小線段分段擬合求出offset點再連起來。


你的下一款字體是黑體?


把曲線的端點和控制點向同一個方向平移應該就可以了。題主作的紅色的垂線之間並不全部平行,所以題中的各個曲線的端點和控制點在移動時並不平行,得到的新曲線自然不與原曲線平行,也不互相平行。

那些紅色的短線(指那些垂線)應該互相之間都平行,這樣才能得到平行的曲線。

題主所用的曲線應該是三階Bezier曲線,只要4個點(兩個端點,兩個控制點)就能被確定。

不知道題主是要在軟體里畫平行線,還是自己寫程序?


推薦閱讀:

為什麼Python比C++慢很多?
機器學習演算法中GBDT與Adaboost的區別與聯繫是什麼?
對於ACM或者OI的問題中,有哪些方法判斷一道題是使用了什麼演算法呢?
在浮點數組中最快的選擇最大k個數的演算法是什麼?
次優查找樹的原理是什麼?

TAG:演算法 | 數學 | 編程 |