OK, before I start I need to tell you something: I have no experience with linear algebra . I am pretty good at programming, and regular algebra, but I am totally clueless about the linear stuff.

I have several flat quads, at 90º angles. I need some balls to bounce off them

Here goes: My collision detection just don't work. It's as if it's not there. Let me show you a few code samples:

Definition of some types first:
- point3d holds a 3d point
- plane3d is not really a plane. It's got point 3d points[4] for holding a quad, float normal x, y, z for the plane normal, and float distance for the plane distance

My function used for calculating distances:

Code:
void calculate_plane(plane3d *theplane) {

	point3d *v1 = &theplane->points[0];
	point3d *v2 = &theplane->points[1];
	point3d *v3 = &theplane->points[2];
	
	theplane->distance = -(v1->x * (v2->y * v3->z - v3->y * v2->z) +
						   v2->x * (v3->y * v1->z - v1->y * v3->z) +
						   v3->x * (v1->y * v2->z - v2->y * v1->z)  );

}
Notice that the code above only calculates the distance of the plane; the plane normals and coordinates are hand-typed. (I probably could've used a loop, but I was too lazy.)

So far, so good, right?

Now I need a function to figure out which side of the plane a point is on:

Code:
int classify_point(plane3d *plane, point3d *dest_pt )
{
        float p = dot_product( &plane->normal, dest_pt ) + plane->distance;

        if( p > 0.0f ) return PLANE_FRONT;
        else
        if( p < 0.0f ) return PLANE_BACK;

        return PLANE_COINCIDE;
}
Where PLANE_FRONT, PLANE_BACK, and PLANE_COINCIDE are 99, 100, and 101, repectively. But the values don't really matter; as long as they're different.

Now, I know that the ball will always be inside the walls (the 4 walls enclose the ball), so that means that I can skip the process of finding where exactly the collision point on the plane is, right?

All that is left is to find which wall it hit, and then reverse the correct axis:
Code:
void ball_collision(ball *theball) {

	// note that we don't actually make sure that the collision point is on the quad; because this
	// is such a simple game, that's all the checking we need to do :)
	
	point3d &current_pos = theball->pos;	// grab the ball's current position
	point3d dest_pos;						// this will hold where the ball would go
	// from the current velocity, calculate where the ball would go (its destination)
	dest_pos.x = theball->pos.x + theball->vel.x;
	dest_pos.y = theball->pos.y + theball->vel.y;
	dest_pos.z = theball->pos.z + theball->vel.z;
	
	// run through each plane in tube
	for (int i=0; i<4; i++) {
		int dest_side = classify_point(&tube[i], &dest_pos);
		int current_side = classify_point(&tube[i], &current_pos);
		
		// check to see if the destintation point and the current point are on the same sides of the plane (quad)
		if (dest_side != current_side) {
			
			// find which wall it collided into
			if (i == 0 || i == 2) {
				// ball collided on the y axis, so reverse it
				theball->pos.y = -theball->pos.y;
				return;
			}
			else {
				// ball collided on the x axis
				theball->pos.x = -theball->pos.x;
				return;
			}
		}
		// keep going
	}
}
Where tube is really plane3d tube[4], and so notice that I check to see which wall of the tube it collided into before reversing the appropriate axis. (tube[0] and tube[2] are the bottom and top, respectively. And of course tube[1] and tube[3] are the left and back, respectively.)

Then I actually run the collision function here:
Code:
void ball_draw(ball *theball) {
	// make sure the ball didn't collide with anything
	ball_collision(theball);
	glTranslatef(theball->pos.x, theball->pos.y, theball->pos.z);
	glColor3f(0.5f, 0.5f, 0.5f);
	gluSphere(quadratic, ball_radius, ball_subdiv_x, ball_subdiv_y);
}
But whenever I run the program, the ball keeps going through the walls as if I was never calling the functions. I looked at what the variables are doing, and classify_point always returns PLANE_FRONT, even when the ball is going to fly into the wall.

Can anyone much smarter than me see where I went wrong?