Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8622455
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T07:03:26+00:00 2026-06-12T07:03:26+00:00

I’m doing triangle to AABB intersection tests, and I’m taking this sample code from

  • 0

I’m doing triangle to AABB intersection tests, and I’m taking this sample code from Real-Time Collision Detection by Christer Ericson. What the author says in the book before he gives the example is different from the example so I’m not sure how to test the remaining axes.. a01-a22.

Test: Nine axes given by the cross products of combination of edges from both.

// Test axes a00..a22 ( category 3 )
// Test axis a00
originDistance0 = triangle.point0.z * triangle.point1.y 
        - triangle.point0.y * triangle.point1.z;
originDistance2 = triangle.point1.z *( triangle.point1.y - triangle.point0.y ) 
        - triangle.point1.z * ( triangle.point1.z - triangle.point0.z );
projectionRadius = extent1 * Math.abs( edge0.z ) + extent2 * Math.abs( edge0.y );
if ( Math.max( -Math.max( originDistance0, originDistance2 ), Math.min( originDistance0, originDistance2 ) ) > projectionRadius ) {
    return false; // Axis is a separating axis
}

// Repeat similar tests for remaining axes a01..a22

So this is the test for the first axes. According to the book, these are the axes:

a00
=
u0 × f0
=
(1, 0, 0) × f0
=
(0, -f0z, f0y)

a01
=
u0 × f1
=
(1, 0, 0) × f1
=
(0, -f1z, f1y)

a02
=
u0 × f2
=
(1, 0, 0) × f2
=
(0, -f2z, f2y)

a10
=
u1 × f0
=
(0, 1, 0) × f0
=
(f0z, 0, -f0x)

a11
=
u1 × f1
=
(0, 1, 0) × f1
=
(f1z, 0, -f1x)

a12
=
u1 × f2
=
(0, 1, 0) × f2
=
(f2z, 0, -f2x)

a20
=
u2 × f0
=
(0, 0, 1) × f0
=
(-f0y, f0x, 0)

a21
=
u2 × f1
=
(0, 0, 1) × f1
=
(-f1y, f1x, 0)

a22
=
u2 × f2
=
(0, 0, 1) × f2
=
(-f2y, f2x, 0)

============

p0
=
V0 · a00

p1
=
V1 · a00 = V1 = p0

p2
=
V2 · a00 = V2

LEGEND: u = center vector, f = triangle edge vector. p = distances from the origin to the projections of the triangle vertices onto normal. V = triangle point.

How would the subsequent axes tests be calculated? Maybe if someone could do one I could have a better idea of the rest, but with only one example, I’m stuck.. Thanks!

EDIT: I tried the following.. for a00-a22 with no luck, the test still passes.
First I added this code, and replace a00, and added a01-a22.

// Test axes a00..a22 ( category 3 )
Vector3d a00 = new Vector3d();
Vector3d a01 = new Vector3d();
Vector3d a02 = new Vector3d();
Vector3d a10 = new Vector3d();
Vector3d a11 = new Vector3d();
Vector3d a12 = new Vector3d();
Vector3d a20 = new Vector3d();
Vector3d a21 = new Vector3d();
Vector3d a22 = new Vector3d();
a00.cross( u0, edge0 );
a01.cross( u0, edge1 );
a02.cross( u0, edge2 );
a10.cross( u1, edge0 );
a11.cross( u1, edge1 );
a12.cross( u1, edge2 );
a20.cross( u2, edge0 );
a21.cross( u2, edge1 );
a22.cross( u2, edge2 );


// Test axes a00-a22
originDistance0 = triangle.point0.dot( a00 );
originDistance2 = triangle.point2.dot( a00 );
projectionRadius = extent1 * Math.abs( edge0.z ) + extent2 * Math.abs( edge0.y );
if ( Math.max( -Math.max( originDistance0, originDistance2 ), Math.min( originDistance0, originDistance2 ) ) > projectionRadius ) {
    return false; // Axis is a separating axis
}
...

EDIT 2: I also tried the following, which got me closer, but still did not get all intersections and got ones that shouldn’t have. https://gist.github.com/3558420

UPDATE: Still not able to get correct intersection results. Looked over Eli’s code, but it seems to be for 2d data and the terms are different so I’m not finding a connection between my code and his.

