* @param absolute Global positions of seen flags
* @param seen Perceived positions of seen flags
*/
private void calculateRotation(List<Vector3D> absolute, List<Vector3D> seen){
int[] order = orderToFormAxes(absolute);
Vector3D y1 = seen.get(order[0]);
Vector3D y2 = seen.get(order[1]);
Vector3D y2MinusY1 = y2.subtract(y1);
Vector3D yAxis = y2MinusY1.negate().toUnitVector();
Vector3D z1 = seen.get(order[2]);
//this.agent is how we get closest point on a line [Y1, Y2] to a point Z_known
//
// (Y_2 - Y_1) x (Z_known - Y_1) x (Y_2 - Y_1)
// Z_needed = Z_known - --------------------------------------------------
// (Y_2 - Y_1) . (Y_2 - Y_1)
Vector3D z2 = z1.subtract(y2MinusY1.crossProduct(z1.subtract(y1)).crossProduct(y2MinusY1).divide(y2MinusY1.dotProduct(y2MinusY1)));
Vector3D zAxis = z1.subtract(z2).toUnitVector();
if (absolute.get(order[2]).getZ() == 0.0)
zAxis = zAxis.negate();
Vector3D xAxis = yAxis.crossProduct(zAxis).toUnitVector();
double rotationX = asin(-xAxis.getZ());
double rotationZ = atan2( -xAxis.rotateOverX(rotationX).getY() / cos(rotationX), xAxis.rotateOverX(rotationX).getX() / cos(rotationX));
double rotationY = atan2( -yAxis.rotateOverX(rotationX).getZ() / cos(rotationX), zAxis.rotateOverX(rotationX).getZ() / cos(rotationX));
this.agent.rotationX = Angles.normalize(rotationX);
this.agent.rotationY = Angles.normalize(rotationY);
this.agent.rotationZ = Angles.normalize(rotationZ);