bool overlap(const polyhedron &a, const polyhedron &b, const double periodic[3], double dr) { const vector3d ab = periodic_diff(a.pos, b.pos, periodic); if (ab.normsquared() > sqr(a.R + b.R + 2*dr)) return false; // construct axes from a // project a and b to each axis for (int i=0; i<a.mypoly->nfaces; i++) { const vector3d axis = a.rot.rotate_vector(a.mypoly->faces[i]); double projection = axis.dot(a.rot.rotate_vector((a.mypoly->vertices[0])*(a.R+dr))); double mina = projection, maxa = projection; for (int j=1; j<a.mypoly->nvertices; j++) { projection = axis.dot(a.rot.rotate_vector(a.mypoly->vertices[j]*(a.R+dr))); if (projection < mina) mina = projection; else if (projection > maxa) maxa = projection; } projection = axis.dot(b.rot.rotate_vector(b.mypoly->vertices[0]*(b.R+dr)) + ab); double minb = projection, maxb = projection; for (int j=1; j<b.mypoly->nvertices; j++) { projection = axis.dot(b.rot.rotate_vector(b.mypoly->vertices[j]*(b.R+dr)) + ab); if (projection < minb) minb = projection; else if (projection > maxb) maxb = projection; } if (mina > maxb || minb > maxa) { return false; } } // construct axes from b // project a and b to each axis for (int i=0; i<b.mypoly->nfaces; i++) { const vector3d axis = b.rot.rotate_vector(b.mypoly->faces[i]); double projection = axis.dot(a.rot.rotate_vector(a.mypoly->vertices[0]*(a.R+dr))); double mina = projection, maxa = projection; for (int j=1; j<a.mypoly->nvertices; j++) { projection = axis.dot(a.rot.rotate_vector(a.mypoly->vertices[j]*(a.R+dr))); if (projection < mina) mina = projection; else if (projection > maxa) maxa = projection; } projection = axis.dot(b.rot.rotate_vector(b.mypoly->vertices[0]*(b.R+dr)) + ab); double minb = projection, maxb = projection; for (int j=1; j<b.mypoly->nvertices; j++) { projection = axis.dot(b.rot.rotate_vector(b.mypoly->vertices[j]*(b.R+dr)) + ab); if (projection < minb) minb = projection; else if (projection > maxb) maxb = projection; } if (mina > maxb || minb > maxa) { return false; } } return true; }
int overlaps_with_any(const polyhedron &a, const polyhedron *bs, const double periodic[3], bool count, double dr) { // construct axes from a and a's projection onto them vector3d *aaxes = new vector3d[a.mypoly->nfaces]; double amins[a.mypoly->nfaces], amaxes[a.mypoly->nfaces]; for (int i=0; i<a.mypoly->nfaces; i++) { aaxes[i] = a.rot.rotate_vector(a.mypoly->faces[i]); double projection = aaxes[i].dot(a.rot.rotate_vector(a.mypoly->vertices[0]*(a.R+dr))); amins[i] = projection, amaxes[i] = projection; for (int j=1; j< a.mypoly->nvertices; j++) { projection = aaxes[i].dot(a.rot.rotate_vector(a.mypoly->vertices[j]*(a.R+dr))); amins[i] = min(projection, amins[i]); amaxes[i] = max(projection, amaxes[i]); } } int num_overlaps = 0; for (int l=0; l<a.num_neighbors; l++) { const int k = a.neighbors[l]; const vector3d ab = periodic_diff(a.pos, bs[k].pos, periodic); if (ab.normsquared() < sqr(a.R + bs[k].R + 2*dr)) { bool overlap = true; // assume overlap until we prove otherwise or fail to. // check projection of b against a's axes for (int i=0; i<a.mypoly->nfaces; i++) { double projection = aaxes[i].dot (bs[k].rot.rotate_vector(bs[k].mypoly->vertices[0]*(bs[k].R+dr)) + ab); double bmin = projection, bmax = projection; for (int j=1; j<bs[k].mypoly->nvertices; j++) { projection = aaxes[i].dot (bs[k].rot.rotate_vector(bs[k].mypoly->vertices[j]*(bs[k].R+dr)) + ab); bmin = min(projection, bmin); bmax = max(projection, bmax); } if (amins[i] > bmax || bmin > amaxes[i]) { overlap = false; i = a.mypoly->nfaces; // no overlap, move on to next } } if (overlap) { // still need to check against b's axes for (int i=0; i<bs[k].mypoly->nfaces; i++) { const vector3d axis = bs[k].rot.rotate_vector(bs[k].mypoly->faces[i]); double projection = axis.dot(a.rot.rotate_vector(a.mypoly->vertices[0]*(a.R+dr))); double amin = projection, amax = projection; for (int j=1; j<a.mypoly->nvertices; j++) { projection = axis.dot(a.rot.rotate_vector(a.mypoly->vertices[j]*(a.R+dr))); amin = min(projection, amin); amax = max(projection, amax); } projection = axis.dot (bs[k].rot.rotate_vector(bs[k].mypoly->vertices[0]*(bs[k].R+dr)) + ab); double bmin = projection, bmax = projection; for (int j=1; j<bs[k].mypoly->nvertices; j++) { projection = axis.dot (bs[k].rot.rotate_vector(bs[k].mypoly->vertices[j]*(bs[k].R+dr)) + ab); bmin = min(projection, bmin); bmax = max(projection, bmax); } if (amin > bmax || bmin > amax) { overlap = false; i = bs[k].mypoly->nfaces; //no overlap, move on to next } } } if (overlap) { if(!count) { delete[] aaxes; return 1; } num_overlaps ++; } } } delete[] aaxes; return num_overlaps; }