根據 ISO/IEC TR 18037:2008(E) 規格書,其中第 4.2 節 Detailed changes to ISO/IEC 9899:1999 給出基於 C99 擴增的 C 語言新規範。
舉例來說,以 16 位元的有號整數來表示一定點數 0000 0010 0010 0101
則此定點數
對有號定點數,可以將位元分成三個部分:
對於數值位元又可以分成:
其中,假如數值位元為
對於用於表示帶分數的定點數,則每一數值位元用於表示在
對無號定點數,可以將位元分成兩個部分:
對於數值位元又可以分成:
其中,假如數值位元為
對於用於表示帶分數的定點數,則每一數值位元用於表示在
typedef int16_t twin_sfixed_t; /* 12.4 format */
typedef int32_t twin_dfixed_t; /* 24.8 format */
在 mado
中採用的是
/* Geometrical objects */
typedef struct _twin_spoint {
twin_sfixed_t x, y;
} twin_spoint_t;
一條樣到一直線的距離。輸入有三個 twin_spoint_t
輸出為一 twin_dfixed_t
。
回顧點到直線距離,直線方程的一般式為:
假設有兩點
整理得到
其中
則一直線方程外的點
將其平方
_lerp
為一線性插值函數,lerp 為 liner interploation 的縮寫
在 mado 中使用的曲線插值方式是貝茲曲線,兩點
其中
把
其中
由於為
但在此
而
static void _lerp(twin_spoint_t *a,
twin_spoint_t *b,
int shift,
twin_spoint_t *result)
{
result->x = a->x + ((b->x - a->x) >> shift);
result->y = a->y + ((b->y - a->y) >> shift);
}
_de_casteljau
Linear-time geometric algorithm for evaluating Bézier curves Filip Chudy, Paweł Woźny
在 mado 中的貝茲曲線是三次貝茲曲線,這裡的三次是基於變數
根據一開始四個點
其中
三次插值為
De Casteljau 的演算法則是藉由,每次迭代算出一線性插植點,再用於下一次迭代中。
藍色為初始點。
令插值函數
_twin_spline_decompose
#define TWIN_SFIXED_ONE (0x10)
#define TWIN_SFIXED_TOLERANCE (TWIN_SFIXED_ONE >> 2)
TWIN_SFIXED_ONE
in binary format is 0000 0000 0001 0000
where four bits for representing the fractional part.
And the default tolerance TWIN_SFIXED_TOLERANCE
is 0000 0000 0000 0100
which is
TWIN_SFIXED_TOLERANCE * TWIN_SFIXED_TOLERANCE
基於容忍量 tolerance 選取 shift 的策略。
數學上的插值函數是建立在一連續定義域跟一對應域中,在電腦中是以二進位數值為定義域跟定義域,更具體的來說是一有限域。詳細的內容可以參考解讀計算機編碼。
每執行一次三次插值法,就會多
https://blend2d.com/research/simplify_and_offset_bezier_curves.pdf
自己選的
2024 RAPH LEVIEN and ARMAN UGURAY
fig 3.
見
https://en.wikipedia.org/wiki/Circular_segment
https://en.wikipedia.org/wiki/Sagitta_(geometry)
對一曲線