code: public Optional<Times> intersectionTimes(VesselPosition vp) {
  
          // TODO handle vp doesn't have speed or cog but is within collision
          // distance given any cog and max speed
  
          Optional<VesselPosition> p = vp.predict(time);
          if (!p.isPresent()) {
              return Optional.absent();
          }
          Vector deltaV = velocity().get().minus(p.get().velocity().get());
          Vector deltaP = position(this).minus(p.get().position(this));
  
          // imagine a ring around the vessel centroid with maxDimensionMetres/2
          // radius. This is the ring we are going to test for collision.
          double r = p.get().maxDimensionMetres().or(maxDimensionMetresWhenUnknown) / 2
                  + maxDimensionMetres().or(maxDimensionMetresWhenUnknown) / 2;
  
          if (deltaP.dot(deltaP) <= r)
              return of(new Times(p.get().time()));
  
          double a = deltaV.dot(deltaV);
          double b = 2 * deltaV.dot(deltaP);
          double c = deltaP.dot(deltaP) - r * r;
  
          // Now solve the quadratic equation with coefficients a,b,c
          double discriminant = b * b - 4 * a * c;
  
          if (a == 0)
              return Optional.absent();
          else if (discriminant < 0)
              return Optional.absent();
          else {
              if (discriminant == 0) {
                  return of(new Times(Math.round(-b / 2 / a)));
              } else {
                  long alpha1 = Math.round((-b + Math.sqrt(discriminant)) / 2 / a);
                  long alpha2 = Math.round((-b - Math.sqrt(discriminant)) / 2 / a);
                  return of(new Times(alpha1, alpha2));
              }
          }
      }
docs: Returns absent if no intersection occurs else return the one or two times
  of intersection of circles around the vessel relative to this.time().
  
  @param vp
  @return