2016年9月17日星期六

PDF 繪畫圓形或橢圓形方法

承上次提及的 純文字製作簡單 PDF
在繪畫圖形中,可以畫線、矩形、甚至以點陣圖插入圖像都可以,但好像沒有提及圓形或橢圓形
莫非 PDF 不能繪畫圓形或橢圓形 ?

的確是
PDF 是不能繪畫圓形或橢圓形,但為何 PDF 可以經圖像處理軟件匯出後顯示圓形或橢圓形 ?
原因是 PDF 是借用使用 Bézier Curve 是模擬圓形或橢圓形

平常很多程式都有橢圓形工具
不同的程式對繪畫橢圓形都略有不同,但大多數都分別使用:
x, y, width, height
x1, y1, x2, y2
cx, cy, width, height
這幾種方法

但由於 PDF 沒有相關操作,因此匯出的資料會以 4組 Bezier Curve 顯示
(上次解析 PDF 結構沒有提及就是因為當時找不到與圓形或橢圓形相關的資訊,唯有先發佈已經了解的資料,避免忘記)

上次提及過
% other options
x1 y1 m x2 y2 l
% other options
能設定線段

若要使用 Bézier Curve 則使用
x1 y1 m cx1 cy1 cx2 cy2 x2 y2 c
cx1 cy1 為線段起點的控制點
cx2 cy2 為線段終點的控制點

例如
100.00 100.00 m 100.00 200.00 100.00 200.00 200.00 200.00 c
見下文
但顯然這個效果不是夠「圓」

要將 Bezier Curve 模擬成圓形或橢圓形的曲線,不是胡亂放置定點及控制點
根據 Composite Bézier curve @ Wiki 的資料
定點與控制點相距離的比例為 4 / 3 * (sqrt(2) - 1)
(SVG 來源原自 Wiki 的 Four-segment cubic polyBézier)

以 (x1, y1), (x2, y2) 分別為 左上角 及 右下角 繪畫矩形
見下文

計算闊高及定點
闊(w) = absolute(x2 - x1)
高(h) = absolute(y2 - y1)
上定點 = (x2 + x1) / 2, y1
右定點 = x2, (y2 + y1) / 2
下定點 = (x2 + x1) / 2, y2
左定點 = x1, (y2 + y1) / 2
見下文

由上至右的定點設定控制點
cx1 = (x2 + x1) / 2 + (w * 4 / 3 * (sqrt(2) - 1))
cy1 = y1
cx2 = x2
cy2 = (y2 + y1) / 2 + (h * 4 / 3 * (sqrt(2) - 1))
見下文

由右至下的定點設定控制點
cx1 = x2
cy1 = (y2 + y1) / 2 - (h * 4 / 3 * (sqrt(2) - 1))
cx2 = (x2 + x1) / 2 + (w * 4 / 3 * (sqrt(2) - 1))
cy2 = y2
見下文

由下至左的定點設定控制點
cx1 = (x2 + x1) / 2 - (w * 4 / 3 * (sqrt(2) - 1))
cy1 = y2
cx2 = x1
cy2 = (y2 + y1) / 2 - (h * 4 / 3 * (sqrt(2) - 1))
見下文

由左至上的定點設定控制點
cx1 = x1
cy1 = (y2 + y1) / 2 + (h * 4 / 3 * (sqrt(2) - 1))
cx2 = (x2 + x1) / 2 - (w * 4 / 3 * (sqrt(2) - 1))
cy2 = y1
見下文

最後 PDF stream 的資料大概會是這樣
% other options
150.00 200.00 m
177.61 200.00 200.00 177.61 200.00 150.00 c
200.00 122.39 177.61 100.00 150.00 100.00 c
122.39 100.00 100.00 122.39 100.00 150.00 c
100.00 177.61 122.39 200.00 150.00 200.00 c
% other options

PDF 的結構仍在理解中

2 則留言 :

  1. 回覆
    1. 有時間會再錄,但應該都係片段式,可能偏向技巧性或 bug 之類既片
      讀緊書又返工,冇乜時間,唔好話打機,連科技野都少左時間試,所以咁遲先回你,唔好意思

      刪除