# Sphere-Plane collision test [closed]

I'm worried about my own attempt at a solution for a Sphere-Plane collision testing. I originally implemented a solution I found on a mix of Game Development websites around the place, which was similar enough to the following:

bool intersecting(BoundingSphere const& s, Vector3 const& s_origin, BoundingPlane const& p, float const p_distance) {
Vector3 const p_origin = p.normal * p_distance;
Vector3 const cp = s_origin + p.normal * dot((p_origin - s_origin), p.normal);

}


But I have recently spent a bit more time doing linear algebra since and basic geometry, and decided upon revising the above solution (to see if I understood the problem space better).

In thinking about it as a simple check: distance of a point from a line being less than the radius. I came up with the following:

bool intersecting2(BoundingSphere const& s, Vector3 const& s_origin, BoundingPlane const& p, float const p_distance) {
return abs<float>(dot(p.normal, s_origin) - p_distance) < s.radius;
}


It has so far passed all my tests practically, but I still worry about my mathematical ability and I don't want an edge case to bite me in the ass that I might have missed. One thing I have definitely noticed is the solution is highly sensitive to the normalised form of the plane normal. If it is simply a rough estimation, ie not truly normalised, it will fail completely (exponential error).

The fact I never saw a solution that short worries me haha.

edit: My testbed: http://pastie.org/3512889

proposed tags: collision-detection && math

I'm not sure what kind of error your getting but here is a very simple collision test:

#include <cmath>
#include <iostream>

class float3 {
public:
float x,y,z;
};

class float4 {
public:
float a,b,c,d;
float norm() const{
return sqrt(a*a+b*b+c*c);
}
};

typedef float4 plane;

class sphere {
public:
float3 position;
};

float project( const float3 & spherePos, const plane & p){
return std::abs( spherePos.x*p.a + spherePos.y*p.b + spherePos.z*p.c + p.d );
}

bool const collision( const sphere & s, const plane & p){
}

int main( int argc, char * argv[]){

plane p = {0.0,-1.0,0.0, 2.0 };
sphere s = { {0.0,1.5,0.0}, 1.0 };

if ( collision(s,p) )
std::cout << "Collision detected" << std::endl;

}


The advantage here is that you don't need a normalized plane. The line that bothers me is this:

return abs<float>(dot(p.normal, s_origin) - p_distance) < s.radius;


Just write your solution such that it can handle un-normalized planes. If you're working with normalized planes (which may be what is contained in "p.normal"?) I believe you need :

return abs<float>(dot(p.normal, s_origin) + p_distance) < s.radius;


See the wolfram page on this topic - it is straight forward. It is not clear how you have implemented BoundingPlane - but if you are getting errors, that would be the first place to look.

• BoundingPlane is just a container for Vector3 normal, a normalised vector for the normal of the plane. Distance from the origin is a variable which is passed p_distance. I originally came up with what you have in the second statement, but it only gave the correct results when I did the - p_distance, which I don't understand. Commented Mar 4, 2012 at 0:58
• " but it only gave the correct results when I did the - p_distance " . I'm not sure what you 'expect' the results to be - I think your error lies in your interpretation of the representation of a plane. See mathworld.wolfram.com/Plane.html for more info about the formal definition of a plane. What you have is very close though! Commented Mar 4, 2012 at 2:21
• I'm pretty sure I have the right understanding. The normal of the plane is obvious enough (the vector perpendicular to the plane), and that is normalised. Then p_distance is the distance of that normal from the origin (0,0,0). Therefore a Plane with a normal of (0, 1, 0) would be flat, and a p_distance of 5 would put the plane at y = 5. Commented Mar 4, 2012 at 3:55
• traditionally, if you have a plane defined by ax + by + cz + d = 0, if you specified the normal to be (0,1,0) you would have the equation y = -d/b = -d, where in this case the intercept is y = - d. So if you set d=5, the y intercept is at -5 (y = - d, y = -5 ). Make sure you are being consistent with the math - I don't believe what you have done is what you expected you did - thus the errors. Simple things like this that 'work' in one case will cause huge headaches down the road one you attempt more complicated operations Commented Mar 4, 2012 at 6:15
• Its taken me this long (24 days?), just reading a paragraph on building planes made me realise you were right. I had a fundamental problem with my understand of distance to the origin. I didn't realise distance could be negative OR positive, based on the normal of the plane. I thought it was simply absolute. Which makes perfect sense now. Hence. Thanks for your answer. Commented Mar 28, 2012 at 9:55