10

コミュニティ。

ここには多くの回答、インターネット上のマニュアル、チュートリアル、リファレンスがあり、この質問についてはさらに多くの情報があることを知っています。また、線形代数の知識が必要であることも知っています。しかし、すべての理論を理解し、実際に演習を解決する時間について考えると、頭が吹き飛ばされて、最も単純なことを行うことができなくなります:(

テキストをレンダリングする前に、テキストを中心に回転させる方法を少し簡単に知っている場合は、教えてください。

今のところ私は持っています:

#...
cr.move_to(*text_center)
myX, myY = text_center[0] - (width / 2), text_center[1] + (height / 2)

cr.save()
cr.translate(myX, myY)
cr.rotate(radians(text_angle))
cr.show_text(letter)
cr.restore()
#...

しかし、私の手紙はそれ自身の周りを回転していません。それはちょうど右側に落ちるようなものです :( 自分のコードが正しくないことはわかっています。変換を見逃しているのかもしれませんが、それを正しくする方法がわかりません。

更新:残念ながら、テキストは翻訳の影響を受けないため、

cr.translate(10000, 10000)
cr.rotate(radians(15))
cr.show_text("hello")

とまったく同じになります

cr.rotate(radians(15))
cr.show_text("hello")

そして、新しい表面や何か(グラフィックプロセッサの新しいレイヤーなど)を作成せずに、その中心でテキストを回転させる方法がわかりません:(

4

4 に答える 4

13

少なくとも私のマシン (1.8.8) で利用可能な cairo のバージョンでは、次のアプローチが機能します。

def text(ctx, string, pos, theta = 0.0, face = 'Georgia', font_size = 18):
    ctx.save()

    # build up an appropriate font
    ctx.select_font_face(face , cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    ctx.set_font_size(font_size)
    fascent, fdescent, fheight, fxadvance, fyadvance = ctx.font_extents()
    x_off, y_off, tw, th = ctx.text_extents(string)[:4]
    nx = -tw/2.0
    ny = fheight/2

    ctx.translate(pos[0], pos[1])
    ctx.rotate(theta)
    ctx.translate(nx, ny)
    ctx.move_to(0,0)
    ctx.show_text(string)
    ctx.restore()

次の方法で使用できます。

width = 500
height = 500
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height)
ctx = cairo.Context(surface)
ctx.set_source_rgb(1,1,1)
rect(ctx, (0,0), (width, height), stroke=False)
ctx.set_source_rgb(0,0,0)
for i in xrange(5):
    for j in xrange(5):
        x = 100 * i + 20
        y = 100 * j + 20
        theta = math.pi*0.25*(5*i+j)
        text(ctx, 'hello world', (x, y), theta, font_size=15)
surface.write_to_png('text-demo.png')

text-demo.png

于 2013-06-26T13:29:09.147 に答える
6

さて、カイロはテキストのmove_toとrotateを許可します。これは、(R) を回転させたときにテキストの中心点が目的の位置 c=(cx,cy) になるように、move_to (T) の (x,y) を計算する必要があることを意味します。

ここに画像の説明を入力

したがって、式 Mv = c を解く必要があります。ここで、v はテキストの原点に対するテキストの中心です。

M = T*R

T = (1 0 x)
    (0 1 y)
    (0 0 1)

R =  (cos r    -sin r   0)
     (sin r     cos r   0)
     (0            0    1)

v = (w/2, h', 1)

c = (cx, cy, 1)

h' = h/2 - (h - y_bearing)

健全性チェック:

  • r が 0 (回転なし) の場合、x=cx-w/2, y=cy-h' となり、これが正解です。
  • r=-90 (テキストを横向き、「上」を右に向ける) の場合、期待どおりの結果が得られます。つまり、x = cx - h' および y = cy + w/2 です。

Python コードの場合、上記の式を書き直して、t=(x,y) である A*t=b になるようにし、t = inv(A)*b を計算する必要があります。次に、あなたは単に行うでしょう

cr.move_to(x, y)
cr.rotate(r)
cr.show_text(yourtext)

cairo の座標系は +y が下がっているため、修正すべき兆候がいくつかあることに注意してください。また、y_bearing が正しくない可能性もありますが、おわかりいただけると思います。

于 2011-12-12T04:35:20.630 に答える
1

したほうがいい

myX, myY = text_center[0] + (height / 2), text_center[1] - (width / 2)

なれ

myX, myY = text_center[0] - (width / 2), text_center[1] + (height / 2)

それはなぜそれが右側に落ちているのかを説明するかもしれません。

于 2011-12-11T11:06:17.667 に答える