簡體   English   中英

Boost Geometry / intersection()似乎返回不一致的結果

[英]Boost Geometry / intersection() seems to return inconsistent result

我有一個3D矢量適合Boost幾何作為2D點,並作為一個環:

BOOST_GEOMETRY_REGISTER_POINT_2D(Vector3, float, cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_RING( std::vector< Vector3 > )

然后:

  1. 繪制一些非凸多邊形(
  2. 繪制線段,切割非凸多邊形並將其分為2(較小的多邊形通常為三角形)
  3. 在線段上鏡像較小的新2個多邊形

結果是兩個多邊形,它們重疊並具有1個切線邊緣。

然后我檢查兩個多邊形的交叉點。 在15%的情況下,交叉點結果是空的,這是一個驚喜(較小的多邊形可以有1.0f..10.f區域,所以它不是一個角落的情況)

std::deque< Polygon > output;
bg::intersection(bigger_Polygon, mirrored_over_cutting_lineseg_Polygon, output);
// output.size() == 0 in 15% of cases

可能是什么原因? 我在調用intersection()之前嘗試對每個多邊形執行boost :: geometry :: correct(),但它沒有幫助。 我的想法已經不多了

編輯::

我測試過是否創建新環,使用Boost Geometry類型和雙存儲類型將有助於:

void my_intersection( std::vector<Vector3>& polyA, std::vector<Vector3>& polyB, std::deque< ... > & output ) {
    typedef bg::model::d2::point_xy<double> point_type;
    bg::model::ring< point_type > ringA;
    bg::model::ring< point_type > ringB;

    for( int i = 0; i < (int) polyA.size(); i ++ ) {
        bg::append( ringA, bg::make< point_type >( polyA[i].x, polyA[i].y ) );
    }

    for( int i = 0; i < (int) polyB.size(); i ++ ) {
        bg::append( ringB, bg::make< point_type >( polyB[i].x, polyB[i].y ) );
    }
    ...
}

我為polyA,polyB(我的初始float Vector3)和ringA,ringB做兩個intersection()調用。 然后,出現不一致:

A[6]( 58.20822143554688 100.0000076293945 , 89.18041229248047 100.0000076293945 , 100.0000076293945 93.08255767822266 , 100 80 , 64.98564147949219 80 , 58.20822143554688 100.0000076293945 )
B[4]( 89.18040466308594 100 , 100 93.08255004882812 , 93.72125244140625 90.17939758300781 , 89.18040466308594 100 )
INFO: ------ 1 vs 0 ------ INCONSISTENCY

“1”表示:輸出deque的大小()== 1,因此發生交叉(這是針對ringA / ringB交集)。 “0”表示Vector3 - 空結果。

編輯2

使用具有浮點存儲類型的boost模型會導致ringA和ringB調用返回不正確的結果。 我確認了這一點。 我曾經困惑過,雙打不會改變錯誤的“邏輯”,但這是因為意外刪除了正確的()調用。 對於ringA / ringB冗余環的正確()調用和雙重存儲類型,我無法獲得空交集。

編輯3

以下是intersection()返回的5種情況:

  • 初始兩個響鈴的空結果(std :: vector <Vector3>),
  • 正確的結果size()== 1,首次創建std :: vector <>環的雙類型副本(使用boost :: geometry模型)。

情況1:

A[6]( 58.20822143554688 100.0000076293945 , 89.18041229248047 100.0000076293945 , 100.0000076293945 93.08255767822266 , 100 80 , 64.98564147949219 80 , 58.20822143554688 100.0000076293945 )

B[4]( 89.18040466308594 100 , 100 93.08255004882812 , 93.72125244140625 90.17939758300781 , 89.18040466308594 100 )

戒指1

案例2:

A[10]( 0 100 , 66.90238189697266 99.99999237060547 , 70.97279357910156 80 , 40 80 , 40 60 , 28.31221580505371 60 , 20 67.16078948974609 , 20 80 , 0 80 , 0 100 )

B[4]( 28.31221961975098 60.00000381469727 , 20.00000762939453 67.16079711914062 , 27.08192825317383 68.22066497802734 , 28.31221961975098 60.00000381469727 )

戒指2

案例3:

A[10]( 0 100 , 72.89675903320312 100 , 73.80842590332031 80 , 40 80 , 40 60 , 26.65167617797852 60 , 20 65.58068084716797 , 20 80 , 0 80 , 0 100 )

B[4]( 26.65167999267578 60.00000381469727 , 20.00000381469727 65.5806884765625 , 25.49577522277832 66.55047607421875 , 26.65167999267578 60.00000381469727 )

戒指3

案例4:

A[6]( 47.28099060058594 99.99999237060547 , 95.71660614013672 100 , 100 97.21295166015625 , 100 80 , 68.72442626953125 80.00000762939453 , 47.28099060058594 99.99999237060547 )

B[4]( 95.71659851074219 99.99999237060547 , 99.99998474121094 97.21293640136719 , 97.45189666748047 96.08384704589844 , 95.71659851074219 99.99999237060547 )

戒指4

案例5:

A[6]( 57.69097518920898 100 , 91.16551208496094 100 , 99.99999237060547 92.9193115234375 , 100 80 , 64.8609619140625 80 , 57.69097518920898 100 )

B[4]( 91.16550445556641 99.99999237060547 , 99.99998474121094 92.9193115234375 , 93.08920288085938 91.37748718261719 , 91.16550445556641 99.99999237060547 )

戒指5

編輯4

這是一個函數,用於在交叉線(x0,y0) - (x1,y1)上鏡像多邊形。 使用此功能創建切線邊緣 - 鏡像后,指向同一位置。

Vector3 mirror_point( Vector3 p, float x0, float y0, float x1, float y1 ) {
    float dx = x1 - x0;
    float dy = y1 - y0;

    float a = ( dx * dx - dy * dy ) / ( dx * dx + dy * dy );
    float b = 2.0f * dx * dy / ( dx * dx + dy * dy );

    float x2 = a * ( p.x - x0 ) + b * ( p.y - y0 ) + x0;
    float y2 = b * ( p.x - x0 ) - a * ( p.y - y0 ) + y0;

    return Vector3( x2, y2, p.z );
}

我對你輸入的分析:

第二個多邊形(以24.57開頭)是逆時針方向。 另外,第二組的第二個多邊形(從90.61開始)是逆時針的。 所以當然應該調用boost :: geometry :: correct。 它有所不同。

所以,如果我使用geometry :: correct,我會得到以下結果:

1)第一個組合,使用double:交集區域= 12.3854,一個幾何,4個點2)第一個組合,使用float:交集區域= 12.3854,一個幾何,4個點(相同)此結果與SQL Server的結果相同

3)第二個組合,使用double:交集區域= 34.7862,一個幾何,4個點4)第二個組合,使用float:交集區域= 34.7862,一個幾何,4個點此結果與SQL Server的結果相同。

請注意,在這兩種情況下,第二個多邊形都在第一個多邊形內(在第二種情況下不觸摸,在第一種情況下它是觸摸 - 根據SQL Server)。

所有輸出似乎都是正確的。 你提到:“消除空交叉點”,最近在Boost.Geometry中解決了這個問題。 該修復程序尚未在1.52中發布,但將在1.53中發布。 因此,如果這是特定問題,則必須使用Boost.Trunk的版本。

但是,這不會導致空輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM