Siv3D / OpenSiv3D

C++20 framework for creative coding 🎮🎨🎹 / Cross-platform support (Windows, macOS, Linux, and the Web)
https://siv3d.github.io/
MIT License
994 stars 136 forks source link

LineString::calculateRoundBuffer() でサイズが1のときに円を返す提案 #1209

Closed Raclamusi closed 1 month ago

Raclamusi commented 5 months ago

サイズが1の LineString に対して .calculateRoundBuffer() を呼んだとき、現在は空のポリゴンが返りますが、円のポリゴンを返すようにすることを提案します。 この方がより自然な挙動だと思います。

# include <Siv3D.hpp>

void Main()
{
    const LineString lineString
    {
        Vec2{ 400, 300 },
    };

    // 円ができるほうが自然ではないか?
    const auto polygon = lineString.calculateRoundBuffer(10);

    while (System::Update())
    {
        polygon.draw();
    }
}

実装は、以下のコードの条件を points.size() < 1 に変更するだけです。

https://github.com/Siv3D/OpenSiv3D/blob/a5a6d7bf1e0399a53607eebd956472fd15026c55/Siv3D/src/Siv3D/Polygon/PolygonDetail.cpp?ts=4#L1293-L1296

Reputeless commented 5 months ago

良さそうです。PR お願いします。

Reputeless commented 5 months ago

PR ありがとうございます。これは .calculateRoundBuffer() だけでなく .calculaeBuffer() も 1 頂点に対応したいですね。やってみて問題が無さそうであれば後者もお願いします。

Raclamusi commented 5 months ago

1頂点の .calculaeBuffer() は、下図のようにポリゴンが潰れてしまうから空のポリゴンを返す方が自然だと思っていたので、.calculateRoundBuffer() についてのみ提案しました。

スクリーンショット

しかし、boost::geometry::buffer() は1頂点の linestring に対して正方形を返します。 そもそも向きが定まらないので潰れようがないという解釈をすると、こちらの方が自然なのかもしれません。

何より、ある Vec2 型変数 p について LineString{ p }.calculateBuffer()LineString{ p, p }.calculateBuffer() の結果は等しいほうが良いと思うので、.calculateBuffer() についても実装してみます。