Radar Approach – Implementation II
Prev: Testing Spheres | Next: Source Code |
This section presents an implementation for sphere testing against the view frustum under the radar approach. The class definition is presented in here again, now with the new data required to test spheres. The differences from the previous implementation are properly commented.
The class header file
class FrustumR{ public: static enum {OUTSIDE, INTERSECT, INSIDE}; Vec3 cc; // camera position Vec3 X,Y,Z;// the camera referential float nearD, farD, width, height; // NEW: these are the variables required to test spheres float sphereFactorX, sphereFactorY; FrustumR::FrustumR(); FrustumR::~FrustumR(); void setCamInternals(float angle, float ratio, float nearD, float farD); void setCamDef(Vec3 &p, Vec3 &l, Vec3 &u); int pointInFrustum(Vec3 &p); // NEW: function to test spheres int sphereInFrustum(Vec3 ¢er, float radius); };
The Methods: setCamInternals
This function is similar to the one presented before, adding only the computation of sphere factors.
#define HALF_ANG2RAD 3.14159265358979323846/360.0 void FrustumR::setCamInternals(float angle, float ratio, float nearD, float farD) { // half of the the horizontal field of view float angleX; // store the information this->ratio = ratio; this->nearD = nearD; this->farD = farD; angle *= HALF_ANG2RAD; // compute width and height of the near and far plane sections tang = tan(angle); sphereFactorY = 1.0/cos(angle); // compute half of the the horizontal field of view and sphereFactorX float anglex = atan(tang*ratio); sphereFactorX = 1.0/cos(anglex); }
The Methods: sphereInFrustum
This function takes the center of the sphere and its radius and tests the sphere against the view frustum.
int FrustumR::sphereInFrustum(Vec3 &p, float radius) { float d; float az,ax,ay; int result = INSIDE; Vec3 v = p-camPos; az = v.innerProduct(-Z); if (az > farD + radius || az < nearD-radius) return(OUTSIDE); if (az > farD - radius || az < nearD+radius) result = INTERSECT; ay = v.innerProduct(Y); d = sphereFactorY * radius; az *= tang; if (ay > az+d || ay < -az-d) return(OUTSIDE); if (ay > az-d || ay < -az+d) result = INTERSECT; ax = v.innerProduct(X); az *= ratio; d = sphereFactorX * radius; if (ax > az+d || ax < -az-d) return(OUTSIDE); if (ax > az-d || ax < -az+d) result = INTERSECT; return(result);
Prev: Testing Spheres | Next: Source Code |
4 Responses to “Radar Approach – Implementation II”
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
On this page the correct ANG2RAD constant is correct but you forget to divide angle (a.k.a. fovy) by two.
In the source code (frustumR.cpp) you use the wrong ANG2RAD constant which counters the lack of division by two.
Yes, you’re right. Silly bug… Thanks, I’ve updated the page.
Maybe I wasn’t clear (i.e. it is still wrong here and in the source code):
This is what it should be:
#define ANG2RAD 3.14159265358979323846/180.0
and in FrustumR::setCamInternals:
angle *= ANG2RAD / 2.0;
Oooops,
I forgot to divide by 2 in HALF_ANG2RAD 🙁
Thanks again.