UPDATE 2: Additional attempts have been trying this code, which is like the defacto standard. I’m getting one intersection, when there should be 4 intersections, with 2 of those containing the points of the triangle, 3 containing the edges, and 1 just the plane.

The intersection that is caught has one point and two edges (plus plane). There is one other object that has the same characteristics, but different location, which does not get counted as intersecting. This is the data I’m working with, and the highlighted “voxel” is the one that gets returned as intersecting the triangle.

Intersection Data Image

Intersection result returned on following test categories:

Voxel1: None, passed all, returned with default “true”.
Voxel2: Category 2
Voxel3: Category 3
Voxel4: Category 3
Voxel5: Category 3

UPDATE 3: Another implementation, better results

Ok, so after reading William Bittle’s article at codezealot.org, I implemented the following:

public static boolean testTriangleAABB( Triangle triangle, BoundingBox boundingBox, double size ) {
    Vector3d[] triangleAxes = getAxes( triangle.getPoints() );
    Vector3d[] aabbVertices = getVertices( boundingBox, size );
    Vector3d[] aabbAxes = getAxes( aabbVertices );

    // loop over the triangleAxes
    for( int i = 0; i < triangleAxes.length; i++ ) {
      Vector3d axis = triangleAxes[ i ];
      // project both shapes onto the axis
      Projection p1 = project( triangle.getPoints(), axis );
      Projection p2 = project( aabbVertices, axis );
      // do the projections overlap?
      if ( !p1.overlap( p2 ) ) {
        // then we can guarantee that the shapes do not overlap
        return false;
      }
    }

    // loop over the aabbAxes
    for( int i = 0; i < aabbAxes.length; i++ ) {
      Vector3d axis = aabbAxes[ i ];
      axis.normalize();
      // project both shapes onto the axis
      Projection p1 = project( triangle.getPoints(), axis );
      Projection p2 = project( aabbVertices, axis );
      // do the projections overlap?
      if ( !p1.overlap( p2 ) ) {
        // then we can guarantee that the shapes do not overlap
        return false;
      }
    }
    // if we get here then we know that every axis had overlap on it
    // so we can guarantee an intersection
    return true;
}

The axes code:

public static Vector3d[] getAxes( Vector3d[] vertices ) {
    Vector3d[] axes = new Vector3d[ vertices.length ];
    // loop over the vertices
    for ( int i = 0; i < vertices.length; i++ ) {
        // get the current vertex
        Vector3d p1 = vertices[ i ];
        // get the next vertex
        Vector3d p2 = vertices[ i + 1 == vertices.length ? 0 : i + 1 ];
        // subtract the two to get the edge vector
        // edge vector can be skipped since we can get the normal by cross product.
        // get either perpendicular vector
        Vector3d normal = new Vector3d();
        normal.cross( p1, p2 );
        axes[ i ] = normal;
    }
    return axes;
}

And the overlap method from the projection class is as follows:

public boolean overlap( Projection projection ) {
    double test1;
    double test2;

    // and test if they are touching 
    test1 = min - projection.max;   // test min1 and max2 
    test2 = projection.min - max;   // test min2 and max1

    if( ( ( test1 > 0 ) || ( test2 > 0 ) ) ) {      // if they are greater than 0, there is a gap 
        return false;                               // just quit } 
    }
    return true;
}    

Now I’m using another dataset, to fully test the intersection, since I got some false positives from my last dataset.

Triangle 0: true
Triangle 1: true
Triangle 2: true <– should be false
Triangle 3: false
Triangle 4: false
Triangle 5: true

(true = intersecting..)

This is my dataset, which is labeled according to the results.

new aabb/triangle dataset

So my thought is that I’m not getting the right data because I’m testing the wrong axes/normals.. So I tried the following for the AABB and a slightly altered version for the triangles:

