Program Listing for File intersection.cc¶
↰ Return to documentation for file (src/intersection.cc
)
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* The ACME project *
* *
* Copyright (c) 2020, Davide Stocco and Enrico Bertolazzi. *
* *
* The ACME project and its components are supplied under the terms of *
* the open source BSD 2-Clause License. The contents of the ACME *
* project and its components may not be copied or disclosed except in *
* accordance with the terms of the BSD 2-Clause License. *
* *
* URL: https://opensource.org/licenses/BSD-2-Clause *
* *
* Davide Stocco *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: davide.stocco@unitn.it *
* *
* Enrico Bertolazzi *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: enrico.bertolazzi@unitn.it *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "acme.hh"
namespace acme
{
/*\
| ___ _ _ _
| |_ _|_ __ | |_ ___ _ __ ___ ___ ___| |_(_) ___ _ __
| | || '_ \| __/ _ \ '__/ __|/ _ \/ __| __| |/ _ \| '_ \
| | || | | | || __/ | \__ \ __/ (__| |_| | (_) | | | |
| |___|_| |_|\__\___|_| |___/\___|\___|\__|_|\___/|_| |_|
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
entity *
Intersection(
entity const * entity0_in,
entity const * entity1_in,
real tolerance
)
{
#define CMD "acme::Intersection(entity, entity): "
integer slide = entity0_in->level() * 100 + entity1_in->level();
bool collide = false;
entity *entity_out = nullptr;
if (entity0_in->isPoint() || entity1_in->isPoint())
{
switch (slide)
{
// - - - - - - - - - - - - - - POINT - - - - - - - - - - - - - -
case 101:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 103:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 104:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 105:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 106:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 107:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 108:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 301:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 401:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 501:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 601:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 701:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 801:
entity_out = new point();
collide = Intersection(
*dynamic_cast<point const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
default:
collide = false;
ACME_ERROR(CMD "exception not handled (punctual).")
break;
}
}
else if (IsCollinear(entity0_in, entity1_in))
{
switch (slide)
{
// - - - - - - - - - - - - - - LINE - - - - - - - - - - - - - -
case 303:
entity_out = new line();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<line *>(entity_out),
tolerance);
break;
case 304:
entity_out = new ray();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<ray *>(entity_out),
tolerance);
break;
case 306:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - RAY - - - - - - - - - - - - - -
case 403:
entity_out = new ray();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ray *>(entity_out),
tolerance);
break;
case 404:
entity_out = new ray();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<ray *>(entity_out),
tolerance);
if (!collide)
{delete entity_out;}
else
{break;}
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
if (!collide)
{delete entity_out;}
else
{break;}
ACME_ERROR(CMD "exception not handled (ray/ray intersection).")
break;
case 406:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - SEGMENT - - - - - - - - - - - - - -
case 603:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 604:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 606:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - DEFAULT - - - - - - - - - - - - - -
default:
ACME_ERROR(CMD "exception not handled (colliear).")
break;
}
}
else if (IsCoplanar(entity0_in, entity1_in))
{
switch (slide)
{
// - - - - - - - - - - - - - - LINE - - - - - - - - - - - - - -
case 303:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 304:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 305:
entity_out = new line();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<line *>(entity_out),
tolerance);
break;
case 306:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 307:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 308:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - RAY - - - - - - - - - - - - - -
case 403:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 404:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 405:
entity_out = new ray();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<ray *>(entity_out),
tolerance);
break;
case 406:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 407:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 408:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - PLANE - - - - - - - - - - - - - -
case 503:
entity_out = new line();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<line *>(entity_out),
tolerance);
break;
case 504:
entity_out = new ray();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<ray *>(entity_out),
tolerance);
break;
case 505:
entity_out = new plane();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<plane *>(entity_out),
tolerance);
break;
case 506:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 507:
entity_out = new triangle();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<triangle *>(entity_out),
tolerance);
break;
case 508:
entity_out = new disk();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<disk *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - SEGMENT - - - - - - - - - - - - - -
case 603:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 604:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 605:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 606:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 607:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 608:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - TRIANGLE - - - - - - - - - - - - - -
case 703:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 704:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 705:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 706:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 707:
entity_out = new none();
collide = Intersection(
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
case 708:
entity_out = new none();
collide = Intersection(
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - DISK - - - - - - - - - - - - - -
case 803:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 804:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 805:
entity_out = new disk();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<disk *>(entity_out),
tolerance);
break;
case 806:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 807:
entity_out = new none();
collide = Intersection(
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
case 808:
entity_out = new none();
collide = Intersection(
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - DEFAULT - - - - - - - - - - - - - -
default:
ACME_ERROR(CMD "exception not handled (coplanar).")
break;
}
}
else
{
switch (slide)
{
// - - - - - - - - - - - - - - LINE - - - - - - - - - - - - - -
case 303:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 304:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 305:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 306:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 307:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 308:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 309:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - RAY - - - - - - - - - - - - - -
case 403:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 404:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 405:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 406:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 407:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 408:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 409:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - PLANE - - - - - - - - - - - - - -
case 503:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 504:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 505:
entity_out = new line();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<line *>(entity_out),
tolerance);
break;
case 506:
entity_out = new point();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 507:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 508:
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 509:
entity_out = new disk();
collide = Intersection(
*dynamic_cast<plane const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<disk *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - SEGMENT - - - - - - - - - - - - - -
case 603:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 604:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 605:
entity_out = new point();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 606:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 607:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 608:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 609:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - TRIANGLE - - - - - - - - - - - - - -
case 703:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 704:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 705:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 706:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 707:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 708:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 709:
entity_out = new none();
collide = Intersection(
*dynamic_cast<triangle const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - DISK - - - - - - - - - - - - - -
case 803:
entity_out = new point();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 804:
entity_out = new point();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 805:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 806:
entity_out = new point();
collide = Intersection(
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<point *>(entity_out),
tolerance);
break;
case 807:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 808:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 809:
entity_out = new none();
collide = Intersection(
*dynamic_cast<disk const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - BALL - - - - - - - - - - - - - -
case 903:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<line const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 904:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<ray const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 905:
entity_out = new disk();
collide = Intersection(
*dynamic_cast<plane const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<disk *>(entity_out),
tolerance);
break;
case 906:
entity_out = new segment();
collide = Intersection(
*dynamic_cast<segment const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<segment *>(entity_out),
tolerance);
break;
case 907:
entity_out = new none();
collide = Intersection(
*dynamic_cast<triangle const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
case 908:
entity_out = new none();
collide = Intersection(
*dynamic_cast<disk const *>(entity1_in),
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
case 909:
entity_out = new none();
collide = Intersection(
*dynamic_cast<ball const *>(entity0_in),
*dynamic_cast<ball const *>(entity1_in),
*dynamic_cast<none *>(entity_out),
tolerance);
break;
// - - - - - - - - - - - - - - DEFAULT - - - - - - - - - - - - - -
default:
ACME_ERROR(CMD "exception not handled (general).")
break;
}
}
if (!collide)
{
delete entity_out;
entity_out = new none();
return entity_out;
}
return entity_out;
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*\
| ____ _ _ _
| / ___|___ | | (_)_ __ ___ __ _ _ __
| | | / _ \| | | | '_ \ / _ \/ _` | '__|
| | |__| (_) | | | | | | | __/ (_| | |
| \____\___/|_|_|_|_| |_|\___|\__,_|_|
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line0_in,
line const & line1_in,
line & line_out,
real tolerance
)
{
if (IsCollinear(line0_in, line1_in, tolerance))
{
line_out = line0_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray0_in,
ray const & ray1_in,
ray & ray_out,
real tolerance
)
{
if (IsCollinear(ray0_in, ray1_in, tolerance) && ray0_in.direction().dot(ray1_in.direction()) > real(0.0))
{
if (ray0_in.isInside(ray1_in.origin(), tolerance))
{
ray_out = ray1_in;
return true;
}
else if (ray1_in.isInside(ray0_in.origin(), tolerance))
{
ray_out = ray0_in;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray0_in,
ray const & ray1_in,
segment & segment_out,
real tolerance
)
{
if (IsCollinear(ray0_in, ray1_in, tolerance) && ray0_in.direction().dot(ray1_in.direction()) < real(0.0))
{
if (ray0_in.isInside(ray1_in.origin(), tolerance) && ray1_in.isInside(ray0_in.origin(), tolerance))
{
segment_out.vertex(0) = ray0_in.origin();
segment_out.vertex(1) = ray1_in.origin();
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment0_in,
segment const & segment1_in,
segment & segment_out,
real tolerance
)
{
#define CMD "acme::Intersection(segment, segment, segment): "
if (IsCollinear(segment0_in, segment1_in, tolerance))
{
//
// p0 p1 p0 p1
// o---s0---o o---s1---o
//
point s0_p0(segment0_in.vertex(0));
point s0_p1(segment0_in.vertex(1));
point s1_p0(segment1_in.vertex(0));
point s1_p1(segment1_in.vertex(1));
int sx_px_in_sx =
int(segment0_in.isInside(s1_p1, tolerance)) +
int(segment0_in.isInside(s1_p0, tolerance)) * 10 +
int(segment1_in.isInside(s0_p1, tolerance)) * 100 +
int(segment1_in.isInside(s0_p0, tolerance)) * 1000;
switch (sx_px_in_sx)
{
//
// Segments coincides
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 1 | 1 | 1 | 1 |
case 1111: // 1111
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s0_p1;
return true;
// An extrema coincides
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 0 | 1 | 1 | 1 |
// | 1 | 0 | 1 | 1 |
// | 1 | 1 | 0 | 1 |
// | 1 | 1 | 1 | 0 |
case 111: // 0111
segment_out.vertex(0) = s1_p0;
segment_out.vertex(1) = s1_p1;
return true;
case 1011: // 1011
segment_out.vertex(0) = s1_p0;
segment_out.vertex(1) = s1_p1;
return true;
case 1101: // 1101
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s0_p1;
return true;
case 1110: // 1110
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s0_p1;
return true;
// Partial overlap
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 0 | 1 | 0 | 1 |
// | 0 | 1 | 1 | 0 |
// | 1 | 0 | 0 | 1 |
// | 1 | 0 | 1 | 0 |
case 101: // 0101
segment_out.vertex(0) = s0_p1;
segment_out.vertex(1) = s1_p1;
return true;
case 110: // 0110
segment_out.vertex(0) = s0_p1;
segment_out.vertex(1) = s1_p0;
return true;
case 1001: // 1001
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s1_p1;
return true;
case 1010: // 1010
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s1_p0;
return true;
// One segment is inside
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 1 | 1 | 0 | 0 |
// | 0 | 0 | 1 | 1 |
case 1100: // 1100
segment_out.vertex(0) = s0_p0;
segment_out.vertex(1) = s0_p1;
return true;
case 11: // 0011
segment_out.vertex(0) = s1_p0;
segment_out.vertex(1) = s1_p1;
return true;
// No Intersection case
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 0 | 0 | 0 | 0 |
case 0: // 0000
return false;
// Exception not handled
// | s0_p0_in_s1 | s0_p1_in_s1 | s1_p0_in_s0 | s1_p1_in_s0 |
// | 0 | 0 | 0 | 1 |
// | 0 | 0 | 1 | 0 |
// | 0 | 1 | 0 | 0 |
// | 1 | 0 | 0 | 0 |
default:
ACME_ERROR(CMD "exception not handled.")
}
}
else
{
return false;
}
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
ray const & ray_in,
ray & ray_out,
real tolerance
)
{
if (IsCollinear(line_in, ray_in, tolerance))
{
ray_out = ray_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
segment const & segment_in,
segment & segment_out,
real tolerance
)
{
if (IsCollinear(line_in, segment_in, tolerance))
{
segment_out = segment_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
segment const & segment_in,
segment & segment_out,
real tolerance
)
{
point point_0(segment_in.vertex(0));
point point_1(segment_in.vertex(1));
if (IsCollinear(ray_in, segment_in, tolerance))
{
if (ray_in.isInside(point_0, tolerance) && ray_in.isInside(point_1, tolerance))
{
segment_out = segment_in;
return true;
}
else if (ray_in.isInside(point_0, tolerance) && !ray_in.isInside(point_1, tolerance))
{
segment_out.vertex(0) = ray_in.origin();
segment_out.vertex(1) = point_0;
return true;
}
else if (!ray_in.isInside(point_0, tolerance) && ray_in.isInside(point_1, tolerance))
{
segment_out.vertex(0) = ray_in.origin();
segment_out.vertex(1) = point_1;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*\
| ____ _ _
| | _ \ _ _ _ __ ___| |_ _ _ __ _| |
| | |_) | | | | '_ \ / __| __| | | |/ _` | |
| | __/| |_| | | | | (__| |_| |_| | (_| | |
| |_| \__,_|_| |_|\___|\__|\__,_|\__,_|_|
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point0_in,
point const & point1_in,
point & point_out,
real tolerance
)
{
if (point0_in.isApprox(point1_in, tolerance))
{
point_out = point0_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
line const & line_in,
point & point_out,
real tolerance
)
{
if (line_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
ray const & ray_in,
point & point_out,
real tolerance
)
{
if (ray_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
plane const & plane_in,
point & point_out,
real tolerance
)
{
if (plane_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
segment const & segment_in,
point & point_out,
real tolerance
)
{
if (segment_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
triangle const & triangle_in,
point & point_out,
real tolerance
)
{
if (triangle_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
point const & point_in,
disk const & disk_in,
point & point_out,
real tolerance
)
{
if (disk_in.isInside(point_in, tolerance))
{
point_out = point_in;
return true;
}
else
{
return false;
}
}
/*\
| ____ _
| / ___| ___ _ __ ___ _ __(_) ___
| | | _ / _ \ '_ \ / _ \ '__| |/ __|
| | |_| | __/ | | | __/ | | | (__
| \____|\___|_| |_|\___|_| |_|\___|
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line0_in,
line const & line1_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(line0_in, line1_in, tolerance))
{
point origin_0(line0_in.origin());
vec3 direction_0(line0_in.direction());
point origin_1(line1_in.origin());
vec3 direction_1(line1_in.direction());
vec3 a(direction_0.cross(direction_1));
vec3 b((origin_1 - origin_0).cross(direction_1));
real t = b.dot(a) / a.dot(a);
point_out = origin_0 + (t * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray0_in,
ray const & ray1_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(ray0_in, ray1_in, tolerance))
{
point origin_0(ray0_in.origin());
vec3 direction_0(ray0_in.direction());
point origin_1(ray1_in.origin());
vec3 direction_1(ray1_in.direction());
vec3 a_0(direction_0.cross(direction_1));
vec3 b_0((origin_1 - origin_0).cross(direction_1));
real t0 = b_0.dot(a_0) / a_0.dot(a_0);
vec3 a_1(-a_0);
vec3 b_1((origin_0 - origin_1).cross(direction_0));
real t1 = b_1.dot(a_1) / a_1.dot(a_1);
if (t0 < real(0.0) - tolerance || t1 < real(0.0) - tolerance)
{return false;}
point_out = origin_0 + (t0 * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment0_in,
segment const & segment1_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(segment0_in, segment1_in, tolerance))
{
point origin_0(segment0_in.vertex(0));
vec3 direction_0(segment0_in.toVector());
point origin_1(segment1_in.vertex(0));
vec3 direction_1(segment1_in.toVector());
vec3 a_0(direction_0.cross(direction_1));
vec3 b_0((origin_1 - origin_0).cross(direction_1));
real t0 = b_0.dot(a_0) / a_0.dot(a_0);
vec3 a_1(-a_0);
vec3 b_1((origin_0 - origin_1).cross(direction_0));
real t1 = b_1.dot(a_1) / a_1.dot(a_1);
if (t0 < real(0.0) - tolerance || t1 < real(0.0) - tolerance || t0 > real(1.0) + tolerance || t1 > real(1.0) + tolerance)
{return false;}
point_out = origin_0 + (t0 * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
ray const & ray_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(line_in, ray_in, tolerance))
{
point origin_0(line_in.origin());
vec3 direction_0(line_in.direction());
point origin_1(ray_in.origin());
vec3 direction_1(ray_in.direction());
vec3 a_0(direction_0.cross(direction_1));
vec3 b_0((origin_1 - origin_0).cross(direction_1));
real t0 = b_0.dot(a_0) / a_0.dot(a_0);
vec3 a_1(-a_0);
vec3 b_1((origin_0 - origin_1).cross(direction_0));
real t1 = b_1.dot(a_1) / a_1.dot(a_1);
if (t1 < real(0.0) - tolerance)
{return false;}
point_out = origin_0 + (t0 * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
segment const & segment_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(line_in, segment_in, tolerance))
{
point origin_0(line_in.origin());
vec3 direction_0(line_in.direction());
point origin_1(segment_in.vertex(0));
vec3 direction_1(segment_in.toVector());
vec3 a_0(direction_0.cross(direction_1));
vec3 b_0((origin_1 - origin_0).cross(direction_1));
real t0 = b_0.dot(a_0) / a_0.dot(a_0);
vec3 a_1(-a_0);
vec3 b_1((origin_0 - origin_1).cross(direction_0));
real t1 = b_1.dot(a_1) / a_1.dot(a_1);
if (t1 < real(0.0) - tolerance || t1 > real(1.0) + tolerance)
{return false;}
point_out = origin_0 + (t0 * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
segment const & segment_in,
point & point_out,
real tolerance
)
{
if (!IsParallel(ray_in, segment_in, tolerance))
{
point origin_0(ray_in.origin());
vec3 direction_0(ray_in.direction());
point origin_1(segment_in.vertex(0));
vec3 direction_1(segment_in.toVector());
vec3 a_0(direction_0.cross(direction_1));
vec3 b_0((origin_1 - origin_0).cross(direction_1));
real t0 = b_0.dot(a_0) / a_0.dot(a_0);
vec3 a_1(-a_0);
vec3 b_1((origin_0 - origin_1).cross(direction_0));
real t1 = b_1.dot(a_1) / a_1.dot(a_1);
if (t0 < real(0.0) - tolerance || t1 < real(0.0) - tolerance || t1 > real(1.0) + tolerance)
{return false;}
point_out = origin_0 + (t0 * direction_0);
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*\
| ____ _
| / ___|___ _ __ | | __ _ _ __ __ _ _ __
| | | / _ \| '_ \| |/ _` | '_ \ / _` | '__|
| | |__| (_) | |_) | | (_| | | | | (_| | |
| \____\___/| .__/|_|\__,_|_| |_|\__,_|_|
| |_|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane0_in,
plane const & plane1_in,
plane & plane_out,
real tolerance
)
{
if (IsCoplanar(plane0_in, plane1_in, tolerance))
{
plane_out = plane0_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
triangle const & triangle0_in,
triangle const & triangle1_in,
none & /*none_out*/,
real tolerance
)
{
if (!IsCoplanar(triangle0_in, triangle1_in, tolerance)) {
return Intersection(triangle0_in, triangle1_in, DUMMY_SEGMENT, tolerance);
}
return triangle0_in.isInside(triangle1_in.vertex(0), tolerance) ||
triangle0_in.isInside(triangle1_in.vertex(1), tolerance) ||
triangle0_in.isInside(triangle1_in.vertex(2), tolerance) ||
triangle1_in.isInside(triangle0_in.vertex(0), tolerance) ||
triangle1_in.isInside(triangle0_in.vertex(1), tolerance) ||
triangle1_in.isInside(triangle0_in.vertex(2), tolerance);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
disk const & /*disk0_in*/,
disk const & /*disk1_in*/,
none & /*none_out*/,
real /*tolerance*/
)
{
#define CMD "acme::Intersection(disk, disk): "
ACME_ERROR(CMD "function not supported.")
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ball const & /*ball0_in*/,
ball const & /*ball1_in*/,
none & /*none_out*/,
real /*tolerance*/
)
{
#define CMD "acme::Intersection(ball, ball): "
ACME_ERROR(CMD "function not supported.")
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
plane const & plane_in,
line & line_out,
real tolerance
)
{
if (IsCoplanar(line_in, plane_in, tolerance))
{
line_out = line_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
triangle const & triangle_in,
segment & segment_out,
real tolerance
)
{
#define CMD "acme::Intersection(line, triangle, segment): "
point point0, point1, point2;
bool bool0 = Intersection(line_in, triangle_in.edge(0), point0, tolerance);
bool bool1 = Intersection(line_in, triangle_in.edge(1), point1, tolerance);
bool bool2 = Intersection(line_in, triangle_in.edge(2), point2, tolerance);
if (bool0 && bool1 && !bool2)
{
segment_out.vertex(0) = point0;
segment_out.vertex(1) = point1;
return true;
}
else if (!bool0 && bool1 && bool2)
{
segment_out.vertex(0) = point1;
segment_out.vertex(1) = point2;
return true;
}
else if (bool0 && !bool1 && bool2)
{
segment_out.vertex(0) = point2;
segment_out.vertex(1) = point0;
return true;
}
else if (bool0 && bool1 && bool2)
{
if (point0.isApprox(point1, tolerance))
{
segment_out.vertex(0) = point1;
segment_out.vertex(1) = point2;
return true;
}
else if (point1.isApprox(point2, tolerance))
{
segment_out.vertex(0) = point0;
segment_out.vertex(1) = point1;
return true;
}
else if (point0.isApprox(point2, tolerance))
{
segment_out.vertex(0) = point0;
segment_out.vertex(1) = point1;
return true;
}
else
{
ACME_ERROR(CMD "exception not handled.")
}
}
else
{
return false;
}
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
disk const & disk_in,
segment & segment_out,
real tolerance
)
{
real disk_radius = disk_in.radius();
point disk_center(disk_in.center());
point line_origin(line_in.origin());
vec3 line_direction(line_in.direction());
vec3 diff(line_origin - disk_center);
real a2 = line_direction.dot(line_direction);
real a1 = diff.dot(line_direction);
real a0 = diff.dot(diff) - disk_radius * disk_radius;
real discriminant = a1 * a1 - a0 * a2;
if (discriminant < -tolerance)
return false;
real inv = real(1.0) / a2;
if (std::abs(discriminant) < tolerance)
{
point int_point(line_origin - (a1 * inv) * line_direction);
segment_out.vertex(0) = int_point;
segment_out.vertex(1) = int_point;
return true;
}
real root = std::sqrt(discriminant);
segment_out.vertex(0) = line_origin - ((a1 + root) * inv) * line_direction;
segment_out.vertex(1) = line_origin - ((a1 - root) * inv) * line_direction;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
plane const & plane_in,
ray & ray_out,
real tolerance
)
{
if (IsCoplanar(ray_in, plane_in, tolerance))
{
ray_out = ray_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
triangle const & triangle_in,
segment & segment_out,
real tolerance
)
{
segment tmp_segment;
if (Intersection(line(ray_in.origin(), ray_in.direction()), triangle_in, tmp_segment, tolerance))
return Intersection(ray_in, tmp_segment, segment_out, tolerance);
else
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
disk const & disk_in,
segment & segment_out,
real tolerance
)
{
real disk_radius = disk_in.radius();
point disk_center(disk_in.center());
point ray_origin(ray_in.origin());
vec3 ray_direction(ray_in.direction());
vec3 diff(ray_origin - disk_center);
real a2 = ray_direction.dot(ray_direction);
real a1 = diff.dot(ray_direction);
real a0 = diff.dot(diff) - disk_radius * disk_radius;
real discriminant = a1 * a1 - a0 * a2;
if (discriminant < -tolerance)
{return false;}
real inv = 1 / a2;
if (std::abs(discriminant) < tolerance)
{
real t = -a1 * inv;
if (t < real(0.0))
{return false;}
point int_point(ray_origin + t * ray_direction);
segment_out.vertex(0) = int_point;
segment_out.vertex(1) = int_point;
return true;
}
real root = std::sqrt(discriminant);
real t0 = -(a1 + root) * inv;
real t1 = -(a1 - root) * inv;
if (t0 < real(0.0) && t1 < real(0.0))
{return false;}
t0 = std::max(real(0.0), t0);
t1 = std::max(real(0.0), t1);
segment_out.vertex(0) = ray_origin + t0 * ray_direction;
segment_out.vertex(1) = ray_origin + t1 * ray_direction;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
segment const & segment_in,
segment & segment_out,
real tolerance
)
{
if (IsCoplanar(plane_in, segment_in, tolerance))
{
segment_out = segment_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
triangle const & triangle_in,
triangle & triangle_out,
real tolerance
)
{
if (IsCoplanar(plane_in, triangle_in, tolerance))
{
triangle_out = triangle_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
disk const & disk_in,
disk & disk_out,
real tolerance
)
{
if (IsCoplanar(plane_in, disk_in, tolerance))
{
disk_out = disk_in;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment_in,
triangle const & triangle_in,
segment & segment_out,
real tolerance
)
{
line tmp_line(segment_in.vertex(0), segment_in.toUnitVector());
segment tmp_segment;
if (Intersection(tmp_line, triangle_in, tmp_segment, tolerance))
{return Intersection(segment_in, tmp_segment, segment_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment_in,
disk const & disk_in,
segment & segment_out,
real tolerance
)
{
if (segment_in.isDegenerated(tolerance) || disk_in.isDegenerated(tolerance))
{return false;}
real disk_radius = disk_in.radius();
point disk_center(disk_in.center());
point segment_origin(segment_in.vertex(0));
vec3 segment_direction(segment_in.toVector());
vec3 diff(segment_origin - disk_center);
real a2 = segment_direction.dot(segment_direction);
real a1 = diff.dot(segment_direction);
real a0 = diff.dot(diff) - disk_radius * disk_radius;
real discriminant = a1 * a1 - a0 * a2;
if (discriminant < -tolerance)
{return false;}
real inv = real(1.0) / a2;
if (std::abs(discriminant) < tolerance)
{
real t = -a1 * inv;
if (t < real(0.0) || t > real(1.0))
{return false;}
point int_point(segment_origin + t * segment_direction);
segment_out.vertex(0) = int_point;
segment_out.vertex(1) = int_point;
return true;
}
real root = std::sqrt(discriminant);
real t0 = -(a1 + root) * inv;
real t1 = -(a1 - root) * inv;
if ((t0 < real(0.0) && t1 < real(0.0)) || (t0 > real(1.0) && t1 > real(1.0)))
{return false;}
t0 = std::max(real(0.0), std::min(t0, real(1.0)));
t1 = std::max(real(0.0), std::min(t1, real(1.0)));
segment_out.vertex(0) = segment_origin + t0 * segment_direction;
segment_out.vertex(1) = segment_origin + t1 * segment_direction;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
triangle const & /*triangle_in*/,
disk const & /*disk_in*/,
none & /*none_out*/,
real /*tolerance*/
)
{
#define CMD "acme::Intersection(triangle, disk): "
ACME_ERROR(CMD "function not supported.")
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*\
| _ _ ____ _
| | \ | | ___ _ __ / ___|___ _ __ | | __ _ _ __ __ _ _ __
| | \| |/ _ \| '_ \| | / _ \| '_ \| |/ _` | '_ \ / _` | '__|
| | |\ | (_) | | | | |__| (_) | |_) | | (_| | | | | (_| | |
| |_| \_|\___/|_| |_|\____\___/| .__/|_|\__,_|_| |_|\__,_|_|
| |_|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane0_in,
plane const & plane1_in,
line & line,
real tolerance
)
{
vec3 normal0(plane0_in.normal().normalized());
vec3 normal1(plane1_in.normal().normalized());
real d0 = -plane0_in.d();
real d1 = -plane1_in.d();
vec3 direction = normal0.cross(normal1);
real dot = normal0.dot(normal1);
real norm = direction.norm();
if (IsApprox(norm * norm, 0.0, tolerance))
{
return false;
}
else
{
real invDet = real(1.0) / (real(1.0) - dot * dot);
real c0 = (d0 - dot * d1) * invDet;
real c1 = (d1 - dot * d0) * invDet;
line.origin() = c0 * normal0 + c1 * normal1;
line.direction() = direction;
return true;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane0_in,
plane const & plane1_in,
plane const & plane2_in,
point & point_out,
real tolerance
)
{
vec3 normal0(plane0_in.normal());
vec3 normal1(plane1_in.normal());
vec3 normal2(plane2_in.normal());
mat3 Mat;
Mat << normal0, normal1, normal2;
real det = Mat.determinant();
if (IsApprox(det, 0.0, tolerance))
{
return false;
}
else
{
point_out = (normal1.cross(normal2) * -plane0_in.d() +
normal2.cross(normal0) * -plane1_in.d() +
normal0.cross(normal1) * -plane2_in.d()) /
det;
return true;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
triangle const & triangle0_in,
triangle const & triangle1_in,
segment & segment_out,
real tolerance
)
{
line tmp_line;
if (Intersection(triangle0_in.layingPlane(), triangle1_in.layingPlane(), tmp_line, tolerance))
{
segment tmp_segment0, tmp_segment1;
Intersection(tmp_line, triangle0_in, tmp_segment0, tolerance);
Intersection(tmp_line, triangle1_in, tmp_segment1, tolerance);
return Intersection(tmp_segment0, tmp_segment1, segment_out, tolerance);
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
disk const & disk0_in,
disk const & disk1_in,
segment & segment_out,
real tolerance
)
{
line tmp_line;
if (Intersection(disk0_in.layingPlane(), disk1_in.layingPlane(), tmp_line, tolerance))
{
segment tmp_segment0, tmp_segment1;
Intersection(tmp_line, disk0_in, tmp_segment0, tolerance);
Intersection(tmp_line, disk1_in, tmp_segment1, tolerance);
return Intersection(tmp_segment0, tmp_segment1, segment_out, tolerance);
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
plane const & plane_in,
point & point_out,
real tolerance
)
{
vec3 origin(line_in.origin());
vec3 direction(line_in.direction());
real det = plane_in.normal().dot(direction);
if (std::abs(det) > tolerance)
{
real t = (plane_in.origin() - origin).dot(plane_in.normal()) / det;
point_out = origin + t * direction;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
triangle const & triangle_in,
point & point_out,
real tolerance
)
{
point vertex0(triangle_in.vertex(0));
point vertex1(triangle_in.vertex(1));
point vertex2(triangle_in.vertex(2));
vec3 edge1(vertex1 - vertex0);
vec3 edge2(vertex2 - vertex0);
point origin(line_in.origin());
vec3 direction(line_in.direction());
vec3 h, s, q;
real a, f, u, v;
h = direction.cross(edge2);
a = edge1.dot(h);
if (a > -tolerance && a < tolerance)
{return false;}
f = real(1.0) / a;
s = origin - vertex0;
u = f * s.dot(h);
if (u < real(0.0) - tolerance || u > real(1.0) + tolerance)
{return false;}
q = s.cross(edge1);
v = f * direction.dot(q);
if (v < real(0.0) - tolerance || u + v > real(1.0) + tolerance)
{return false;}
real t = f * edge2.dot(q);
point_out = origin + t * direction;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
disk const & disk_in,
point & point_out,
real tolerance
)
{
if (Intersection(line_in, disk_in.layingPlane(), point_out, tolerance))
{return disk_in.isInside(point_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
line const & line_in,
ball const & ball_in,
segment & segment_out,
real tolerance
)
{
vec3 origin(line_in.origin());
vec3 direction(line_in.toUnitVector());
vec3 diff(origin - ball_in.center());
real a0 = diff.dot(diff) - ball_in.radius() * ball_in.radius();
real a1 = direction.dot(diff);
real discr = a1 * a1 - a0;
if (discr > tolerance)
{
real root = std::sqrt(discr);
segment_out.vertex(0) = origin + (-a1 - root) * direction;
segment_out.vertex(1) = origin + (-a1 + root) * direction;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
plane const & plane_in,
point & point_out,
real tolerance
)
{
vec3 origin(ray_in.origin());
vec3 direction(ray_in.direction());
real det = direction.dot(plane_in.normal());
if (std::abs(det) > tolerance)
{
real t = -(origin - plane_in.origin()).dot(plane_in.normal()) / det;
if (t > tolerance)
{
point_out = origin + t * direction;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
triangle const & triangle_in,
point & point_out,
real tolerance
)
{
point vertex0(triangle_in.vertex(0));
point vertex1(triangle_in.vertex(1));
point vertex2(triangle_in.vertex(2));
vec3 edge1(vertex1 - vertex0);
vec3 edge2(vertex2 - vertex0);
point origin(ray_in.origin());
vec3 direction(ray_in.direction());
vec3 h, s, q;
real a, f, u, v;
h = direction.cross(edge2);
a = edge1.dot(h);
if (a > -tolerance && a < tolerance)
{return false;}
f = real(1.0) / a;
s = origin - vertex0;
u = f * s.dot(h);
if (u < real(0.0) - tolerance || u > real(1.0) + tolerance)
{return false;}
q = s.cross(edge1);
v = f * direction.dot(q);
if (v < real(0.0) - tolerance || u + v > real(1.0) + tolerance)
{return false;}
real t = f * edge2.dot(q);
if (t >= real(0.0) - tolerance)
{
point_out = origin + t * direction;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
disk const & disk_in,
point & point_out,
real tolerance
)
{
if (Intersection(ray_in, disk_in.layingPlane(), point_out, tolerance))
{return disk_in.isInside(point_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
ray const & ray_in,
ball const & ball_in,
segment & segment_out,
real tolerance
)
{
vec3 origin(ray_in.origin());
vec3 direction(ray_in.toUnitVector());
vec3 diff(origin - ball_in.center());
real a0 = diff.dot(diff) - ball_in.radius() * ball_in.radius();
real a1 = direction.dot(diff);
real discr = a1 * a1 - a0;
if (discr > tolerance)
{
real root = std::sqrt(discr);
real t0 = -a1 - root;
real t1 = -a1 + root;
if (t0 < real(0.0) && t1 < real(0.0))
{return false;}
t0 = std::max(t0, real(0.0));
t1 = std::max(t1, real(0.0));
segment_out.vertex(0) = origin + t0 * direction;
segment_out.vertex(1) = origin + t1 * direction;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
segment const & segment_in,
point & point_out,
real tolerance
)
{
vec3 origin(segment_in.vertex(0));
vec3 direction(segment_in.toVector());
real det = direction.dot(plane_in.normal());
if (std::abs(det) > tolerance)
{
real t = -(origin - plane_in.origin()).dot(plane_in.normal()) / det;
if (t >= real(0.0) - tolerance && t <= real(1.0) + tolerance)
{
point_out = origin + t * direction;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
triangle const & triangle_in,
segment & segment_out,
real tolerance
)
{
line tmp_line;
if (Intersection(plane_in, triangle_in.layingPlane(), tmp_line, tolerance))
{return Intersection(tmp_line, triangle_in, segment_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
disk const & disk_in,
segment & segment_out,
real tolerance
)
{
line tmp_line;
if (Intersection(plane_in, disk_in.layingPlane(), tmp_line, tolerance))
{return Intersection(tmp_line, disk_in, segment_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
plane const & plane_in,
ball const & ball_in,
disk & disk_out,
real /*tolerance*/
)
{
vec3 normal(plane_in.unitNormal());
real signed_distance = (ball_in.center() - plane_in.origin()).dot(normal);
real distance = std::abs(signed_distance);
if (distance <= ball_in.radius())
{
disk_out.radius() = std::sqrt((ball_in.radius() + distance) * (ball_in.radius() - distance));
disk_out.center() = ball_in.center() - signed_distance * normal;
disk_out.normal() = normal;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment_in,
triangle const & triangle_in,
point & point_out,
real tolerance
)
{
point vertex0(triangle_in.vertex(0));
point vertex1(triangle_in.vertex(1));
point vertex2(triangle_in.vertex(2));
vec3 edge1(vertex1 - vertex0);
vec3 edge2(vertex2 - vertex0);
point origin(segment_in.vertex(0));
vec3 direction(segment_in.toVector());
vec3 h, s, q;
real a, f, u, v;
h = direction.cross(edge2);
a = edge1.dot(h);
if (a > -tolerance && a < tolerance)
{return false;}
f = real(1.0) / a;
s = origin - vertex0;
u = f * s.dot(h);
if (u < real(0.0) - tolerance || u > real(1.0) + tolerance)
{return false;}
q = s.cross(edge1);
v = f * direction.dot(q);
if (v < real(0.0) - tolerance || u + v > real(1.0) + tolerance)
{return false;}
real t = f * edge2.dot(q);
if (t >= real(0.0) - tolerance && t <= real(1.0) + tolerance)
{
point_out = origin + direction * t;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment_in,
disk const & disk_in,
point & point_out,
real tolerance
)
{
if (Intersection(disk_in.layingPlane(), segment_in, point_out, tolerance))
return disk_in.isInside(point_out, tolerance);
else
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
segment const & segment_in,
ball const & ball_in,
segment & segment_out,
real tolerance
)
{
vec3 origin(segment_in.vertex(0));
vec3 direction(segment_in.toVector());
vec3 diff(origin - ball_in.center());
real a0 = diff.dot(diff) - ball_in.radius() * ball_in.radius();
real a1 = direction.dot(diff);
real discr = a1 * a1 - a0;
if (discr > tolerance)
{
real root = std::sqrt(discr);
real t0 = -a1 - root;
real t1 = -a1 + root;
if ((t0 < real(0.0) && t1 < real(0.0)) || (t0 > real(1.0) && t1 > real(1.0)))
{return false;}
t0 = std::max(t0, real(0.0));
t0 = std::min(t0, real(1.0));
t1 = std::max(t1, real(0.0));
t1 = std::min(t1, real(1.0));
segment_out.vertex(0) = origin + t0 * direction;
segment_out.vertex(1) = origin + t1 * direction;
return true;
}
else
{
return false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
triangle const & triangle_in,
disk const & disk_in,
segment & segment_out,
real tolerance
)
{
segment tmp_segment;
if (Intersection(disk_in.layingPlane(), triangle_in, tmp_segment, tolerance))
{return Intersection(tmp_segment, disk_in, segment_out, tolerance);}
else
{return false;}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
triangle const & /*triangle_in*/,
ball const & /*ball_in*/,
none & /*none_out*/,
real /*tolerance*/
)
{
#define CMD "acme::Intersection(triangle, ball): "
ACME_ERROR(CMD "function not supported.")
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
disk const & /*disk_in*/,
ball const & /*ball_in*/,
none & /*none_out*/,
real /*tolerance*/
)
{
#define CMD "acme::Intersection(disk, ball): "
ACME_ERROR(CMD "function not supported.")
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*\
| __ __ _ _ _
| | \/ (_)___ ___ ___| | | __ _ _ __ ___ ___ _ _ ___
| | |\/| | / __|/ __/ _ \ | |/ _` | '_ \ / _ \/ _ \| | | / __|
| | | | | \__ \ (_| __/ | | (_| | | | | __/ (_) | |_| \__ \
| |_| |_|_|___/\___\___|_|_|\__,_|_| |_|\___|\___/ \__,_|___/
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
Intersection(
aabb const & aabb0_in,
aabb const & aabb1_in,
aabb & aabb_out,
real /*tolerance*/
)
{
if (!(aabb0_in.intersects(aabb1_in)))
return false;
for (integer i = 0; i < 3; ++i)
{
if (aabb0_in.max(i) <= aabb1_in.max(i))
{aabb_out.max(i) = aabb0_in.max(i);}
else
{aabb_out.max(i) = aabb1_in.max(i);}
if (aabb0_in.min(i) <= aabb1_in.min(i))
{aabb_out.min(i) = aabb1_in.min(i);}
else
{aabb_out.min(i) = aabb0_in.min(i);}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} // namespace acme
#endif