C++入門/Scalable Vector Graphics

柴田祐樹,東京都立大学,情報科学科
戻る

ここでは Scalable Vector Graphics (SVG)に出力する方法をかんたんに紹介する.ファイルに文字列を出力する知識があるとする.

SVG とは線分や円など基本的幾何学図形を組み合わせて絵を描く命令を,文字列で記述したテキストファイルである.記述の形式には Extensible Markup Language (XML)を用いている.XMLが読み込めるプログラムならば,SVGに特化していなくても内容を編集できるという扱いやすい形式となっている.

以下はかんたんだが,放物線を描く例である.

#include <iostream>
#include <fstream>
using namespace std;

int main(){
    ofstream of("10th.svg", ios::out);

    of << "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-2 -2 4 4\">\n";
    // Header,viewBox= x, y 座標の開始位置,幅,高さ
    double x_p = 0;
    double y_p = 0;
    double n = 8;
    for(double i=0;i<n;++i){
        double x = x_p + 1.0/n;
        double y = x*x;
        // 線分を描画する.2点必要なため,x, y, x_p, y_p を用意する.
        // y 座標は上下反転
        of << "<line x1=\"" << x_p << "\" y1=\"" << -y_p
              << "\" x2=\"" << x << "\" y2=\"" << -y
              << "\" style=\"stroke:rgb(0,0,0);stroke-width:0.002\" />\n";
        x_p = x;
        y_p = y;
    }
 

出力されたファイルはテキストエディタで開くと次のようになるはずである.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1.5 -1.5 4 2">
<line x1="0" y1="-0" x2="0.125" y2="-0.015625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.125" y1="-0.015625" x2="0.25" y2="-0.0625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.25" y1="-0.0625" x2="0.375" y2="-0.140625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.375" y1="-0.140625" x2="0.5" y2="-0.25" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.5" y1="-0.25" x2="0.625" y2="-0.390625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.625" y1="-0.390625" x2="0.75" y2="-0.5625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.75" y1="-0.5625" x2="0.875" y2="-0.765625" style="stroke:rgb(0,0,0);stroke-width:0.002" />
<line x1="0.875" y1="-0.765625" x2="1" y2="-1" style="stroke:rgb(0,0,0);stroke-width:0.002" />
</svg>

これはファイルに保存しておけば,Webブラウザで開くことができ,次のように表示されるはずと思う.余白がやたらと大きいが,これは,のviewBoxのあとに設定している値で調節することができる.気になる方はここをいじられたい.

放物線では少し分かりづらいだろうから,四角形を描く例を,こちらはプログラムが分かりづらくなるのであるが,以下に示す.他にもう少し良い例があれば教えていただきたい.

#include <iostream>
#include <fstream>
using namespace std;

int main(){
    ofstream of("out.svg", ios::out);

    of << "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-1.5 -1.5 4 2\">\n";
    // Header,viewBox= x, y 座標の開始位置,幅,高さ
    double x[4] = {0, 1, 1, 0};
    double y[4] = {0, 0, 1, 1};
    double x1 = x[3];
    double y1 = y[3];
    for(int i=0;i<4;++i){
        double x2 = x[i];
        double y2 = y[i];
        // 線分を描画する.2点必要なため,x, y, x_p, y_p を用意する.
        // y 座標は上下反転
        of << "<line x1=\"" << x1 << "\" y1=\"" << -y1
              << "\" x2=\"" << x2 << "\" y2=\"" << -y2
              << "\" style=\"stroke:rgb(0,0,0);stroke-width:0.002\" />\n";
        x1 = x2;
        y1 = y2;
    }
    of << "</svg>\n";
}

初学者は,出力が絵で見てわかる方法を何かしら用意したほうがいい.Excelによるグラフの描画は無いよりはいいが,自由度が低すぎるため,他の方法もあったほうが良い.SVGは少し自由度が高すぎるとおもうが,できないよりはマシで,ソフトウェアの操作方法を覚える手間も無いことからかんたんなため,おすすめである.SVGは他にも楕円を描けたり,色々できる.以下は私が描いた絵である.Inkscapeを使い描かれている.

https://krectmt3.sd.tmu.ac.jp/ProBaseII/