# Bézier1 スプライン

技術的には、PostScript は 3 次 Bézier スプラインを使用します。各制御点は、対応する端点におけるスプラインの傾きを決定します。TrueType が使用している 2 次 Bézier スプラインでは、2 個の端点の間には 1 個の制御点しかなく、その点が隣接する両方の端点における傾きを決定します。両フォーマットとも直線 (これは線形な Bézier スプラインです) も併用します。

他の次数の Bézier スプラインを作成することも可能です。4 次スプラインでは 3 個の制御点が存在し、5 次スプラインでは 4 個の制御点が、という具合です。そのなかで我々が関心をもっているのは線形, 2 次と 3 次のスプラインです――それらは TrueType と PostScript で使用されています。

左の例は 2 個の制御点をもつ 3 次スプラインで、それぞれ近い側の端点における傾きを決定しています。一方、右に示した例は 2 次スプラインで、1 個の制御点が両側の端点における傾きを決定しています。

一般的に、P0, P1,... Pn というラベルのついた (n+1) 個の点がある場合、P0 と Pn が端点となり (その他はすべて制御点です)、Bézier スプラインを定義する等式は、 となります。点が 2 個のときは、これは単に 2 個の端点を結ぶ線分となります。点が 3 個のときは TrueType で用いられている 2 次スプラインで、4 個のときは PostScript で用いられている 3 次スプラインです。

3 次 Bézier 曲線はのように表示することができます:

> x = ax*t3 + bx*t2 + cx*t +dx
> y = ay*t3 + by*t2 + cy*t +dy

ここで

| dx = P0.x | dy = P0.y
| cx = 3*P1.x-3*P0.x | cy = 3*P1.y-3*P0.y
| bx = 3*P2.x-6*P1.x+3*P0.x | by = 3*P2.y-6*P1.y+3*P0.y
| ax = P3.x-3*P2.x+3*P1.x-P0.x | ay = P3.y-3*P2.y+3*P1.y-P0.y

です。

また、2 次 Bézier 曲線は以下のようになります:

| dx = P0.x | dy = P0.y
| cx = 2*P1.x-2*P0.x | cy = 2*P1.y-2*P0.y
| bx = P2.x-2*P1.x+P0.x | by = P2.y-2*P1.y+P0.y

そして直線は以下のとおりです:

| dx = P0.x | dy = P0.y
| cx = P1.x-P0.x | cy = P1.y-P0.y

## TrueType を PostScript に変換する方法

直線のフォーマット変換には数学は一切必要ありません.

任意の 2 次スプラインは 3 次の表現をもちます (その場合、3 次の項が 0 となる)。3 次のときの端点は 2 次のときと同じです。

> CP0 = QP0
> CP3 = QP2

3 次表現での 2 個の制御点は、以下のようになります。

> CP1 = QP0 + 2/3 *(QP1-QP0)
> CP2 = CP1 + 1/3 *(QP2-QP0)

ですから、TrueType から PostScript への変換は自明です。丸めに伴う微小な誤差はありますが、それはほとんど気づかない程度のものです。

(Anish Mehta から、TrueType ではピクセルの中間に位置する点を指定する (すなわち、x や y の値が 1/2 の端数をもつ) ことができるという指摘を受けました。これも PostScript への変換を行うときに丸め誤差を持ち込む原因となり得ます。しかし解決方法は単純です: フォントの EM 正方形を 2 倍に拡大すれば、問題はなくなります)。

## PostScript を TrueType に変換する方法

ほとんどすべての 3 次スプラインは 2 次スプラインで正確に表現することができません (それどころか、2 次スプラインを連結しても表現できません)。可能な最良の手段は、3 次曲線をある程度の許容誤差の範囲で近似することです。ここにそれを行う方法を示します:

3 次スプラインが与えられたとしましょう。スプライン上の 2 個の点に注目しましょう。その場合、それらの 2 点における傾きが求める値であるスプラインは、それら 2 個の点の間に 1 本しか引くことができません。(その 2 次曲線は、その区間の端点を端点とし、その制御点は、3 次曲線のその区間の始点と終点における接線の交点です)。

スプライン上の片方の端点から始め、時折 (すなわち、許容誤差の範囲内で) ある許される 2 次近似が本当に、3 次曲線に十分密接に合致しているかをチェックします。

もしこの近似がうまく行ったら、結果の一部としてそれらを保存し、開始点を 3 次スプラインに沿って、私たちがいま作成した 2 次曲線の端点に向かって延長します。

(指定された点において 2 次近似が存在するとは限らない (例えば交点がたまたま交点だった場合など) ため、何らかの微妙な複雑さが含まれている場合があります。しかしこれらは簡単に解消することができます)。

もちろん、場合によっては、与えられた“3 次曲線”が実際には 2 次曲線であることもあります (3 次の項が 0 である場合)。その最もありふれた原因は、そのフォントの元データが TrueType である場合です。この場合、2 次曲線の制御点は以下のようになります:

> QP1 = CP0 + 3/2 * (CP1 - CP0)

私がネット上で読んだ他の情報源では、3 次スプラインに変曲点 (これは 2 次曲線には存在しません) があるかどうかをチェックし、そこで強制的に分割することを提案しています。私の目には、この方法は実際にはより悪い結果をもたらすように見えます。より多くの点が必要になり、近似結果は、変曲点を無視したときほど元の線に近くないように見えます。そういうわけで、その提案は無視することにしました。

## OpenType, もう一つの解決法

Adobe と Microsoft は TrueType フォントと PostScript フォントのどちらを格納することも可能なフォントフォーマットを作成することに決定しました。これは OpenType と呼ばれています。これは本質的には TrueType の拡張です。すべての TrueType フォントは正しい OpenType フォントですが、 OpenType フォントは PostScript を含むこともできます。OpenType をサポートするシステムではどれも、PostScript と TrueType の間の変換を必要としないでしょう。

### 参照

- FontForge の数学

1 Bézier スプラインは Pierre Bézier (1910-1999) によって開発されました。

― 前 ― 目次 ― 次 ―