Siv3Dで画像をステンドグラス風に加工する


この記事はhttps://qiita.com/advent-calendar/2020/siv3d 20日目の記事です。

概要

クリスマス前なので、画像をステンドグラス風に加工するサンプルを作りました。

結果

入力画像

出力画像

ソースコード

Main.cpp
# include <Siv3D.hpp>

void Main()
{
    Window::Resize(1280, 960);
    Scene::SetBackground(ColorF(0.99));

    //点群の生成
    double r = 10.0;
    PoissonDisk2D pd(Scene::Size(), r);

    //もとになる画像を用意
    Image image(U"image.png");
    image.resize(1280, 960);

    //ボロノイ図の生成
    const Rect rect(0, 0, Scene::Size());
    Subdivision2D subdiv(rect);
    Array<VoronoiFacet> facets;
    Array<Polygon> facetPolygons;

    for (const auto& point : pd.getPoints()) {
        if (rect.contains(point))
        {
            subdiv.addPoint(point);
        }
    }

    subdiv.calculateVoronoiFacets(facets);

    //ポリゴンを加工
    facetPolygons = facets.map([rect = rect.asPolygon()](const VoronoiFacet& f)
    {
        return Geometry2D::And(Polygon(f.points), rect).front();
    });



    while (System::Update())
    {
        for (auto [i, facetPolygon] : Indexed(facetPolygons))
        {
            const Vec2 pos = facets[i].center;

            facetPolygon.draw(image[static_cast<int32>(pos.y)][static_cast<int32>(pos.x)]).drawFrame(3, ColorF(0.25));
        }
    }
}