Help end child hunger

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”

  1. 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;

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: