ホーム ] TIPS ウィンドウズ系 ] TIPS グラフィックス系 ] TIPS メルチメディア系 ] TIPS 理数系 ] TIPS 総覧 ]

上へ
G0001 色名一覧
G0002 アルファブレンド
G0003 カラーマップを作る
G0101 曲線の数値化
G0102 曲線長を測る
G0103 曲線の接線・法線
G0104 曲線のスムージング
G0201 図形の回転
G0202 領域の認識
G0301 文字の線形変換
G0302 文字の自由変形
G0303 文字の極座標変換
G0304 曲線に沿った文字列
G0305 飾文字-中抜き
G0306 飾文字-縁取り
G0307 飾文字-ドロップダウンシャドウ
G0501 画像の線形変換
G0502 画像の透明化
G0503 画像の任意形状切出し
G0504 画像の回転
G0505 画像の高速処理化

VB.NET2005 TIPS / グラフィックス系

G0303 文字の極座標変換

最終更新:2006/11/12 再掲

●解説

 グラフを極座標で描くように文字列を描く。元のXY座標の点をXY平面で表した極座標の点に写像することになる。


楕円での実例

●原理

○変換式

 X軸を角度θ、Y軸を距離rに変換する。結果を再び、X-Yで表すと、 

 X = g(y) * Cos(f(x))
 Y = g(y) * Sin(f(x)) 

となる。g()はyを、f()はxをθにそれぞれマッピングする関数である。 

○変換元

 文字は描画はできるが、そのままでは演算対象にならない。一番簡単な方法は、描画される文字を点集合にするものである。これには、GraphicPath オブジェクトを利用する。

●方法

 元の関数(ここでは文字列)をGraphicPathにてPoint配列に変換する。従って、任意の図形が対象となる。

1.         オブジェクトをPoint配列にする。

2.         xの範囲を角度の範囲にマッピングする。今全角度をaとすると、
θi = (xi
xmin) * (a/(xmax-xmin)) + θoffs

3.         yは結果の円の半径Rを考慮して決める。
ri = R + b * yi など。

4.         極座標の原点(円の中心)をXc、Yc、半径をRとし、全角度をaラジアン、また、簡単のためPoint配列(po())の原点が左下とすれば、
θi = (po(i).X
xmin) * (a/(xmax-xmin)) + θoffs
Xi = (R + po(i).Y) * cos(θi) + Xc
Yi = (R + po(i).Y) * sin(θi) + Yc 

文字列をGraphicPath にするには、以下のようにする。

Dim pa As New GraphicsPath()          '空白のパスオブジェクト
pa.Reset()                                    '念のため空白にしておく
pa.AddString("内容", フォント指定, フォント属性, フォントサイズ, ポイント配列, 描画フォーマット)                                     'パスに文字列を描画する
pa.CloseFigure()                             '描画終了
pa.Flatten                                     '描画したものを全て直線化する
re = pa.GetBounds
Dim pps() As PointF = pa.PathPoints   
完全なPoint配列にする

このpps()が演算対象となる。

文字として描くには、このpps を再びパス化する必要がある。

pa = New GraphicsPath(pps, pa.PathTypes)

PathTypes は、点の性質を記述したバイト配列である。この記述により文字としての集合が明らかになる。

●実例 

○例1:円の全周に乗っかった文字列の例 

gはGraphics、Xc、Ycは円の中心点とする。

Dim ds As String = " 円に沿った文字列です"     'スペースを文字とするため、最後尾を先頭にする。
fmt.Alignment = StringAlignment.Near
fmt.LineAlignment = StringAlignment.Near
Dim R As Single = 120
g.DrawEllipse(Pens.Black, New RectangleF(Xc - R, Yc - R, 2 * R, 2 * R))
Dim pa As New GraphicsPath()
Dim re As RectangleF, fh As Single = f.GetHeight(g)
pa.Reset()
pa.AddString(ds, New FontFamily("MS Pゴシック"), CInt(FontStyle.Regular), fh, New PointF(0, 0), fmt)
pa.CloseFigure()
pa.Flatten
re = pa.GetBounds
Dim pps() As PointF = pa.PathPoints                  
文字列をパス化し、Point配列にする
Dim i As Integer, ra As Double, K As Double = 2 * PI / re.Width
Dim YY As Single
For i = 0 To pps.GetLength(0) - 1
   ra = pps(i).X * K + PI
   YY = fh - pps(i).Y                  
実際には、文字は半径方向と逆なので反転する。
   pps(i).X = (R + YY) * Cos(ra) + Xc             
円の内側にぶら下がる場合は、(R pps(i).Y)とする
   pps(i).Y = (R + YY) * Sin(ra) + Yc

Next
pa = New GraphicsPath(pps, pa.PathTypes)      
Point配列を再びパス化する。でないと文字として見えない。
g.FillPath(Brushes.Red, pa)
pa.dispose() 

○例2:楕円上に乗っかった文字列 

1のRを変更すれば、楕円となる。 

pps(i).X = (R + YY) * Cos(ra) + Xc
pps(i).Y = (R / 2 + YY) * Sin(ra) + Yc