簡體   English   中英

Boost :: Geometry - 在3d空間中查找2d多邊形的區域?

[英]Boost::Geometry - Find area of 2d polygon in 3d space?

我想在3d空間中獲得2d多邊形的區域。 Boost :: Geometry有沒有辦法做到這一點? 這是我的實現,但它一直返回0:

#include <iostream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>

namespace bg = boost::geometry;

typedef bg::model::point<double, 3, bg::cs::cartesian> point3d;

int main()
{
    bg::model::multi_point<point3d> square;
    bg::read_wkt("MULTIPOINT((0 0 0), (0 2 0), (0 2 2), (0 0 2), (0 0 0))", square);
    double area = bg::area(square);
    std::cout << "Area: " << area << std::endl;

    return 0;
}

UPD :實際上,我對簡單的2d多點方形有同樣的問題:

#include <iostream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>

namespace bg = boost::geometry;

typedef bg::model::point<double, 2, bg::cs::cartesian> point2d;

int main()
{
    bg::model::multi_point<point2d> square;
    bg::read_wkt("MULTIPOINT((0 0), (2 0), (2 2), (0 2))", square);
    double area = bg::area(square);
    std::cout << "Area: " << area << std::endl;

    return 0;
}

結果如下:

$ ./test_area
Area: 0

UPD :看起來只有2維多邊形的boost::geometry可用區域計算。

我不希望有一個點集合有一個區域。 您需要等效的model::polygon<poind3d>但目前似乎不支持。

如果保證點是共面的並且段不相互交叉,則可以將多邊形分解為一系列三角形,並使用一點線性代數計算區域,基於該區域的以下公式三角形:
在此輸入圖像描述

在非凸多邊形的情況下,需要調整區域的總和以減去多邊形外的區域。 實現這一目標的最簡單方法是使用三角形的有符號區域,包括右手三角形的正貢獻和左手三角形的負貢獻:
在此輸入圖像描述

請注意,似乎有一些計划在Boost中包含cross_product實現,但從版本1.56開始似乎沒有包含它。 以下替換應該為您的用例提供技巧:

point3d cross_product(const point3d& p1, const point3d& p2)
{
  double x = bg::get<0>(p1);
  double y = bg::get<1>(p1);
  double z = bg::get<2>(p1);
  double u = bg::get<0>(p2);
  double v = bg::get<1>(p2);
  double w = bg::get<2>(p2);
  return point3d(y*w-z*v, z*u-x*w, x*v-y*u);
}
point3d cross_product(const bg::model::segment<point3d>& p1
                    , const bg::model::segment<point3d>& p2)
{
  point3d v1(p1.second);
  point3d v2(p2.second);
  bg::subtract_point(v1, p1.first);
  bg::subtract_point(v2, p2.first);

  return cross_product(v1, v2);
}

然后可以使用以下內容計算該區域:

// compute the are of a collection of 3D points interpreted as a 3D polygon
// Note that there are no checks as to whether or not the points are
// indeed co-planar.
double area(bg::model::multi_point<point3d>& polygon)
{
  if (polygon.size()<3) return 0;

  bg::model::segment<point3d> v1(polygon[1], polygon[0]);
  bg::model::segment<point3d> v2(polygon[2], polygon[0]);
  // Compute the cross product for the first pair of points, to handle
  // shapes that are not convex.
  point3d n1 = cross_product(v1, v2);
  double normSquared = bg::dot_product(n1, n1);
  if (normSquared > 0)
  {
    bg::multiply_value(n1, 1.0/sqrt(normSquared));
  }
  // sum signed areas of triangles
  double result = 0.0;
  for (size_t i=1; i<polygon.size(); ++i)
  {
    bg::model::segment<point3d> v1(polygon[0], polygon[i-1]);
    bg::model::segment<point3d> v2(polygon[0], polygon[i]);

    result += bg::dot_product(cross_product(v1, v2), n1);
  }
  result *= 0.5;
  return abs(result);
}

我不熟悉boost的幾何部分,但憑借我對幾何的了解,我可以說它在3D中與2D不同。 雖然可能已經有了一些提升,但你可以編寫自己的方法,相當容易。

編輯:

da code monkey指出鞋帶配方在這方面會更有效率,因為它不那么復雜,而且速度更快。

原創意見如下:


為了計算這一點,我首先將多邊形細分為三角形,因為任何多邊形都可以分成多個三角形。 我將采用這些三角形中的每一個,並計算每個三角形的面積。 要在3d空間中執行此操作,相同的概念適用。 為了得到基數,你取△ABC並任意指定-AB作為基數,-BC作為高度,-CA作為斜邊。 做(-AB * -BC)/ 2。 只需將每個三角形的區域相加即可。

我不知道boost是否有內置的tessellate方法,這在c ++中實現起來相當困難,但你可能想要創建某種三角形扇形。 (注意:這僅適用於凸多邊形)。 如果你有一個凹多邊形,你應該看看這個: http//www.cs.unc.edu/~dm/CODE/GEM/chapter.html我會把它放到c ++作為練習,但是這個過程很簡單。

暫無
暫無

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

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