MathVector tripleProduct(MathVector a, MathVector b, MathVector c) { MathVector U = b.multiply(c.dotProduct(a)); MathVector V = a.multiply(c.dotProduct(b)); return U.subtractVectors(V); }
minkowskiDifference_t buildMinkowskiDifference(std::vector<MathVector> a, std::vector<MathVector> b) { MathVector direction = MathVector(1,1); std::vector<MathVector> simplex; simplex.push_back(getSupportVertex(a, b, direction)); minkowskiDifference_t difference; direction = direction.negate(); while(true) { simplex.push_back(getSupportVertex(a, b, direction)); if(simplex.back().dotProduct(direction) <= 0) { difference.colliding = false; difference.collisionNormal = MathVector(0,0); difference.collisionDepth = 0; return difference; } else if(containsOrigin(simplex, direction) && simplex.size() == 3) { while(true) { //Perform EPA to get collision normal and penetration distance Edge_t e = findClosestEdge(simplex); MathVector p = getSupportVertex(a, b, direction); double d = p.dotProduct(e.normal); // std::cout << d - e.distance << std::endl; // std::cout << "Simplex size: " << simplex.size() << std::endl; if(d - e.distance < TOLERANCE) { difference.collisionNormal = e.normal; difference.collisionDepth = d; difference.colliding = true; return difference; } else { // std::cout << "Closest edge not found in this iteration, adding point to simplex and continuing." << std::endl; simplex.insert((simplex.begin()+e.index),p); } } } } }
MathVector getFurthestPoint(MathVector direction, std::vector<MathVector> polygon) { double greatestDotProduct = -std::numeric_limits<double>::max(); double currentDotProduct; MathVector currentVertex; MathVector bestVertex; for(int i = 0; i < polygon.size(); i++) { currentVertex = polygon[i]; currentDotProduct = currentVertex.dotProduct(direction); if(currentDotProduct > greatestDotProduct) { greatestDotProduct = currentDotProduct; bestVertex = currentVertex; } } return bestVertex; }
typename MathVector<T>::value_type operator*(const MathVector<T>& lhs, const MathVector<T>& rhs) { return lhs.dotProduct(rhs); }