2014年3月1日土曜日

バウンディングボックスと中心座標の取得

集中線エクステンション用に中心座標を取得した時のメモ。

メソッド

中心座標を回転中心に取ろうと思いバウンディングボックスの座標を取得しようと探していたら、simpletransformモジュールにroughBBox()、refinedBBox()、computeBBox()の3つのメソッドを見つけました。

roughBBox()はノードとハンドルの座標を基準に、refinedBBox()はパス形状を基準に、computeBBox()は選択オブジェクトを基準にそれぞれバウンディングボックスの最大最小座標を返します。

簡素ですがこの辺りにまとめました。

computeBBox()が一番使い勝手が良いと思いますが、今回はcubicsuperpath.parsePath()をすでに使用しているので、refinedBBox()を使います。

補正と例外処理

回転中心を移動させることで、集中線の中心も移動出来るようにしたいので、inkscape:transform-center-xyの値を取得して補正しています。

import inkex, simpletransform, cubicsuperpath
...
def getCenter(path):
  bbox = simpletransform.refinedBBox(cubicsuperpath.parsePath(path.get('d')))
  try:
    kx = float(path.get(inkex.addNS('transform-center-x', 'inkscape')))
  except:
    kx = 0
  try:
    ky = float(path.get(inkex.addNS('transform-center-y', 'inkscape')))
  except:
    ky = 0
  return [(bbox[0] + bbox[1]) / 2 + kx, (bbox[2] + bbox[3]) / 2 - ky]

Inkscape内部とSVGとでY座標の上下が反対になっているようで、Y座標の補正は符号が正負反対です。

この時、例外処理の使い道を初めて知った。

#before
  if float(path.get(inkex.addNS('transform-center-x', 'inkscape'))):
    kx = float(path.get(inkex.addNS('transform-center-x', 'inkscape')))
  else:
    kx = 0

Pythonは条件式で代入できないから、これまで上のように記述していた。
既出のエクステンションにもこの記述が溢れているが、戒めとして残しておく。

出力

こんな感じになりました。

パースをとるツールとしても使えそうな感じです。