| 433 | } |
| 434 | |
| 435 | std::pair<double, double> computeHausdorffPair(PointViewPtr viewA, |
| 436 | PointViewPtr viewB) |
| 437 | { |
| 438 | // Computes both the max and mean of all nearest neighbor distances from |
| 439 | // each point in the PointView to those in the KD3Index. |
| 440 | auto compute = [](PointViewPtr view, KD3Index& index) { |
| 441 | double max_distance = std::numeric_limits<double>::lowest(); |
| 442 | double M1(0.0); |
| 443 | for (PointRef p : *view) |
| 444 | { |
| 445 | PointIdList indices(1); |
| 446 | std::vector<double> sqr_dists(1); |
| 447 | index.knnSearch(p, 1, &indices, &sqr_dists); |
| 448 | |
| 449 | if (sqr_dists[0] > max_distance) |
| 450 | max_distance = sqr_dists[0]; |
| 451 | |
| 452 | double delta = std::sqrt(sqr_dists[0]) - M1; |
| 453 | double delta_n = delta / (p.pointId() + 1); |
| 454 | M1 += delta_n; |
| 455 | } |
| 456 | max_distance = std::sqrt(max_distance); |
| 457 | return std::pair<double, double>{max_distance, M1}; |
| 458 | }; |
| 459 | |
| 460 | // First, test from view A to view B... |
| 461 | KD3Index& indexB = viewB->build3dIndex(); |
| 462 | std::pair<double, double> a2b = compute(viewA, indexB); |
| 463 | |
| 464 | // then recompute from view B to view A. |
| 465 | KD3Index& indexA = viewA->build3dIndex(); |
| 466 | std::pair<double, double> b2a = compute(viewB, indexA); |
| 467 | |
| 468 | // The original Hausdorff metric is the max of the max distances from A to B |
| 469 | // and vice versa. |
| 470 | double original = (std::max)(a2b.first, b2a.first); |
| 471 | |
| 472 | // The modified Hausdorff metric is the max of the mean distances from A to |
| 473 | // B and vice versa. |
| 474 | double modified = (std::max)(a2b.second, b2a.second); |
| 475 | |
| 476 | // Return both the original and modified metrics. |
| 477 | return std::pair<double, double>{original, modified}; |
| 478 | } |
| 479 | |
| 480 | std::string dllDir() |
| 481 | { |