座標変換
先述しましたが、基本的に画像を描く際は左上を原点 (0, 0) としており、右下に向かい X 軸、 Y 軸の値が増加していきます。
MFC(GDI+) では座標の変換により通常のグラフと同じ座標系に変更することができます。
しかし、 SVG では通常のグラフと同じ座標系にはできません。
SVG で可能なのはそれぞれの個別タグにて行う座標変換のみとなります。
本稿ではグラフの座標系から画像座標系への変換方法とタグ個別の座標変換について説明を行います。
グラフ座標系から画像座標系への変換
計算方法は「MFCからSVGの基本図形」に記載してありますが、ここでは詳しく解説していきます。
通常グラフから部分的に SVG 画像へ書き出しを行うため、描画する範囲の座標が必要となります。
必要な値がグラフ座標の描画範囲に位置する左下の点 (Left, Top) と右上の点 (Right, Bottom) の値になります。こちらを m_rectAll にて保持しておきます。
class SvgImage
{
protected:
CString m_strFilePath; // ファイル名
CArray<mdSvgTag*, mdSvgTag*> m_arrayTag; // タグ
Rect m_rectAll; // viewport
public:
SvgImage();
~SvgImage();
}
グラフ上の任意の点 A (Ax, Ay) を画像の座標系に変換するとします。
X 軸はそのまま反映されるため左端を原点にすればよいですから、 Ax から m_rectAll.left の値を引き算します。
- A'x = Ax - m_rectAll.left
Y 軸はグラフの座標系から画像の座標系で上下反転する必要があります。m_rectAll.bottom を画像の座標系で Y 軸の原点にするため計算式は以下の通りとなります。
- A'y = m_rectAll.bottom - Ay
※グラフ系が上下反転するに伴い、回転角度も反転する必要があることに注意してください。上下が反転するため、回転の縦軸計算が反転します。
SVG タグ個別の座標系変換
タグ個別の座標系返還には transform 属性を利用します。
MFC から書き出しする場合、MFC で変換している順に合わせて transform 属性の関数呼び出しを行う必要があります。
MFC 、SVG ともに座標を指定しなければ原点を中心に回転が行われます。
MFC で回転を行いたい場合、原点を回転する中心点へ平行移動し、座標全体を回転させ描画したあと、元に戻すという方法をとることが多いかと思います。
SVG への書き出しも同様に行います。
<text x="0" y="0" font-size="20" font-family="Verdana"
fill="blue" transform="translate(50,50)rotate(30)">
ABC (rotate)
</text>
拡縮や斜め変形などは必ず平行移動や回転の後に行うようにしてください。
拡縮や斜め変形を先に宣言すると平行移動や回転角がずれを発生させてしまう恐れがあります。
なお、塗パターンなどの pattern タグの場合属性名が patternTransform になります。
個別タグの座標変換関数
class SvgImage
{
public:
+ void AddAttrTransform(CPoint pnTrans, int nDegree);
}
void SvgImage::AddAttrTransform(CPoint pnTrans, int nDegree)
{
CString strTransform;
strTransform.Format(L"translate(%.03lf,%.03lf)rotate(%d)",
pnTrans.x, pnTrans.y, -nDegree);
AddAttribute(L"transform", strTransform);
}