2015-03-18 4 views
3

Я пытаюсь использовать форсированную геометрию для вычисления пересечения двух сегментов линии в 3D.Ускорение пересечения двух сегментов линии в 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; 
} 

Очевидно, что нет пересечений выше случае, но она по-прежнему возвращает результат: (1, 0, 6.94593e-310)

Любой помощь будет оценена.

Работает ли он только в 2D?

+0

голосов без ответа .... –

ответ

1

Полагает, что он действительно работает только для 2-х корпусов. Это удивительно, потому что обычно эти ограничения утверждаются довольно агрессивно pro-active от библиотеки.

Однако, со следующими тестовыми, это довольно ясно, что z значение координаты только неинициализированными/неопределенными:

Live On Coliru

#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 -133276928) 
Intersecting LINESTRING(0 0 0,2 0 0) and LINESTRING(1 1 2,1 -1 2) 
Output size: 1 POINT(1 0 -133276928) 

И при следующем запуске

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 подтверждает, что значение является неопределенным:

==== Conditional jump or move depends on uninitialised value(s) 
==== 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) 
==== 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) 
==== by 0x4ECC21D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19) 
==== by 0x401549: main (write.hpp:62) 

Я думаю, что так или другое это пахнет как вопрос, который может быть зарегистрирован с разработчиками библиотеки

Для Вашего удобства, «простой тест» случай, который я добавил на самом деле 2D только выглядит так:

enter image description here

+0

спасибо за анализ. можете ли вы дать мне подсказку для выполнения пересечения двух сегментов линии в 3D? есть библиотека CGAL, но мне очень трудно это понять. –

+0

Я честно не знаю. Я потратил довольно много времени на достижение вышеупомянутых выводов. Возможно, вы попытаетесь преобразовать сегменты линии в многоугольник? (Даже не уверен, поддерживается ли это, потому что технически вы пересекаете треугольники с нулевой шириной) – sehe

+0

Еще раз спасибо, я даже хотел использовать форсированное расстояние, чтобы увидеть, нет ли пересечения (к сожалению, оно не поддерживается). Хотя я нашел библиотеку расширений «http://cgm.cs.mcgill.ca/~stever/CGAL/» –

Смежные вопросы