| 3521 | } |
| 3522 | |
| 3523 | bool ImPlot3DBox::ClipLineSegment(const ImPlot3DPoint& p0, const ImPlot3DPoint& p1, ImPlot3DPoint& p0_clipped, ImPlot3DPoint& p1_clipped) const { |
| 3524 | // Check if the line segment is completely inside the box |
| 3525 | if (Contains(p0) && Contains(p1)) { |
| 3526 | p0_clipped = p0; |
| 3527 | p1_clipped = p1; |
| 3528 | return true; |
| 3529 | } |
| 3530 | |
| 3531 | // Perform Liang-Barsky 3D clipping |
| 3532 | double t0 = 0.0; |
| 3533 | double t1 = 1.0; |
| 3534 | ImPlot3DPoint d = p1 - p0; |
| 3535 | |
| 3536 | // Define the clipping boundaries |
| 3537 | const double xmin = Min.x, xmax = Max.x; |
| 3538 | const double ymin = Min.y, ymax = Max.y; |
| 3539 | const double zmin = Min.z, zmax = Max.z; |
| 3540 | |
| 3541 | // Lambda function to update t0 and t1 |
| 3542 | auto update = [&](double p, double q) -> bool { |
| 3543 | if (p == 0.0) { |
| 3544 | if (q < 0.0) |
| 3545 | return false; // Line is parallel and outside the boundary |
| 3546 | else |
| 3547 | return true; // Line is parallel and inside or coincident with boundary |
| 3548 | } |
| 3549 | double r = q / p; |
| 3550 | if (p < 0.0) { |
| 3551 | if (r > t1) |
| 3552 | return false; // Line is outside |
| 3553 | if (r > t0) |
| 3554 | t0 = r; // Move up t0 |
| 3555 | } else { |
| 3556 | if (r < t0) |
| 3557 | return false; // Line is outside |
| 3558 | if (r < t1) |
| 3559 | t1 = r; // Move down t1 |
| 3560 | } |
| 3561 | return true; |
| 3562 | }; |
| 3563 | |
| 3564 | // Clip against each boundary |
| 3565 | if (!update(-d.x, p0.x - xmin)) |
| 3566 | return false; // Left |
| 3567 | if (!update(d.x, xmax - p0.x)) |
| 3568 | return false; // Right |
| 3569 | if (!update(-d.y, p0.y - ymin)) |
| 3570 | return false; // Bottom |
| 3571 | if (!update(d.y, ymax - p0.y)) |
| 3572 | return false; // Top |
| 3573 | if (!update(-d.z, p0.z - zmin)) |
| 3574 | return false; // Near |
| 3575 | if (!update(d.z, zmax - p0.z)) |
| 3576 | return false; // Far |
| 3577 | |
| 3578 | // Compute clipped points |
| 3579 | p0_clipped = p0 + d * t0; |
| 3580 | p1_clipped = p0 + d * t1; |