LoginSignup
7
2

More than 3 years have passed since last update.

Rustとsvg

Last updated at Posted at 2020-12-22

Rustをsvg形式で書き出す。

Rust 3 Advent Calendar 2020 22日目の記事です。

Qiita初投稿です。
Rustを使ってクレート開発とsvg形式で書き出したという話です。

こんな感じの画像を書き出します。

testPolygon1.png

Qiitaではsvg形式は貼り付けられないのでpng形式です。リポジトリにはsvg形式の画像もあります。

なおこの記事ではsvgとは何か?と言うような説明はしません。

リポジトリ

すべてGithubにおいています。

Rust version

Python version

Python versionのほうが開発は進んでいます

開発目的

1.Rustの勉強
2.svgの勉強
3.イラスト制作のため

以上この3つです。

polygonの実装

svgにはいくつものタグが存在しますがpolygonタグ1つに絞って実装しました。

pub mod polygon {
    use crate::point::point::Point;
    use crate::convert_str::convert_str::*;
    ///# Polygonを表す構造体
    pub struct Polygon {

        data: Vec<Point>,
    }

    impl Polygon {
        /// ## 変数の初期化を行う(コンストラクタ)
       /// ### variable
       /// init_data : Vec<Point> ポリゴンデータの初期化
       /// ### Example
       /// let polygon1 = Polygon::new(0.0, 0.0)
       ///
        pub fn new(init_data: Vec<Point>) -> Polygon {

            Polygon { data: init_data }
        }
    }


    impl Polygon {
        /// ## ポリゴンタグデータの取得
        /// 設定パラメータ fill fill-opacity
        /// fill_color: fill
        /// fill_opacity: fill-opacity
        ///
        pub fn render_polygon1(self, fill_color: String, fill_opacity: f64) -> String{
            let str_data = format_one(self.data);
            let start = "<polygon";
            let location_data = format!("points=\"{}\"", str_data);
            let fill_set = format!("fill=\"{}\" fill-opacity=\"{}\"",
                                   fill_color, fill_opacity);
            let end = "/>\n";
            let poly1 = format!("{} {} {} {}", start, location_data, fill_set, end);

            return poly1;
        }
    }

    impl Polygon {
        /// ## ポリゴンタグデータの取得
        /// 設定パラメータ fill fill-opacity stroke stroke-width stroke-opacity
        /// fill_color: String fill
        /// fill_opacity: f64 fill-opacity
        /// stroke_color: String stroke
        /// stroke_width: f64 stroke-width
        /// stroke_opacity: f64 stroke-opacity
        ///
        pub fn render_polygon2(self, fill_color: String, fill_opacity: f64,
                               stroke_color: String, stroke_width: f64, stroke_opacity: f64) -> String{
            let str_data = format_one(self.data);
            let start = "<polygon";
            let location_data = format!("points=\"{}\"", str_data);
            let fill_set = format!("fill=\"{}\" fill-opacity=\"{}\"",
                                   fill_color, fill_opacity);
            let stroke_set = format!("stroke=\"{}\" stroke-width=\"{}\" stroke-opacity=\"{}\"",
                                     stroke_color, stroke_width, stroke_opacity);
            let end = "/>\n";
            let poly2 = format!("{} {} {} {} {}", start, location_data, fill_set, stroke_set, end);

            return poly2;
        }
    }

    impl Polygon {
        /// ## ポリゴンタグデータの取得
        /// 設定パラメータ stroke stroke-width stroke-opacity
        /// stroke_color: String stroke
        /// stroke_width: f64 stroke-width
        /// stroke_opacity: f64 stroke-opacity
        pub fn render_polygon3(self, stroke_color: String, stroke_width: f64, stroke_opacity: f64) -> String{
            let str_data = format_one(self.data);
            let start = "<polygon";
            let location_data = format!("points=\"{}\"", str_data);
            let fill_set = format!("fill=\"transparent\"");
            let stroke_set = format!("stroke=\"{}\" stroke-width=\"{}\" stroke-opacity=\"{}\"",
                                     stroke_color, stroke_width, stroke_opacity);
            let end = "/>\n";
            let poly3 = format!("{} {} {} {} {}", start, location_data, fill_set, stroke_set, end);

            return poly3;
        }
    }
}

1つ注意点なのはpolygonタグでの座標データの取り扱いは1つの文字列にまとめていかないといけないということです。

それほど難しくないですがsvgの仕様を知らないとうまく出力されてもsvg側でエラーが出てしまうので注意が必要です。

ソースコードにある

format_one(self.data);

は複数のデータを1つにまとめているユーリティ関数です。

三角形の描画

三角形の描画するコードの1部です

pub mod triangle {
    use crate::point::point::Point;
    /// # 三角形の作成
    /// 大きさはsvg画像サイズに依存する。
    pub struct Triangle {
        width: f64,
        height: f64,
    }

    impl Triangle {
        /// ## 変数の初期化を行う(コンストラクタ)
        /// ### variable
        /// init_width: f64 画像サイズ 横幅
        /// init_height: f64 画像サイズ 高さ
        pub fn new(init_width: f64, init_height: f64) -> Triangle {

            Triangle { width:init_width, height: init_height }
        }
    }

    impl Triangle {
        pub fn triangle1(&self) -> Vec<Point> {
            let mut data: Vec<Point> = vec![];
            let x = [0.0, self.width / 2.0, self.width];
            let y = [self.height, 0.0, self.height];
            if x.len() == y.len() {
                for count in 0..3 {
                    let tmp = Point::new(x[count], y[count]);
                    data.push(tmp);
                }
            }

            return data
        }
    }
}

三角形を描画するコード

まとめと反省点

  1. main.rsとlib.rsが同じ階層に有る。
  2. ディレクトリによる分別と管理を行う。
  3. lib.rsに何か書かれている。
  4. svgとしてしっかり?出力されている。

など上げたらきりがないのでここまでとします。

クレート開発とsvgの勉強をし直してきます。

アップデート情報

2020/12/27 Githubリンクの修正とrect lineの追加

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2