title: Separating axis theorem falsely triggers
body: <p>I'm writing some code in C++ for testing collisions using the separating axis theorem and in certain orientations it wrongly triggers that there is a collision occurring</p>
  
  <p>I'm following <a href="http://www.dyn4j.org/2010/01/sat/" rel="nofollow noreferrer">this</a> tutorial, however the tutorial is only in 2D and i'm trying to implement it in 3D although i think it should still be the same.</p>
  
  <p>The algorithm that i have now doesn't miss any collisions but for some orientations of the two boxes it thinks that that are colliding when they're infact not. An example can be seen here, these two boxes are apparently colliding according to the code below.</p>
  
  <p><a href="https://i.stack.imgur.com/bHMck.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bHMck.png" alt="False collision"></a></p>
  
  <p>The code is written in C++</p>
  
  <p>BoxCollider.h</p>
  
  <pre><code>class BoxCollider :
      public Collider
  {
  public:
      BoxCollider(Vector3 position, Vector3 rotation, Vector3 size);
  
  
      ~BoxCollider();
  
      void Update();
  
  public:
      Vector3 rotation;
      Vector3 size;
      Matrix transformMatrix;
  
      std::vector&lt;Vector3&gt; points;
  
      Vector3 normals[3];
  };
  </code></pre>
  
  <p>BoxCollider.cpp</p>
  
  <pre><code>BoxCollider::BoxCollider(Vector3 position, Vector3 rotation, Vector3 size) : rotation(rotation), size(size)
  {
      this-&gt;position = position;
      points.resize(8);
  
  }
  
  BoxCollider::~BoxCollider()
  {
  }
  
  void BoxCollider::Update()
  {
      Transform* eTransform = m_entity-&gt;GetComponent&lt;Transform&gt;();
      transformMatrix.RotateYawPitchRoll(rotation + eTransform-&gt;rotation);
      Vector3 ePos = eTransform-&gt;position;
  
      points[0] = transformMatrix * (Vector3( 0.5, -0.5, -0.5) * size) + position + ePos;
      points[1] = transformMatrix * (Vector3( 0.5,  0.5, -0.5) * size) + position + ePos;
      points[2] = transformMatrix * (Vector3( 0.5, -0.5,  0.5) * size) + position + ePos;
      points[3] = transformMatrix * (Vector3( 0.5,  0.5,  0.5) * size) + position + ePos;
      points[4] = transformMatrix * (Vector3(-0.5, -0.5, -0.5) * size) + position + ePos;
      points[5] = transformMatrix * (Vector3(-0.5,  0.5, -0.5) * size) + position + ePos;
      points[6] = transformMatrix * (Vector3(-0.5, -0.5,  0.5) * size) + position + ePos;
      points[7] = transformMatrix * (Vector3(-0.5,  0.5,  0.5) * size) + position + ePos;
  
      normals[0] = transformMatrix * Vector3(1, 0, 0);
      normals[1] = transformMatrix * Vector3(0, 1, 0);
      normals[2] = transformMatrix * Vector3(0, 0, 1);
  }
  </code></pre>
  
  <p>The algorithm:</p>
  
  <pre><code>void EntityManager::CheckCollision(BoxCollider * col0, BoxCollider * col1)
  {
      for (int i = 0; i &lt; 3; i++) //First cube
      {
          Vector3 axis = col0-&gt;normals[i];
          axis = Vector3(axis.z, -axis.x, axis.y);
  
  
          Projection proj1 = GetProjection(col0-&gt;points, axis);
          Projection proj2 = GetProjection(col1-&gt;points, axis);
  
          float overlap = GetOverlap(proj1, proj2);
  
          if (overlap &gt; 0.0) //The projections do not overlap
              return;
      }
  
      for (int i = 0; i &lt; 3; i++) //First cube
      {
          Vector3 axis = col1-&gt;normals[i];
          axis = Vector3(axis.z, -axis.x, axis.y);
  
          Projection proj1 = GetProjection(col0-&gt;points, axis);
          Projection proj2 = GetProjection(col1-&gt;points, axis);
  
          float overlap = GetOverlap(proj1, proj2);
  
          if (overlap &gt; 0.0) //The projections do not overlap
              return;
      }
  }
  
  float GetOverlap(Projection proj1, Projection proj2)
  {
      float a = proj2.left - proj1.right;
      float b = proj1.left - proj2.right;
  
      return a &gt; b ? a : b;
  }
  
  Projection GetProjection(std::vector&lt;Vector3&gt; points, Vector3 axis)
  {
      float tmp = 0;
      float left = D3D10_FLOAT32_MAX, right = -D3D10_FLOAT32_MAX;
  
      for (int i = 0; i &lt; points.size(); i++)
      {
          tmp = DotProduct(points[i], axis.Normalize());
          if (tmp &lt; left)
          {
              left = tmp;
          }
  
          if (tmp &gt; right)
          {
              right = tmp;
          }
      }
  
      return Projection(left, right, axis);
  }
  </code></pre>