public static Vector3d[] getAABBAxes( Vector3d[] vertices ) {
    Vector3d[] axes = new Vector3d[ 6 ];
    // loop over the vertices
    for ( int i = 0; i < 6; i++ ) {
        // get the current vertex
        Vector3d p1 = vertices[ i ];
        // get the next vertex
        Vector3d p2 = vertices[ i + 1 == vertices.length ? 0 : i + 1 ];
        Vector3d p4 = vertices[ i + 3 == vertices.length ? 0 : i + 3 ];
        Vector3d edge1 = new Vector3d();
        Vector3d edge2 = new Vector3d();
        edge1.sub( p2, p1 );
        edge2.sub( p4, p1 );
        // subtract the two to get the edge vector
        // edge vector can be skipped since we can get the normal by cross product.
        // get either perpendicular vector
        Vector3d normal = new Vector3d();
        normal.cross( edge2, edge1 );
        normal.normalize();
        axes[ i ] = normal;
    }
    return axes;
}

I get this:

Triangle 0: true
Triangle 1: true
Triangle 2: false
Triangle 3: true <– should be false
Triangle 4: true <– should be false
Triangle 5: true

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T07:03:28+00:00Added an answer on June 12, 2026 at 7:03 am

    The reason that I was getting false positives for my tests was related to the triangle test.

    To test a triangle, which is a plane in 3D space, you have to test against 4 axes(aka normals).

    1. Surface Normal
      • The cross-product between two edges of the triangle.
    2. Edge Normal 1
      • The cross product between the surface normal and edge 1.
    3. Edge Normal 2
      • The cross product between the surface normal and edge 2.
    4. Edge Normal 3
      • The cross product between the surface normal and edge 3.

    So in the end, to get a proper (at least it is working correctly so far) collision test between a cube and a triangle, you have to perform 7 axes tests.

    Each test consists of checking the triangle and box vertices against the axis (normal). This can be broken down into a triangle and box test, and if one has a separating axis, then you don’t have to do the other.

    Note: This test will only give you true/false results. No other data is provided.

    public static boolean testTriangleAABB( Triangle triangle, 
            Vector3d origin, double size ) {
        setTriangleNormal( triangle.getNormal( true ) );
        Vector3d[] aabbVertices = calculateAABBVertices( origin, size );
    
        // Triangle Normal axis test, false = No Collision.
        if( !testTriangleNormal( triangle, aabbVertices ) ) {
            return false;
        }
    
        // Triangle Edge Normals axis test, false = No Collision.
        if( !testTriangleEdgeNormals( triangle, aabbVertices ) ) {
            return false;
        }
    
        // Axis-Aligned Bounding Box X, Y, Z axis test, false = No Collision.
        if( !testAABBAxis( triangle, aabbVertices ) ) {
            return false;
        }     
    
        // if we get here then we know that every axis had overlap on it
        // so we can guarantee an intersection
        return true;
    }
    
    ...
    
    private static boolean testTriangleEdgeNormals( Triangle triangle, Vector3d[] aabbVertices ) {
        Vector3d edge = new Vector3d();
        Vector3d edgeNormal = new Vector3d();
    
        // loop over the triangle edge normals
        Vector3d[] points = triangle.getPoints();
        for( int i = 0; i < points.length; i++ ) {
            int iOverflow = i + 1 == points.length ? 0 : i + 1;
            edge.sub( points[ i ], points[ iOverflow ] );
            edge.normalize();
            edgeNormal.cross( getTriangleNormal(), edge );
    
            // project both shapes onto the axis
            projectionAABB = project2D1D( aabbVertices, edgeNormal );
            projectionTriangle = project2D1D( triangle.getPoints(), edgeNormal );
            // do the projections overlap?
            if ( !projectionAABB.hasOverlap( projectionTriangle ) ) {
                // then we can guarantee that the shapes do not overlap
                return false;
            }
        }
        return true;
    }
    

    Furthermore, there is no need to calculate Axis-Aligned Bounding Box axes..since they are axis aligned the axes will be like so:

    private static final Vector3d[] AABB_AXES = { 
        new Vector3d( -1.0, 0.0, 0.0 ), 
        new Vector3d( 0.0, -1.0, 0.0 ),
        new Vector3d( 0.0, 0.0, -1.0 ) };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
Does anyone know how can I replace this 2 symbol below from the string
link Im having trouble converting the html entites into html characters, (&# 8217;) i
this is what i have right now Drawing an RSS feed into the php,
I am doing a simple coin flipping experiment for class that involves flipping a
This could be a duplicate question, but I have no idea what search terms

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.