I've tried for some time to make the following code run properly. The problem is in the comparison function of sort(comp). It compares 2 doubles but in some cases it causes the program to crash with the message
"Debug Assertion failed!
Program: retrace.exe
File:c:program files (x86)\microsoft visual studio 10.0\vc\include\algorithm
Expression:Invalid operator<".
I'm 100% it's from the stl's sort because when the program crashes the last line that has been successfully executed is the one before sort. At first I thought that it is some precision problem with double but now I doubt it. Any help or info will be appreciated.
Vector startg;
bool comp(const std::pair<Vector, int>& p1, const std::pair<Vector, int>& p2)
{
return (p1.first-startg).lengthSqr() < (p2.first-startg).lengthSqr();
}
bool Blobs::intersect(const Ray& ray, IntersectionInfo& info) const
{
startg.set(ray.start.x, ray.start.y, ray.start.z);
std::vector<std::pair<Vector, int> > spheres_inters;
for(int i=0;i<n;i++)//intersections with bounding spheres
{
Vector H = ray.start - centres[i];
double A = ray.dir.lengthSqr();
double B = 2 * dot(H, ray.dir);
double C = H.lengthSqr() - bounding_radius*bounding_radius;
double D = B*B - 4*A*C;
if(D<=0)
continue;
double x1 = (-B + sqrt(D)) / (2*A);
double x2 = (-B - sqrt(D)) / (2*A);
Vector v1 = ray.start + x1*ray.dir;
Vector v2 = ray.start + x2*ray.dir;
spheres_inters.push_back(std::make_pair(v1, i));
spheres_inters.push_back(std::make_pair(v2, i));
}
if(spheres_inters.size()==0)
return false;
std::sort(spheres_inters.begin(), spheres_inters.end(), comp);//THE PROBLEM IS HERE!
//the rest is OK
std::list<int> active_spheres_indxx;
for(int i=0;i<spheres_inters.size()-1;i++)
{
std::list<int>::iterator j;
for(j = active_spheres_indxx.begin(); ; j++)
{
if(j==active_spheres_indxx.end())
{
active_spheres_indxx.push_back(spheres_inters[i].second);
break;
}
if((*j) == spheres_inters[i].second)
{
active_spheres_indxx.erase(j);
break;
}
}
float d3 = ray.dir.lengthSqr();
float d4 = (spheres_inters[0].first-spheres_inters[1].first).lengthSqr();
for(Vector c_step = spheres_inters[i].first; (c_step-spheres_inters[i+1].first).lengthSqr() >= 0.0001; c_step += (0.001*ray.dir))
{
float d5 = (c_step-spheres_inters[1].first).lengthSqr();
float accum = 0;
float r_sqr;
for(j = active_spheres_indxx.begin(); j!=active_spheres_indxx.end(); j++)
{
r_sqr = (c_step - centres[(*j)]).lengthSqr();
accum += r_sqr*r_sqr - r_sqr + 0.25f;
}
if(accum > threshold - 1e-9)
{
info.ip = c_step;
info.distance = (c_step - ray.start).length();
info.norm.set(0, 0, 0);
for(j = active_spheres_indxx.begin(); j!=active_spheres_indxx.end(); j++)
{
r_sqr = (c_step - centres[(*j)]).lengthSqr();
info.norm += ((r_sqr*r_sqr - r_sqr + 0.25f)/accum) * (c_step - centres[(*j)]);
}
info.norm.normalize();
return true;
}
}
}
return false;
}