2017-07-12 31 views
2

我正在使用Boost :: Geometry :: Buffer創建不規則形狀多邊形的內部偏移量或膨脹。下圖顯示了一個示例輸入和輸出。原始多邊形顯示爲白色,偏移多邊形顯示爲紫色。紫色多邊形右側有兩組外部線條(看起來像是較厚/較亮的區域),左邊是一個很長的無關尖峯。使用Boost幾何體進行多邊形緩衝時結果不正確或不正確

Example output from Boost::Geometry::Buffer

在例子中使用的多邊形是非常基本的。它缺乏任何對稱性,但沒有急轉彎或鋸齒狀邊緣。對於輸入多邊形的原始數據是笛卡爾點名單:

x: 61.2101898, y: 81.9854202 
x: 61.3715706, y: 82.0616913 
x: 61.4335442, y: 82.1924744 
x: 61.4778328, y: 82.2606735 
x: 61.5202942, y: 82.3236465 
x: 61.5283432, y: 82.3527832 
x: 61.5431557, y: 82.4063950 
x: 61.5221367, y: 82.4381790 
x: 61.3944855, y: 82.4706116 
x: 61.3497124, y: 82.4679184 
x: 61.3284111, y: 82.4674301 
x: 61.1539803, y: 82.3401947 
x: 61.1297760, y: 82.2854843 
x: 61.0671043, y: 82.1489639 
x: 61.0682831, y: 82.0264740 
x: 61.0667953, y: 82.0112915 
x: 61.0663414, y: 82.0066376 
x: 61.0707321, y: 81.9976196 
x: 61.0998306, y: 81.9980850 
x: 61.2101898, y: 81.9854202 

這是我使用來產生偏移多邊形代碼:

namespace bg = boost::geometry; 
typedef bg::model::d2::point_xy<float> BoostPoint; 
typedef bg::model::polygon<BoostPoint> BoostPolygon; 
typedef bg::model::multi_polygon<BoostPolygon> BoostMultipolygon; 

std::vector<BoostPoint> points; 
BoostPoint tmpPoint; 
BoostPolygon input; 
BoostMultipolygon output; 

/* currentContour is a pointer to a non-Boost specialized polygon 
* structure. It contains a bool indicating clockwise/counterclockwise 
* direction and a list of lines, each line defined by two x-y points. 
* For each line, point 2 follows point 1 in the clockwise/counterclockwise 
* direction of that polygon. 
*/ 

if (currentContour->clockwise) { 
    for (int line = 0; line < currentContour->lines.size(); line++) { 
     bg::set<0>(tmpPoint, currentContour->lines[line].x1); 
     bg::set<1>(tmpPoint, currentContour->lines[line].y1); 
     points.push_back(tmpPoint); 
    } 
    // Add last point to wrap back around to starting point. 
    bg::set<0>(tmpPoint, currentContour->lines.back().x2); 
    bg::set<1>(tmpPoint, currentContour->lines.back().y2); 
    points.push_back(tmpPoint); 
} 
else { 
    for (int line = currentContour->lines.size() - 1; line >= 0; line--) { 
     bg::set<0>(tmpPoint, currentContour->lines[line].x2); 
     bg::set<1>(tmpPoint, currentContour->lines[line].y2); 
     points.push_back(tmpPoint); 
    } 
    // Add last point to wrap back around to starting point. 
    bg::set<0>(tmpPoint, currentContour->lines.front().x1); 
    bg::set<1>(tmpPoint, currentContour->lines.front().y1); 
    points.push_back(tmpPoint); 
} 

// Transfer points to polygon object. 
bg::assign_points(input, points); 
// Declare boost strategies for buffer function. 
bg::strategy::buffer::distance_symmetric<double> distance_strategy(-0.05); 
bg::strategy::buffer::join_miter join_strategy; 
bg::strategy::buffer::end_round end_strategy; 
bg::strategy::buffer::point_circle point_strategy; 
bg::strategy::buffer::side_straight side_strategy; 
// Perform polygon buffering. 
bg::buffer(input, output, distance_strategy, side_strategy, join_strategy, 
    end_strategy, point_strategy); 

加速是一個重大的信譽庫,所以我很難相信它的幾何API會在多邊形上失敗如此簡單。爲什麼我得到那些無關的線?如果有任何其他信息會有幫助,我會很樂意提供。

+0

「萬一有用」的原始數據。什麼。這是最有用的一點。 – sehe

+2

Geez。誰是建設性的。或者跳動。我很抱歉我花了時間。我猜? – sehe

+1

