文字を三角形に分割

ここ一週間は仕事とも、卒論とも関係ない(使いどころはあるけど)アウトラインフォントの三角形分割をやっていました。
使い道は当然、文字列をポリゴンで描画したいからです。
DirectXには文字列をから3Dフォント(立体文字)生成するメソッドがあるのですが、「あまり奇麗でない・生成に時間がかかる・Meshとして返ってくるため加工しづらい」といった理由でいまいち使い勝手がよくありません。
文字列の縁取りをして描画したいので、元のアウトラインデータが必要ですし、特に立体である必要もないので自分でやってみることにしました。(まさかこんなに深みにハマるとは…)


まず、フォントのアウトラインデータの取得ですが、ちょっと手を抜いて.NETのGraphicsPathを利用しました。AddStringで文字列をパスに追加して、PathPointsとPathTypesを取得すれば、アウトラインの点列が取得できます。あとから分かったのですが、GraphicsPathのFlattenメソッドを使えば、ベジェ曲線を直線に分割してくれるようで、自分で曲線の分割をしなくても済みました。


そこらか、閉じたパス(穴のあいた部分も含む)を取得して、穴あき凹多角形の三角形分割を行います。
穴あき凹多角形の三角分割は…ネットで検索して出てきたパワーポイントのスライドを元に、アルゴリズムをちょっと改良して分割しました。まぁ、今でも仕組みはよく分かりませんが、そこそこうまく行きました。こういうこと(テセレーション?)を行ってくれるメソッドって、DirectXにはないのかな。。。
で、結果がこれ。

GDI+で三角形を描画しています。境界線を表示するとこんな感じ。

漢字なんかもうまくいきます。

おまけの、デバック用表示



ちなみに、DirectXの3Dフォントを使った例がこれ。

もう少し奇麗にできたような気もしますが、カクカクしてあまり奇麗ではないですね。(ちなみに、上の文字はドローネ分割を試してみて失敗した例です)


とかちつくちて」をDirectXの3Dフォントを使って生成すると10msec程度かかる(まぁ、そのほかにもUV座標の添加とかしてますが)のに対して、今回作ったものでは5msec程度で生成できました。GraphicsPathのFlattenの値にもよりますが、今回作った方が速いし滑らかです。


実はまだまだバグが取れていないとか、もう少し速くする見込みがあるとか色々ありますが、とりあえずここら辺で切りを付け用と思います。GraphicsPathを使っているので、文字以外の図形も分割してポリゴンで表示できそうです。




卒論の中間報告を書かなきゃいけないのに、この実装に一週間近くかかってしまった。やばい。