C++ 增强三维中两条线段的相交

C++ 增强三维中两条线段的相交,c++,boost,intersection,boost-geometry,line-intersection,C++,Boost,Intersection,Boost Geometry,Line Intersection,我尝试使用boost geometry来计算3D中两条线段的交点 下面是一段代码: typedef boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> boost3dPoint; typedef boost::geometry::model::segment<boost3dPoint> boost3dSegment; const boost3dPoint bp0(0, 0, 0

我尝试使用boost geometry来计算3D中两条线段的交点

下面是一段代码:

typedef boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> boost3dPoint;
typedef boost::geometry::model::segment<boost3dPoint> boost3dSegment;

const boost3dPoint bp0(0, 0, 0);
const boost3dPoint bp1(2, 0, 0);
boost3dSegment lineP(bp0, bp1);

// line m
const boost3dPoint bm0(1, 1, 2);
const boost3dPoint bm1(1, -1, 2);
boost3dSegment lineM(bm0, bm1);

std::vector<boost3dPoint> output;

boost::geometry::intersection(lineP, lineM, output);

if(output.size() == 0)
{
  result.intsec = false;
}
else if(output.size() == 1)
{
  std::cout << "test: output.size() " << std::endl;
  result.intsec = true;
  boost3dPoint bresult = output[0];
  mesh::Point cross(bresult.get<0>(), bresult.get<1>(), bresult.get<2>());
  result.pon = cross;
}
else
{
  // it may line on each other, cosider as no intersection for now
  result.intsec = false;
}
typedef boost::geometry::model::point boost3dPoint;
typedef boost::geometry::model::segment boost3dSegment;
常数boost3dPoint bp0(0,0,0);
常数boost3dPoint bp1(2,0,0);
boost3d段线(bp0,bp1);
//行m
常数boost3dPoint bm0(1,1,2);
常数boost3dPoint bm1(1,-1,2);
boost3d段线m(bm0,bm1);
std::矢量输出;
boost::geometry::intersection(lineP、lineM、output);
if(output.size()==0)
{
result.intsec=false;
}
else if(output.size()==1)
{

在我看来,std::cout确实只适用于2d情况。这是令人惊讶的,因为这些约束通常是由库主动主动断言的

但是,对于以下测试用例,很明显,
z
坐标值只是单位化/不确定的:

==13210== Conditional jump or move depends on uninitialised value(s)
==13210==    at 0x4EBFE9E: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x4EC047C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x4ECC21D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x401549: main (write.hpp:62)

#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/io/wkt/stream.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/correct.hpp>

#include <iomanip>
#include <fstream>
#include <iostream>

#if 0
#include <boost/multiprecision/cpp_dec_float.hpp>
typedef boost::multiprecision::cpp_dec_float<50> dec_float_backend;
typedef boost::multiprecision::number<dec_float_backend, boost::multiprecision::expression_template_option::et_off> T;
#else
typedef int T;
#endif

typedef boost::geometry::model::point<T, 3, boost::geometry::cs::cartesian> boostPoint;
typedef boost::geometry::model::segment<boostPoint> boostSegment;

int main() {
    std::cout << std::setprecision(std::numeric_limits<double>::max_digits10+2);

    for (auto&& segments : {
                // a simple test with intersection [ 5,0,0 ]
                std::make_pair(
                    boostSegment(boostPoint(0 , 0 , 0), boostPoint(10, 0 , 0)),
                    boostSegment(boostPoint(+3, +1, 0), boostPoint(+7, -1, 0))
                ),
                // the test from the OP:
                std::make_pair(
                    boostSegment(boostPoint(0, 0, 0), boostPoint(2, 0, 0)),
                    boostSegment(boostPoint(1, 1, 2), boostPoint(1, -1, 2))
                ),
            })
    {
        std::vector<boostPoint> output;
        boost::geometry::correct(segments.first); // just in case o.O
        boost::geometry::correct(segments.second);
        boost::geometry::intersection(segments.first, segments.second, output);

        std::cout << "Intersecting " << segments.first << " and " << segments.second << "\n";
        std::cout << "Output size: " << output.size() << " ";
        if (!output.empty()) std::cout << output[0];
        std::cout << "\n";
    }
}
在下一次跑步中

Intersecting LINESTRING(0 0 0,10 0 0) and LINESTRING(3 1 0,7 -1 0)
Output size: 1 POINT(5 0 1)
Intersecting LINESTRING(0 0 0,2 0 0) and LINESTRING(1 1 2,1 -1 2)
Output size: 1 POINT(1 0 1)
valgrind确认该值不确定:

==13210== Conditional jump or move depends on uninitialised value(s)
==13210==    at 0x4EBFE9E: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x4EC047C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x4ECC21D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==    by 0x401549: main (write.hpp:62)
==13210==条件跳转或移动取决于未初始化的值
==13210==at 0x4EBFE9E:std::ostreambuf_迭代器std::num_put::_M_insert_int(std::ostreambuf_迭代器,std::ios_base&,char,long)const(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==0x4EC047C:std::num_put::do_put(std::ostreambuf_迭代器,std::ios_base&,char,long)const(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==0x4ECC21D:std::ostream&std::ostream::_M_insert(long)(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13210==by 0x401549:main(write.hpp:62)
我认为不管怎样,这闻起来像是一个可以向库开发人员报告的问题

为方便起见,我添加的“简单测试”案例实际上是2D的,如下所示:


无答案投票……感谢您的分析。您能给我一个在3D中进行两条线段相交的提示吗?有CGAL库,但我很难理解它。我真的不知道。我花了很多时间得出上述结论。也许您可以试着将线段转换为polygon?(甚至不确定是否支持,因为从技术上讲,您将与零宽度的三角形相交)再次感谢,我甚至想使用boost distance来查看是否存在任何相交(遗憾的是,它不受支持)。尽管我发现了一个扩展库“”您可以在3D空间中找到两个线段之间的最短距离。如果距离等于零(或小于定义的公差),则线段是相交的。@Jepessen在最后一条评论中没有指出“不幸的是,这不受支持”。他错了吗?