segment_concept.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. // Boost.Polygon library segment_concept.hpp header file
  2. // Copyright (c) Intel Corporation 2008.
  3. // Copyright (c) 2008-2012 Simonson Lucanus.
  4. // Copyright (c) 2012-2012 Andrii Sydorchuk.
  5. // See http://www.boost.org for updates, documentation, and revision history.
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_POLYGON_SEGMENT_CONCEPT_HPP
  10. #define BOOST_POLYGON_SEGMENT_CONCEPT_HPP
  11. #include "isotropy.hpp"
  12. #include "segment_traits.hpp"
  13. #include "rectangle_concept.hpp"
  14. namespace boost {
  15. namespace polygon {
  16. struct segment_concept {};
  17. template <typename ConceptType>
  18. struct is_segment_concept {
  19. typedef gtl_no type;
  20. };
  21. template <>
  22. struct is_segment_concept<segment_concept> {
  23. typedef gtl_yes type;
  24. };
  25. template <typename ConceptType>
  26. struct is_mutable_segment_concept {
  27. typedef gtl_no type;
  28. };
  29. template <>
  30. struct is_mutable_segment_concept<segment_concept> {
  31. typedef gtl_yes type;
  32. };
  33. template <typename GeometryType, typename BoolType>
  34. struct segment_distance_type_by_concept {
  35. typedef void type;
  36. };
  37. template <typename GeometryType>
  38. struct segment_distance_type_by_concept<GeometryType, gtl_yes> {
  39. typedef typename coordinate_traits<
  40. typename segment_traits<GeometryType>::coordinate_type
  41. >::coordinate_distance type;
  42. };
  43. template <typename GeometryType>
  44. struct segment_distance_type {
  45. typedef typename segment_distance_type_by_concept<
  46. GeometryType,
  47. typename is_segment_concept<
  48. typename geometry_concept<GeometryType>::type
  49. >::type
  50. >::type type;
  51. };
  52. template <typename GeometryType, typename BoolType>
  53. struct segment_point_type_by_concept {
  54. typedef void type;
  55. };
  56. template <typename GeometryType>
  57. struct segment_point_type_by_concept<GeometryType, gtl_yes> {
  58. typedef typename segment_traits<GeometryType>::point_type type;
  59. };
  60. template <typename GeometryType>
  61. struct segment_point_type {
  62. typedef typename segment_point_type_by_concept<
  63. GeometryType,
  64. typename is_segment_concept<
  65. typename geometry_concept<GeometryType>::type
  66. >::type
  67. >::type type;
  68. };
  69. template <typename GeometryType, typename BoolType>
  70. struct segment_coordinate_type_by_concept {
  71. typedef void type;
  72. };
  73. template <typename GeometryType>
  74. struct segment_coordinate_type_by_concept<GeometryType, gtl_yes> {
  75. typedef typename segment_traits<GeometryType>::coordinate_type type;
  76. };
  77. template <typename GeometryType>
  78. struct segment_coordinate_type {
  79. typedef typename segment_coordinate_type_by_concept<
  80. GeometryType,
  81. typename is_segment_concept<
  82. typename geometry_concept<GeometryType>::type
  83. >::type
  84. >::type type;
  85. };
  86. struct y_s_get : gtl_yes {};
  87. template <typename Segment>
  88. typename enable_if<
  89. typename gtl_and<
  90. y_s_get,
  91. typename is_segment_concept<
  92. typename geometry_concept<Segment>::type
  93. >::type
  94. >::type,
  95. typename segment_point_type<Segment>::type>::type
  96. get(const Segment& segment, direction_1d dir) {
  97. return segment_traits<Segment>::get(segment, dir);
  98. }
  99. struct y_s_set : gtl_yes {};
  100. template <typename Segment, typename Point>
  101. typename enable_if<
  102. typename gtl_and_3<
  103. y_s_set,
  104. typename is_mutable_segment_concept<
  105. typename geometry_concept<Segment>::type
  106. >::type,
  107. typename is_point_concept<
  108. typename geometry_concept<Point>::type
  109. >::type
  110. >::type,
  111. void>::type set(Segment& segment, direction_1d dir, const Point& point) {
  112. segment_mutable_traits<Segment>::set(segment, dir, point);
  113. }
  114. struct y_s_construct : gtl_yes {};
  115. template <typename Segment, typename Point1, typename Point2>
  116. typename enable_if<
  117. typename gtl_and_4<
  118. y_s_construct,
  119. typename is_mutable_segment_concept<
  120. typename geometry_concept<Segment>::type
  121. >::type,
  122. typename is_point_concept<
  123. typename geometry_concept<Point1>::type
  124. >::type,
  125. typename is_point_concept<
  126. typename geometry_concept<Point2>::type
  127. >::type
  128. >::type,
  129. Segment>::type construct(const Point1& low, const Point2& high) {
  130. return segment_mutable_traits<Segment>::construct(low, high);
  131. }
  132. struct y_s_copy_construct : gtl_yes {};
  133. template <typename Segment1, typename Segment2>
  134. typename enable_if<
  135. typename gtl_and_3<
  136. y_s_copy_construct,
  137. typename is_mutable_segment_concept<
  138. typename geometry_concept<Segment1>::type
  139. >::type,
  140. typename is_segment_concept<
  141. typename geometry_concept<Segment2>::type
  142. >::type
  143. >::type,
  144. Segment1>::type copy_construct(const Segment2& segment) {
  145. return construct<Segment1>(get(segment, LOW), get(segment, HIGH));
  146. }
  147. struct y_s_assign : gtl_yes {};
  148. template <typename Segment1, typename Segment2>
  149. typename enable_if<
  150. typename gtl_and_3<
  151. y_s_assign,
  152. typename is_mutable_segment_concept<
  153. typename geometry_concept<Segment1>::type
  154. >::type,
  155. typename is_segment_concept<
  156. typename geometry_concept<Segment2>::type
  157. >::type
  158. >::type,
  159. Segment1>::type& assign(Segment1& segment1, const Segment2& segment2) {
  160. return segment1 = copy_construct<Segment1>(segment2);
  161. }
  162. struct y_s_equivalence : gtl_yes {};
  163. template <typename Segment1, typename Segment2>
  164. typename enable_if<
  165. typename gtl_and_3<
  166. y_s_equivalence,
  167. typename is_segment_concept<
  168. typename geometry_concept<Segment1>::type
  169. >::type,
  170. typename is_segment_concept<
  171. typename geometry_concept<Segment2>::type
  172. >::type
  173. >::type,
  174. bool>::type equivalence(const Segment1& segment1, const Segment2& segment2) {
  175. return get(segment1, LOW) == get(segment2, LOW) &&
  176. get(segment1, HIGH) == get(segment2, HIGH);
  177. }
  178. struct y_s_low : gtl_yes {};
  179. template <typename Segment>
  180. typename enable_if<
  181. typename gtl_and<
  182. y_s_low,
  183. typename is_segment_concept<
  184. typename geometry_concept<Segment>::type
  185. >::type
  186. >::type,
  187. typename segment_point_type<Segment>::type>::type low(const Segment& segment) {
  188. return get(segment, LOW);
  189. }
  190. struct y_s_high : gtl_yes {};
  191. template <typename Segment>
  192. typename enable_if<
  193. typename gtl_and<
  194. y_s_high,
  195. typename is_segment_concept<
  196. typename geometry_concept<Segment>::type
  197. >::type
  198. >::type,
  199. typename segment_point_type<Segment>::type>::type high(const Segment& segment) {
  200. return get(segment, HIGH);
  201. }
  202. struct y_s_center : gtl_yes {};
  203. template <typename Segment>
  204. typename enable_if<
  205. typename gtl_and<
  206. y_s_center,
  207. typename is_segment_concept<
  208. typename geometry_concept<Segment>::type
  209. >::type
  210. >::type,
  211. typename segment_point_type<Segment>::type>::type
  212. center(const Segment& segment) {
  213. return construct<typename segment_point_type<Segment>::type>(
  214. (x(high(segment)) + x(low(segment)))/2,
  215. (y(high(segment)) + y(low(segment)))/2);
  216. }
  217. struct y_s_low2 : gtl_yes {};
  218. template <typename Segment, typename Point>
  219. typename enable_if<
  220. typename gtl_and_3<
  221. y_s_low2,
  222. typename is_mutable_segment_concept<
  223. typename geometry_concept<Segment>::type
  224. >::type,
  225. typename is_point_concept<
  226. typename geometry_concept<Point>::type
  227. >::type
  228. >::type,
  229. void>::type low(Segment& segment, const Point& point) {
  230. set(segment, LOW, point);
  231. }
  232. struct y_s_high2 : gtl_yes {};
  233. template <typename Segment, typename Point>
  234. typename enable_if<
  235. typename gtl_and_3<
  236. y_s_high2,
  237. typename is_mutable_segment_concept<
  238. typename geometry_concept<Segment>::type
  239. >::type,
  240. typename is_point_concept<
  241. typename geometry_concept<Point>::type
  242. >::type
  243. >::type,
  244. void>::type high(Segment& segment, const Point& point) {
  245. set(segment, HIGH, point);
  246. }
  247. struct y_s_orientation1 : gtl_yes {};
  248. // -1 for CW, 0 for collinear and 1 for CCW.
  249. template <typename Segment1, typename Segment2>
  250. typename enable_if<
  251. typename gtl_and_3<
  252. y_s_orientation1,
  253. typename is_segment_concept<
  254. typename geometry_concept<Segment1>::type
  255. >::type,
  256. typename is_segment_concept<
  257. typename geometry_concept<Segment2>::type
  258. >::type
  259. >::type,
  260. int>::type orientation(const Segment1& segment1, const Segment2& segment2) {
  261. typedef typename coordinate_traits<
  262. typename segment_traits<Segment1>::coordinate_type
  263. >::manhattan_area_type int_x2;
  264. typedef typename coordinate_traits<
  265. typename segment_traits<Segment1>::coordinate_type
  266. >::unsigned_area_type uint_x2;
  267. int_x2 a1 = (int_x2)x(high(segment1)) - (int_x2)x(low(segment1));
  268. int_x2 b1 = (int_x2)y(high(segment1)) - (int_x2)y(low(segment1));
  269. int_x2 a2 = (int_x2)x(high(segment2)) - (int_x2)x(low(segment2));
  270. int_x2 b2 = (int_x2)y(high(segment2)) - (int_x2)y(low(segment2));
  271. int sign1 = 0;
  272. int sign2 = 0;
  273. if (a1 && b2)
  274. sign1 = ((a1 > 0) ^ (b2 > 0)) ? -1 : 1;
  275. if (a2 && b1)
  276. sign2 = ((a2 > 0) ^ (b1 > 0)) ? -1 : 1;
  277. if (sign1 != sign2)
  278. return (sign1 < sign2) ? -1 : 1;
  279. uint_x2 a3 = (uint_x2)(a1 < 0 ? -a1 : a1) * (uint_x2)(b2 < 0 ? -b2 : b2);
  280. uint_x2 b3 = (uint_x2)(b1 < 0 ? -b1 : b1) * (uint_x2)(a2 < 0 ? -a2 : a2);
  281. if (a3 == b3)
  282. return 0;
  283. return ((a3 < b3) ^ (sign1 == 1)) ? 1 : -1;
  284. }
  285. struct y_s_orientation2 : gtl_yes {};
  286. // -1 for right, 0 for collinear and 1 for left.
  287. template <typename Segment, typename Point>
  288. typename enable_if<
  289. typename gtl_and_3<
  290. y_s_orientation2,
  291. typename is_segment_concept<
  292. typename geometry_concept<Segment>::type
  293. >::type,
  294. typename is_point_concept<
  295. typename geometry_concept<Point>::type
  296. >::type
  297. >::type,
  298. int>::type orientation(const Segment& segment, const Point& point) {
  299. Segment segment2 = construct<Segment>(high(segment), point);
  300. return orientation(segment, segment2);
  301. }
  302. struct y_s_contains : gtl_yes {};
  303. template <typename Segment, typename Point>
  304. typename enable_if<
  305. typename gtl_and_3<
  306. y_s_contains,
  307. typename is_segment_concept<
  308. typename geometry_concept<Segment>::type
  309. >::type,
  310. typename is_point_concept<
  311. typename geometry_concept<Point>::type
  312. >::type
  313. >::type,
  314. bool>::type contains(const Segment& segment,
  315. const Point& point, bool consider_touch = true ) {
  316. if (orientation(segment, point))
  317. return false;
  318. rectangle_data<typename segment_coordinate_type<Segment>::type> rect;
  319. set_points(rect, low(segment), high(segment));
  320. if (!contains(rect, point, true))
  321. return false;
  322. if (!consider_touch &&
  323. (equivalence(low(segment), point) ||
  324. equivalence(high(segment), point)))
  325. return false;
  326. return true;
  327. }
  328. struct y_s_contains2 : gtl_yes {};
  329. template <typename Segment1, typename Segment2>
  330. typename enable_if<
  331. typename gtl_and_3<
  332. y_s_contains2,
  333. typename is_segment_concept<
  334. typename geometry_concept<Segment1>::type
  335. >::type,
  336. typename is_segment_concept<
  337. typename geometry_concept<Segment2>::type
  338. >::type
  339. >::type,
  340. bool>::type contains(const Segment1& segment1,
  341. const Segment2& segment2, bool consider_touch = true) {
  342. return contains(segment1, get(segment2, LOW), consider_touch) &&
  343. contains(segment1, get(segment2, HIGH), consider_touch);
  344. }
  345. struct y_s_length : gtl_yes {};
  346. template <typename Segment>
  347. typename enable_if<
  348. typename gtl_and<
  349. y_s_length,
  350. typename is_segment_concept<
  351. typename geometry_concept<Segment>::type
  352. >::type
  353. >::type,
  354. typename segment_distance_type<Segment>::type>::type
  355. length(const Segment& segment) {
  356. return euclidean_distance(low(segment), high(segment));
  357. }
  358. struct y_s_scale_up : gtl_yes {};
  359. template <typename Segment>
  360. typename enable_if<
  361. typename gtl_and<
  362. y_s_scale_up,
  363. typename is_mutable_segment_concept<
  364. typename geometry_concept<Segment>::type
  365. >::type
  366. >::type,
  367. Segment>::type& scale_up(Segment& segment,
  368. typename coordinate_traits<
  369. typename segment_coordinate_type<Segment>::type
  370. >::unsigned_area_type factor) {
  371. typename segment_point_type<Segment>::type l = low(segment);
  372. typename segment_point_type<Segment>::type h = high(segment);
  373. low(segment, scale_up(l, factor));
  374. high(segment, scale_up(h, factor));
  375. return segment;
  376. }
  377. struct y_s_scale_down : gtl_yes {};
  378. template <typename Segment>
  379. typename enable_if<
  380. typename gtl_and<
  381. y_s_scale_down,
  382. typename is_mutable_segment_concept<
  383. typename geometry_concept<Segment>::type
  384. >::type
  385. >::type,
  386. Segment>::type& scale_down(Segment& segment,
  387. typename coordinate_traits<
  388. typename segment_coordinate_type<Segment>::type
  389. >::unsigned_area_type factor) {
  390. typename segment_point_type<Segment>::type l = low(segment);
  391. typename segment_point_type<Segment>::type h = high(segment);
  392. low(segment, scale_down(l, factor));
  393. high(segment, scale_down(h, factor));
  394. return segment;
  395. }
  396. struct y_s_scale : gtl_yes {};
  397. template <typename Segment, typename Scale>
  398. typename enable_if<
  399. typename gtl_and<
  400. y_s_scale,
  401. typename is_mutable_segment_concept<
  402. typename geometry_concept<Segment>::type
  403. >::type
  404. >::type,
  405. Segment>::type& scale(Segment& segment, const Scale& sc) {
  406. typename segment_point_type<Segment>::type l = low(segment);
  407. typename segment_point_type<Segment>::type h = high(segment);
  408. low(segment, scale(l, sc));
  409. high(segment, scale(h, sc));
  410. return segment;
  411. }
  412. struct y_s_transform : gtl_yes {};
  413. template <typename Segment, typename Transform>
  414. typename enable_if<
  415. typename gtl_and<
  416. y_s_transform,
  417. typename is_mutable_segment_concept<
  418. typename geometry_concept<Segment>::type
  419. >::type
  420. >::type,
  421. Segment>::type& transform(Segment& segment, const Transform& tr) {
  422. typename segment_point_type<Segment>::type l = low(segment);
  423. typename segment_point_type<Segment>::type h = high(segment);
  424. low(segment, transform(l, tr));
  425. high(segment, transform(h, tr));
  426. return segment;
  427. }
  428. struct y_s_move : gtl_yes {};
  429. template <typename Segment>
  430. typename enable_if<
  431. typename gtl_and<
  432. y_s_move,
  433. typename is_mutable_segment_concept<
  434. typename geometry_concept<Segment>::type
  435. >::type
  436. >::type,
  437. Segment>::type& move(Segment& segment, orientation_2d orient,
  438. typename segment_coordinate_type<Segment>::type displacement) {
  439. typename segment_point_type<Segment>::type l = low(segment);
  440. typename segment_point_type<Segment>::type h = high(segment);
  441. low(segment, move(l, orient, displacement));
  442. high(segment, move(h, orient, displacement));
  443. return segment;
  444. }
  445. struct y_s_convolve : gtl_yes {};
  446. template <typename Segment, typename Point>
  447. typename enable_if<
  448. typename gtl_and_3<
  449. y_s_convolve,
  450. typename is_mutable_segment_concept<
  451. typename geometry_concept<Segment>::type
  452. >::type,
  453. typename is_point_concept<
  454. typename geometry_concept<Point>::type
  455. >::type
  456. >::type,
  457. Segment>::type& convolve(Segment& segment, const Point& point) {
  458. typename segment_point_type<Segment>::type l = low(segment);
  459. typename segment_point_type<Segment>::type h = high(segment);
  460. low(segment, convolve(l, point));
  461. high(segment, convolve(h, point));
  462. return segment;
  463. }
  464. struct y_s_deconvolve : gtl_yes {};
  465. template <typename Segment, typename Point>
  466. typename enable_if<
  467. typename gtl_and_3<
  468. y_s_deconvolve,
  469. typename is_mutable_segment_concept<
  470. typename geometry_concept<Segment>::type
  471. >::type,
  472. typename is_point_concept<
  473. typename geometry_concept<Point>::type
  474. >::type
  475. >::type,
  476. Segment>::type& deconvolve(Segment& segment, const Point& point) {
  477. typename segment_point_type<Segment>::type l = low(segment);
  478. typename segment_point_type<Segment>::type h = high(segment);
  479. low(segment, deconvolve(l, point));
  480. high(segment, deconvolve(h, point));
  481. return segment;
  482. }
  483. struct y_s_abuts1 : gtl_yes {};
  484. template <typename Segment1, typename Segment2>
  485. typename enable_if<
  486. typename gtl_and_3<
  487. y_s_abuts1,
  488. typename is_segment_concept<
  489. typename geometry_concept<Segment1>::type
  490. >::type,
  491. typename is_segment_concept<
  492. typename geometry_concept<Segment2>::type
  493. >::type
  494. >::type,
  495. bool>::type abuts(const Segment1& segment1,
  496. const Segment2& segment2, direction_1d dir) {
  497. return dir.to_int() ? equivalence(low(segment2) , high(segment1)) :
  498. equivalence(low(segment1) , high(segment2));
  499. }
  500. struct y_s_abuts2 : gtl_yes {};
  501. template <typename Segment1, typename Segment2>
  502. typename enable_if<
  503. typename gtl_and_3<
  504. y_s_abuts2,
  505. typename is_segment_concept<
  506. typename geometry_concept<Segment1>::type
  507. >::type,
  508. typename is_segment_concept<
  509. typename geometry_concept<Segment2>::type
  510. >::type
  511. >::type,
  512. bool>::type abuts(const Segment1& segment1, const Segment2& segment2) {
  513. return abuts(segment1, segment2, HIGH) || abuts(segment1, segment2, LOW);
  514. }
  515. struct y_s_e_intersects : gtl_yes {};
  516. template <typename Segment1, typename Segment2>
  517. typename enable_if<
  518. typename gtl_and_3<
  519. y_s_e_intersects,
  520. typename is_segment_concept<
  521. typename geometry_concept<Segment1>::type
  522. >::type,
  523. typename is_segment_concept<
  524. typename geometry_concept<Segment2>::type
  525. >::type
  526. >::type,
  527. bool
  528. >::type intersects(const Segment1& segment1, const Segment2& segment2,
  529. bool consider_touch = true) {
  530. rectangle_data<typename segment_coordinate_type<Segment1>::type> rect1, rect2;
  531. set_points(rect1, low(segment1), high(segment1));
  532. set_points(rect2, low(segment2), high(segment2));
  533. // Check if axis-parallel rectangles containing segments intersect.
  534. if (!intersects(rect1, rect2, true))
  535. return false;
  536. int or1_1 = orientation(segment1, low(segment2));
  537. int or1_2 = orientation(segment1, high(segment2));
  538. if (or1_1 * or1_2 > 0)
  539. return false;
  540. int or2_1 = orientation(segment2, low(segment1));
  541. int or2_2 = orientation(segment2, high(segment1));
  542. if (or2_1 * or2_2 > 0)
  543. return false;
  544. if (consider_touch || (or1_1 && or1_2) || (or2_1 && or2_2))
  545. return true;
  546. if (or1_1 || or1_2)
  547. return false;
  548. return intersects(vertical(rect1), vertical(rect2), false) ||
  549. intersects(horizontal(rect1), horizontal(rect2), false);
  550. }
  551. struct y_s_e_dist : gtl_yes {};
  552. template <typename Segment, typename Point>
  553. typename enable_if<
  554. typename gtl_and_3<
  555. y_s_e_dist,
  556. typename is_segment_concept<
  557. typename geometry_concept<Segment>::type
  558. >::type,
  559. typename is_point_concept<
  560. typename geometry_concept<Point>::type
  561. >::type
  562. >::type,
  563. typename segment_distance_type<Segment>::type>::type
  564. euclidean_distance(const Segment& segment, const Point& point) {
  565. typedef typename segment_distance_type<Segment>::type Unit;
  566. Unit x1 = x(low(segment));
  567. Unit y1 = y(low(segment));
  568. Unit x2 = x(high(segment));
  569. Unit y2 = y(high(segment));
  570. Unit X = x(point);
  571. Unit Y = y(point);
  572. Unit A = X - x1;
  573. Unit B = Y - y1;
  574. Unit C = x2 - x1;
  575. Unit D = y2 - y1;
  576. Unit param = (A * C + B * D);
  577. Unit length_sq = C * C + D * D;
  578. if (param > length_sq) {
  579. return euclidean_distance(high(segment), point);
  580. } else if (param < 0.0) {
  581. return euclidean_distance(low(segment), point);
  582. }
  583. if (length_sq == 0.0)
  584. return 0.0;
  585. Unit denom = std::sqrt(length_sq);
  586. Unit result = (A * D - C * B) / denom;
  587. return (result < 0.0) ? -result : result;
  588. }
  589. struct y_s_e_dist2 : gtl_yes {};
  590. template <typename Segment1, typename Segment2>
  591. typename enable_if<
  592. typename gtl_and_3<
  593. y_s_e_dist2,
  594. typename is_segment_concept<
  595. typename geometry_concept<Segment1>::type
  596. >::type,
  597. typename is_segment_concept<
  598. typename geometry_concept<Segment2>::type
  599. >::type
  600. >::type,
  601. typename segment_distance_type<Segment1>::type>::type
  602. euclidean_distance(const Segment1& segment1, const Segment2& segment2) {
  603. if (intersects(segment1, segment2))
  604. return 0.0;
  605. typename segment_distance_type<Segment1>::type
  606. result1 = euclidean_distance(segment1, low(segment2)),
  607. result2 = euclidean_distance(segment1, high(segment2)),
  608. result3 = euclidean_distance(segment2, low(segment1)),
  609. result4 = euclidean_distance(segment2, high(segment1));
  610. if (result2 < result1)
  611. result1 = result2;
  612. if (result4 < result3)
  613. result3 = result4;
  614. return (result1 < result3) ? result1 : result3;
  615. }
  616. } // polygon
  617. } // boost
  618. #endif // BOOST_POLYGON_SEGMENT_CONCEPT_HPP