@ChrisD如果你知道問題是什麼,爲什麼還要問這裏? –

回答

2

我們不能說,因爲你沒有包括源數據。您的「currentContour」可能包含任何內容。

,而不是正與原始數據你 - 幸運的 - 包括,我讀了WKT多邊形:

boost::geometry::read_wkt("POLYGON((61.2101898 81.9854202, 61.3715706 82.0616913, 61.4335442 82.1924744, 61.4778328 82.2606735, 61.5202942 82.3236465, 61.5283432 82.3527832, 61.5431557 82.4063950, 61.5221367 82.4381790, 61.3944855 82.4706116, 61.3497124 82.4679184, 61.3284111 82.4674301, 61.1539803 82.3401947, 61.1297760 82.2854843, 61.0671043 82.1489639, 61.0682831 82.0264740, 61.0667953 82.0112915, 61.0663414 82.0066376, 61.0707321 81.9976196, 61.0998306 81.9980850, 61.2101898 81.9854202))", input); 

驗證失敗,因爲它是在錯誤的方向:

我不能告訴您的方向是否由順時針旗標正確管理,因此請按照以下方式進行檢查:

{ 
    std::string reason; 
    if (!bg::is_valid(input, reason)) 
     std::cout << "Input is not valid: " << reason << "\n"; 
} 

如果您需要解決任何可以解決的錯誤:

bg::correct(input); 

後,我得到了一個乾淨的緩衝區,但我看到了秒殺。沒有在所有選項深諳buffer,我 「隨機」 改變join_miterjoin_round,它走了:

Live On Wandbox

#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/io/io.hpp> 
#include <boost/geometry/geometries/point_xy.hpp> 
#include <fstream> 
#include <iostream> 

namespace bg = boost::geometry; 
typedef bg::model::d2::point_xy<float> BoostPoint; 
typedef bg::model::polygon<BoostPoint> BoostPolygon; 
typedef bg::model::multi_polygon<BoostPolygon> BoostMultipolygon; 

int main() { 
    BoostPolygon input; 
    BoostMultipolygon output; 

    boost::geometry::read_wkt("POLYGON((61.2101898 81.9854202, 61.3715706 82.0616913, 61.4335442 82.1924744, 61.4778328 82.2606735, 61.5202942 82.3236465, 61.5283432 82.3527832, 61.5431557 82.4063950, 61.5221367 82.4381790, 61.3944855 82.4706116, 61.3497124 82.4679184, 61.3284111 82.4674301, 61.1539803 82.3401947, 61.1297760 82.2854843, 61.0671043 82.1489639, 61.0682831 82.0264740, 61.0667953 82.0112915, 61.0663414 82.0066376, 61.0707321 81.9976196, 61.0998306 81.9980850, 61.2101898 81.9854202))", input); 
    { 
     std::string reason; 
     if (!bg::is_valid(input, reason)) 
      std::cout << "Input is not valid: " << reason << "\n"; 
    } 
    bg::correct(input); 
    { 
     std::string reason; 
     if (!bg::is_valid(input, reason)) 
      std::cout << "Input is not valid: " << reason << "\n"; 
     else 
      std::cout << "Input is valid"; 
    } 

    // Declare boost strategies for buffer function. 
    bg::strategy::buffer::distance_symmetric<double> distance_strategy(-0.05); 
    bg::strategy::buffer::join_round join_strategy; 
    bg::strategy::buffer::end_round end_strategy; 
    bg::strategy::buffer::point_circle point_strategy; 
    bg::strategy::buffer::side_straight side_strategy; 
    // Perform polygon buffering. 
    bg::buffer(input, output, distance_strategy, side_strategy, join_strategy, end_strategy, point_strategy); 

    { 
     std::ofstream svg("output.svg"); 
     boost::geometry::svg_mapper<BoostPoint> mapper(svg, 400, 400); 
     mapper.add(output); 
     mapper.add(input); 

     mapper.map(input, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2"); 
     mapper.map(output, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(202,153,0);stroke-width:2"); 
    } 
} 

enter image description here

+0

我很欣賞這種迴應。我必須弄清楚我的取向概念與Boost的不同。不幸的是,我的用例需要尖端。任何人都知道爲什麼測試結果不起作用? –

+0

我不知道。也許你可以問一個簡單的,有針對性的問題。而且我會考慮發佈到圖書館郵件列表,因爲開發者在那裏非常活躍(他們也是零星貢獻) – sehe

0

我不能以獲得與Boost一起工作的端點。我反而切換到Clipper Library,它處理斜切結尾。