| 584 | // of the plane with the four edges |
| 585 | |
| 586 | bool vtkBoundingBox::IntersectPlane(double origin[3], double normal[3]) |
| 587 | { |
| 588 | double* bounds[2] = { this->MinPnt, this->MaxPnt }; |
| 589 | assert(this->IsValid()); |
| 590 | |
| 591 | // Index[0..2] represents the order of traversing the corners of a cube |
| 592 | // in (x,y,z), (y,x,z) and (z,x,y) ordering, respectively |
| 593 | static const int Index[3][8] = { |
| 594 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 595 | { 0, 1, 4, 5, 2, 3, 6, 7 }, |
| 596 | { 0, 2, 4, 6, 1, 3, 5, 7 }, |
| 597 | }; |
| 598 | |
| 599 | double d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // stores the signed distance to a plane |
| 600 | { |
| 601 | int index(-1); |
| 602 | for (int ix = 0; ix <= 1; ix++) |
| 603 | { |
| 604 | for (int iy = 0; iy <= 1; iy++) |
| 605 | { |
| 606 | for (int iz = 0; iz <= 1; iz++) |
| 607 | { |
| 608 | double x[3] = { bounds[ix][0], bounds[iy][1], bounds[iz][2] }; |
| 609 | d[++index] = vtkPlane::Evaluate(normal, origin, x); |
| 610 | } |
| 611 | } |
| 612 | } |
| 613 | } |
| 614 | |
| 615 | int dir(-1); |
| 616 | for (dir = 2; dir >= 0; dir--) |
| 617 | { |
| 618 | // in each direction, we test if the vertices of two orthogonal faces |
| 619 | // are on either side of the plane |
| 620 | if (OppSign(d[Index[dir][0]], d[Index[dir][4]]) && |
| 621 | OppSign(d[Index[dir][1]], d[Index[dir][5]]) && OppSign(d[Index[dir][2]], d[Index[dir][6]]) && |
| 622 | OppSign(d[Index[dir][3]], d[Index[dir][7]])) |
| 623 | { |
| 624 | break; |
| 625 | } |
| 626 | } |
| 627 | if (dir < 0) |
| 628 | { |
| 629 | return false; |
| 630 | } |
| 631 | |
| 632 | double sign = Sign(normal[dir]); |
| 633 | double size = fabs((bounds[1][dir] - bounds[0][dir]) * normal[dir]); |
| 634 | double t = sign > 0 ? 1 : 0; |
| 635 | for (int i = 0; i < 4; i++) |
| 636 | { |
| 637 | if (size == 0) |
| 638 | continue; // shouldn't happen |
| 639 | double ti = fabs(d[Index[dir][i]]) / size; |
| 640 | if (sign > 0 && ti < t) |
| 641 | { |
| 642 | t = ti; |
| 643 | } |