OpenSiv3D
OpenSiv3D copied to clipboard
LineString::calculateRoundBuffer() から空の Polygon が返ることがある
特定の状況で LineString::calculateRoundBuffer() から空の Polygon オブジェクトが返ります。
Polygon/PolygonDetail.cpp の s3d::detail::CalculateRoundBuffer() を覗いてみると、PolygonFailureType::SelfIntersections で Polygon の作成に失敗しているようです。
以下のコードで再現します。
# include <Siv3D.hpp>
void Main()
{
const LineString lineString
{
Vec2{ 0, 85 },
Vec2{ 10, 18 },
Vec2{ 10, 0 },
Vec2{ 10, 84 },
Vec2{ 18, 26 },
};
const auto polygon = lineString.calculateRoundBuffer(10);
Print << polygon.isEmpty(); // true
while (System::Update())
{
}
}
ご報告ありがとうございます。調査します。
この問題、Boost 1.78.0 では修正されてそうです。
Wandbox 上の Boost で実験しました。 https://wandbox.org/permlink/lw5WQpxdtb7SrZJi
# include <Siv3D.hpp> // OpenSiv3D v0.6.13
void Main()
{
const Polygon polygon
{
Array{
Vec2{ 0x1.da5b167041beap+2, -0x1.3518a4c8d776ep+3 },
Vec2{ 0x1.4000000000002p+3, -0x1.4p+3 },
Vec2{ 0x1.92d274c7df20ep+3, -0x1.3518a4c8d776cp+3 },
Vec2{ 0x1.e000000000001p+3, -0x1.1520cd1372feap+3 },
Vec2{ 0x1.112318007c2bp+4, -0x1.c48c6001f0abfp+2 },
Vec2{ 0x1.2a906689b97f5p+4, -0x1.3ffffffffffffp+2 },
Vec2{ 0x1.3a8c52646bbb7p+4, -0x1.4b49d31f7c834p+1 },
Vec2{ 0x1.4p+4, 0x0p+0 },
Vec2{ 0x1.4p+4, 0x1.0448bfcae540fp+4 },
Vec2{ 0x1.5e23c4390f756p+4, 0x1.0c8f45622289ap+4 },
Vec2{ 0x1.822ec6f705ac2p+4, 0x1.21aa9fd99fd8ep+4 },
Vec2{ 0x1.9f88e4f6a32d8p+4, 0x1.3f61fd35a3693p+4 },
Vec2{ 0x1.b4320b1a72693p+4, 0x1.63aeef8d814d6p+4 },
Vec2{ 0x1.bec1c7036c0c3p+4, 0x1.8c182a58c5b73p+4 },
Vec2{ 0x1.be7fd769845ecp+4, 0x1.b5dcaaf412421p+4 },
Vec2{ 0x1.3e7fd769845ecp+4, 0x1.55772abd04908p+6 },
Vec2{ 0x1.3423f6d7edb29p+4, 0x1.5f1ce71b328dp+6 },
Vec2{ 0x1.208b1336f23fdp+4, 0x1.67d15dc550191p+6 },
Vec2{ 0x1.04ee097012ca3p+4, 0x1.6f099613c1b82p+6 },
Vec2{ 0x1.c60b608ee1c35p+3, 0x1.74524dd439f68p+6 },
Vec2{ 0x1.79deb50879f59p+3, 0x1.7757295a03af5p+6 },
Vec2{ 0x1.2a1629cc424b5p+3, 0x1.77e7f63d88cdap+6 },
Vec2{ 0x1.b756eb5b83e4ap+2, 0x1.75fbacceb66bap+6 },
Vec2{ 0x1.7b5aa7bfab8cep+2, 0x1.743305bf80afdp+6 },
Vec2{ 0x1.d559f3728eb97p+1, 0x1.7936c063dd96ap+6 },
Vec2{ 0x1.224a8180b330dp+0, 0x1.7bbdf3b177fcfp+6 },
Vec2{ -0x1.79e74d0b94169p+0, 0x1.7b8fd077364d9p+6 },
Vec2{ -0x1.fe2c1b1908c32p+1, 0x1.78af7b9f7fe33p+6 },
Vec2{ -0x1.8e500dba1d7b8p+2, 0x1.734f232faf464p+6 },
Vec2{ -0x1.01328ccbe8b34p+3, 0x1.6bcc92d8afb6ep+6 },
Vec2{ -0x1.29b6031eecb4dp+3, 0x1.62aacf9b9475dp+6 },
Vec2{ -0x1.3def9d8bbfe78p+3, 0x1.58892a0602ccdp+6 },
Vec2{ -0x1.3c7e83b9b26c7p+3, 0x1.4e1862cbd1afap+6 },
Vec2{ -0x1.a3055eba6p-21, 0x1.142024301c9d7p+4 },
Vec2{ 0x0p+0, 0x1.cf8282013467cp-49 },
Vec2{ 0x1.5ceb66e51125cp-2, -0x1.4b49d31f7c83p+1 },
Vec2{ 0x1.56f99764680a9p+0, -0x1.3ffffffffffffp+2 },
Vec2{ 0x1.76e73ffc1ea82p+1, -0x1.c48c6001f0acp+2 },
Vec2{ 0x1.4000000000002p+2, -0x1.1520cd1372febp+3 },
},
};
Print << polygon.isEmpty(); // false
while (System::Update())
{
polygon.draw(200, 200);
}
}