rendered paste bodydouble ArzRectangle::intersect(ArzCircle* circle, Object* owner, Object* target) { Vector2D velocity = target->getVelocity() - owner->getVelocity(); Vector2D offset = target->getPosition() - owner->getPosition(); // TODO: Massively increase speed by checking that the objects are actually somewhere near each other before doing this expensive series of checks double min = 0.0; double max = 0.0; Vector2D corners[] = {tl, br}; int helper_x[] = {0,1,1,0,0}; int helper_y[] = {0,0,1,1,0}; int i_a = 0; int i_b = 1; while(i_a < 4) { Vector2D a = Vector2D(corners[helper_x[i_a]].x, corners[helper_y[i_a]].y); Vector2D b = Vector2D(corners[helper_x[i_b]].x, corners[helper_y[i_b]].y); double* r = circle->touchLine(offset, b, a, velocity); if(r != NULL) { if(r[0] < min) { min = r[0]; towards = circle->getCandidate(); } max = fmax(r[1], max); } i_a++; i_b++; } if(min < 0.0 && max > 0.0) { return min; } return 1.0;}double ArzCircle::intersect(ArzRectangle* rectangle, Object* owner, Object* target) { return rectangle->intersect(this, target, owner);}bool ArzCircle::pointInside(Vector2D point) { Vector2D dist = centre - point; return(dist.norm() > radius - 0.05);}double *ArzCircle::touchLine(Vector2D offset, Vector2D lineStart, Vector2D lineEnd, Vector2D velocity) { Vector2D effectiveCentre = centre + offset - lineStart; Vector2D effectiveEnd = lineEnd - lineStart; Vector2D lf = effectiveEnd.normalised(); Vector2D lfT = Vector2D(-lf.y, lf.x); Vector2D horizontalLine = Vector2D(effectiveEnd.norm(), 0); effectiveCentre = Vector2D(lf * effectiveCentre, lfT * effectiveCentre); Vector2D effectiveVelocity = Vector2D(lf * velocity, lfT * velocity); double a = effectiveVelocity.y * effectiveVelocity.y; double b = effectiveVelocity.y * effectiveCentre.y; double c = effectiveCentre.y * effectiveCentre.y - radius * radius; double *t = quadratic(a, b, c); if(t == NULL) { return NULL; } double *x = new double[2]; x[0] = effectiveCentre.x + t[0] * effectiveVelocity.x; // etc x[1] = effectiveCentre.x + t[1] * effectiveVelocity.x; double *to = new double[2]; candidate = lfT; double *tE0 = checkEndLineCase(horizontalLine, effectiveCentre, effectiveVelocity, x[0]); double *tE1 = checkEndLineCase(horizontalLine, effectiveCentre, effectiveVelocity, x[1]); if(tE0 != NULL) { if(tE0[0] != 0 || tE0[0] != 0) { to[0] = fmin(tE0[0], tE0[1]); if(tE0[2] == 0) { candidate = (lineStart - offset - centre).normalised(); } else { candidate = (lineEnd - offset - centre).normalised(); } to[1] = fmax(tE0[0], tE0[1]); } } else { to[0] = t[0]; to[1] = t[0]; } if(tE1 != NULL) { if(tE1[0] != 0 || tE1[1] != 0) { double temp = fmin(tE1[0], tE1[1]); if(temp < to[0]) { to[0] = temp; if(tE1[2] == 0) { candidate = (lineStart - offset - centre).normalised(); } else { candidate = (lineEnd - offset - centre).normalised(); } } to[1] = fmax(to[1], fmax(tE1[0], tE1[1])); } } else { to[0] = fmin(to[0], t[1]); to[1] = fmax(to[1], t[1]); } return to;}double* ArzCircle::checkEndLineCase(Vector2D hL, Vector2D eC, Vector2D eV, double x) { Vector2D point; double *t = new double[3]; if(x < 0) { point = Vector2D(0,0); t[2] = 0; // BIGGEST HACK EVER: 0 = start of line is closest, 1 otherwise } else if(x > hL.x) { point = hL; t[2] = 1; } else { return NULL; } /*if(x < -radius || x > hL.x + radius) { cout << "caught case" << endl; t[0] = 0; t[1] = 0; return t; }*/ double *temp = movePointOut(eC, point, eV); if(temp == NULL) { return NULL; } t[0] = temp[0]; t[1] = temp[1]; return t;}// velocity is point velocity I think?double* ArzCircle::movePointOut(Vector2D centre, Vector2D point, Vector2D velocity) { Vector2D alpha = point - centre; double a = velocity * velocity; double b = alpha * velocity; double c = alpha * alpha - radius * radius; double* t = quadratic(a, b, c); return t;}