public Vec get_displacement() {
   double min_signed_overlap = -get_overlap(axes[0]);
   double min_overlap = min_signed_overlap < 0 ? -min_signed_overlap : min_signed_overlap;
   Vec min_axis = axes[0];
   for (int i = 1; i < axes.length; i++) {
     double overlap = -get_overlap(axes[i]);
     double unsigned_overlap = overlap < 0 ? -overlap : overlap;
     if (unsigned_overlap < min_overlap) {
       min_overlap = unsigned_overlap;
       min_signed_overlap = overlap;
       min_axis = axes[i];
     }
   }
   return min_axis.mul(min_signed_overlap);
 }
 public void relax() {
   if (p1.inv_mass == 0 && p2.inv_mass == 0) return;
   Vec displacement = get_displacement();
   if (displacement.equals(new Vec(0, 0))) return;
   double prop1, prop2;
   if (p1.inv_mass == 0) {
     prop1 = 0;
     prop2 = 1;
   } else if (p2.inv_mass == 0) {
     prop1 = 1;
     prop2 = 0;
   } else {
     double imass_total = p1.inv_mass + p2.inv_mass;
     prop1 = p1.inv_mass / imass_total;
     prop2 = p2.inv_mass / imass_total;
   }
   p1.pos.iadd(displacement.mul(prop1));
   p2.pos.isub(displacement.mul(prop2));
 }