void Voronoi::CheckCircle(VParabola * b){ VParabola * lp = VParabola::GetLeftParent (b); VParabola * rp = VParabola::GetRightParent(b); VParabola * a = VParabola::GetLeftChild (lp); VParabola * c = VParabola::GetRightChild(rp); if(!a || !c || a->site == c->site) return; Vec2d * s = 0; s = GetEdgeIntersection(lp->edge, rp->edge); if(s == 0) return; double dx = a->site->x - s->x; double dy = a->site->y - s->y; double d = std::sqrt( (dx * dx) + (dy * dy) ); if(s->y - d >= ly) { return;} Vec2d * newv = new Vec2d(); newv->set( s->x, s->y - d ); VEvent * e = new VEvent( newv, false); //VEvent * e = new VEvent( new Vec2d(s->x, s->y - d), false); points.push_back(e->point); b->cEvent = e; e->arch = b; queue.push(e); }
int IntrBox3Sphere3<Real>::FindJustEdgeIntersection (Real cy, Real ex, Real ey, Real ez, Real dx, Real dz, Real vx, Real vy, Real vz, Real& ix, Real& iy, Real& iz) { // Finds the intersection of a point dx and dz away from an edge with // direction y. The sphere is at a point cy, and the edge is at the // point ex. Checks the edge and the vertex the velocity is heading // towards. Real rsqr = mSphere->Radius*mSphere->Radius; Real dy, crossZ, crossX; // possible edge/vertex intersection int signY; // Depending on the sign of Vy, pick the vertex that the velocity is // heading towards on the edge, as well as creating crossX and crossZ // such that their sign will always be positive if the sphere center goes // over that edge. if (vy >= (Real)0) { signY = 1; dy = cy - ey; crossZ = dx*vy - dy*vx; crossX = dz*vy - dy*vz; } else { signY = -1; dy = cy + ey; crossZ = dy*vx - dx*vy; crossX = dy*vz - dz*vy; } // Check where on edge this intersection will occur. if (crossZ >= (Real)0 && crossX >= (Real)0 && crossX*crossX + crossZ*crossZ > vy*vy*mSphere->Radius*mSphere->Radius) { // Sphere potentially intersects with vertex. Vector3<Real> relVelocity(vx, vy, vz); Vector3<Real> D(dx, dy, dz); Vector3<Real> cross = D.Cross(relVelocity); if (cross.SquaredLength() > rsqr*relVelocity.SquaredLength()) { // Sphere overshoots the box on the vertex. return 0; } // Sphere actually does intersect the vertex. mContactTime = GetVertexIntersection(dx, dy, dz, vx, vy, vz, rsqr); ix = ex; iy = signY*ey; iz = ez; } else { // Sphere intersects with edge. Real vsqrX = vz*vz + vx*vx; mContactTime = GetEdgeIntersection(dx, dz, vx, vz, vsqrX, rsqr); ix = ex; iy = cy + mContactTime*vy; iz = ez; } return 1; }
int IntrBox3Sphere3<Real>::FindFaceRegionIntersection (Real ex, Real ey, Real ez, Real cx, Real cy, Real cz, Real vx, Real vy, Real vz, Real& ix, Real& iy, Real& iz, bool aboveFace) { // Returns when and whether a sphere in the region above face +Z // intersects face +Z or any of its vertices or edges. The input // aboveFace is true when the x and y coordinates are within the x and y // extents. The function will still work if they are not, but it needs // to be false then, to avoid some checks that assume that x and y are // within the extents. This function checks face z, and the vertex and // two edges that the velocity is headed towards on the face. // Check for already intersecting if above face. if (cz <= ez + mSphere->Radius && aboveFace) { mContactTime = (Real)0; return -1; } // Check for easy out (moving away on Z axis). if (vz >= (Real)0) { return 0; } Real rsqr = mSphere->Radius*mSphere->Radius; Real vsqrX = vz*vz + vx*vx; Real vsqrY = vz*vz + vy*vy; Real dx, dy, dz = cz - ez; Real crossX, crossY; int signX, signY; // This determines which way the box is heading and finds the values of // CrossX and CrossY which are positive if the sphere center will not // pass through the box. Then it is only necessary to check two edges, // the face and the vertex for intersection. if (vx >= (Real)0) { signX = 1; dx = cx - ex; crossX = vx*dz - vz*dx; } else { signX = -1; dx = cx + ex; crossX = vz*dx - vx*dz; } if (vy >= (Real)0) { signY = 1; dy = cy - ey; crossY = vy*dz - vz*dy; } else { signY = -1; dy = cy + ey; crossY = vz*dy - vy*dz; } // Does the circle intersect along the x edge? if (crossX > mSphere->Radius*vx*signX) { if (crossX*crossX > rsqr*vsqrX) { // Sphere overshoots box on the x-axis (either side). return 0; } // Does the circle hit the y edge? if (crossY > mSphere->Radius*vy*signY) { // Potential vertex intersection. if (crossY*crossY > rsqr*vsqrY) { // Sphere overshoots box on the y-axis (either side). return 0; } Vector3<Real> relVelocity(vx,vy,vz); Vector3<Real> D(dx,dy,dz); Vector3<Real> cross = D.Cross(relVelocity); if (cross.SquaredLength() > rsqr*relVelocity.SquaredLength()) { // Sphere overshoots the box on the corner. return 0; } mContactTime = GetVertexIntersection(dx, dy, dz, vx, vy, vz, rsqr); ix = ex*signX; iy = ey*signY; } else { // x-edge intersection mContactTime = GetEdgeIntersection(dx, dz, vx, vz, vsqrX, rsqr); ix = ex*signX; iy = cy + vy*mContactTime; } } else { // Does the circle hit the y edge? if (crossY > mSphere->Radius*vy*signY) { // Potential y-edge intersection. if (crossY*crossY > rsqr*vsqrY) { // Sphere overshoots box on the y-axis (either side). return 0; } mContactTime = GetEdgeIntersection(dy, dz, vy, vz, vsqrY, rsqr); ix = cx + vx*mContactTime; iy = ey*signY; } else { // Face intersection (easy). mContactTime = (-dz + mSphere->Radius)/vz; ix = mContactTime*vx + cx; iy = mContactTime*vy + cy; } } // z coordinate of any intersection must be the face of z. iz = ez; return 1; }