IntersectionResult::Value OrientedBoundingBox::frustumIntersect(Frustum const& frustum) const { bool intersecting = false; for (int i = 0; i < 6; i++) { IntersectionResult::Value result = planeIntersect(frustum.getPlane(i)); if (result == IntersectionResult::OUTSIDE) { return IntersectionResult::OUTSIDE; } else if (result == IntersectionResult::INTERSECTING) { intersecting = true; } } if (intersecting) { return IntersectionResult::INTERSECTING; } return IntersectionResult::INSIDE; }
/* CXXCircle::CXXCircle (const CXXCircle &oldOne) : theAtomJ(oldOne.getAtomJ()), theBallJ(oldOne.getBallJ()), theParent(oldOne.getParent()), centreOfSecondSphere(oldOne.getCentreOfSecondSphere()), theNormal(oldOne.getNormal()), radiusOfSecondSphere(oldOne.getRadiusOfSecondSphere()), radiusOfSphere(oldOne.getRadiusOfSphere()), centreOfCircle(oldOne.centreOfCircle), centreToCircle(oldOne.getCentreToCircle()), referenceUnitRadius(oldOne.getReferenceUnitRadius()), radiusOfCircle(oldOne.getRadiusOfCircle()), theNodes(oldOne.getNodes()), nIntersectingCircles(oldOne.getNIntersectingCircles()), completelyEaten(oldOne.getEaten()) { for (unsigned i=0; i<oldOne.getNNodes(); i++){ theNodes[i].setParent(this); } theStarts.resize(oldOne.nSegments()); theStops.resize(oldOne.nSegments()); for (unsigned i=0; i<oldOne.nSegments(); i++){ theStarts[i] = oldOne.start(i); theStops[i] = oldOne.stop(i); } } */ int CXXCircle::meetsCircle(const CXXCircle &otherCircle, vector<CXXCoord, CXX::CXXAlloc<CXXCoord> > &nodeList) const{ // check if there is an intersection between this circle and another circle // return 0 if there is intersection // 2 if the this circle is entirely swallowedd by the atom that generates the otherCircle, // 1 if the converse of the above applies // and 3 otherwise CXXCoord intersectA, intersectB; // some simplifications: rj - centreToCircle of current (this) arc circle // rk - centreToCircle of newArc circle CXXCoord rj(getCentreToCircle()); CXXCoord rk(otherCircle.getCentreToCircle()); CXXCoord rjxrk; // following Totrovs vector match - plane intersection of the two circles. // PlaneIntersectioon points at intersection of two this- and new- circlePlanes // with plane spanned by the centre of the two VDW spheres and the centre of thisArc // some dummy variables double rjrk, rjSquared, rkSquared; double a, b, distSq, radiusOfSphereSq, x; rjSquared = rj*rj; rkSquared = rk*rk; rjrk = rj*rk; a = ((rjSquared - rjrk)*rkSquared)/(rjSquared*rkSquared - rjrk*rjrk); b = ((rkSquared - rjrk)*rjSquared)/(rjSquared*rkSquared - rjrk*rjrk); // with this now: CXXCoord planeIntersect((rj*a) + (rk*b)); // if the distance between the intersection point of the three planes is closer then //the radius of the VDW + probe sphere, then the two circle of this arc and new arc intersect.... // distance of intersectino point distSq = planeIntersect*planeIntersect; radiusOfSphereSq = radiusOfSphere*radiusOfSphere; // distance of (VDW + probe) sphere of thisAtom = radiusOfSphere therefore: if (distSq < radiusOfSphereSq) { // the CIRCLES corresponding to the new and the current (old) arc cross each other // the crossingpoints of the two CIRCLES are the points where the line defined by the // intersection of the two arcplanes cuts throught the new circle // the intersection line is perpendicular the plane spanned by rj and rk - that is parallel to: rjxrk = rj ^ rk; rjxrk.normalise(); //the intersection line is defined by this vector and one of its point - the planeIntersection vector: // => line planeIntersect + x*(rjxrk), x some real number // intersection points have x=+-0.5*length of the secante of circle therefore: x = sqrt(radiusOfSphereSq - distSq); rjxrk.scale(x); //We need to see whether the centreToCircle vectors of these circles indicate that the //corresponding torus is "behind" the centre of the first circle, or in front. This determines //Whether the first or the second calculated intersection point represents a point to start drawing. //It boils down to a sort of parity thing. Think about it ! CXXCoord unitCentreToCircle(centreToCircle); unitCentreToCircle.normalise(); int forwardOne = (theNormal*unitCentreToCircle > 0.?1:-1); CXXCoord otherCircleUnitCentreToCircle(otherCircle.getCentreToCircle()); otherCircleUnitCentreToCircle.normalise(); int forwardTwo = (otherCircle.getNormal()*otherCircleUnitCentreToCircle > 0.?1:-1); if (forwardOne*forwardTwo > 0){ intersectA = planeIntersect+rjxrk; intersectB = planeIntersect-rjxrk; } else { intersectB = planeIntersect+rjxrk; intersectA = planeIntersect-rjxrk; } nodeList[0] = intersectA + getCentreOfSphere(); nodeList[1] = intersectB + getCentreOfSphere(); return 0; } else { //We get here if the two circles don't intersect //Now check whether this circle falls somewhere inside the //sphere indicated by the other circle. If it does, then //(given it doesn't intersect), it must *always* be inside // otherwise it must *always* be outside if (otherCircle.accIsBehind(getCentreOfCircle()) == 0) return 2; if(accIsBehind(otherCircle.getCentreOfCircle()) == 0) return 1; return 3; } }
DistNorm ShapeCube::implicitIntersect(glm::vec4 pos, glm::vec4 direction, glm::mat4 shapeTransform, glm::vec2 *storeUV){ glm::mat4 inverse = glm::inverse(shapeTransform); //to transform world coordinates into shape coordinates glm::vec4 shape_pos = inverse * pos; glm::vec4 shape_dir = inverse * direction; DistNorm gives; gives.dist = -1; glm::vec4 faces[] = {glm::vec4(.5, 0, 0, 1), glm::vec4(-.5, 0, 0, 1), glm::vec4(0, .5, 0, 1), glm::vec4(0, -.5, 0, 1), glm::vec4(0, 0, .5, 1), glm::vec4(0, 0, -.5, 1)}; for (int i = 0; i < 6; i++){ glm::vec4 facePt = faces[i]; glm::vec4 fNorm = glm::normalize(glm::vec4(glm::vec3(facePt), 0)); float planehit = planeIntersect(shape_pos, shape_dir, facePt, fNorm); glm::vec4 intersect = shape_pos + shape_dir*planehit; if ((std::abs(intersect.x) - .5 < .001) && //idea: if the point is less than .5 from origin in each dimension, good; (std::abs(intersect.y) - .5 < .001) && //coordinate corresponding to face will always be .5 so don't worry (std::abs(intersect.z) - .5 < .001)){ //so, get magnitude, subtract .5, check < epsilon //ex: .25, .5, -.4 -> -.25, 0, -.1 all < epsilon if ((gives.dist > planehit && planehit >= 0) || gives.dist < 0){ gives.dist = planehit; gives.norm = fNorm; if (storeUV){ //not null float u, v; switch (i){ case 0: u = -intersect.z; v = intersect.y; break; case 1: u = intersect.z; v = intersect.y; break; case 2: u = intersect.x; v = -intersect.z; break; case 3: u = intersect.x; v = intersect.z; break; case 4: u = intersect.x; v = intersect.y; break; case 5: u = -intersect.x; v = intersect.y; break; } *storeUV = glm::vec2(u + .5f, v+.5f); } } } } if (gives.dist >= 0){ gives.norm = glm::vec4(glm::normalize(glm::transpose(glm::inverse(glm::mat3(shapeTransform)))*glm::vec3(gives.norm)), 0); //put into world coords return gives; }else{ return DistNorm{-1.f, glm::vec4(0, 0, 0, 0)}; //no intersect in front found } }