简体   繁体   中英

C++ floating point comparison

Suppose you have have a rectangle, bottom-left point 0,0 and upper-right point is 100,100. Now two line intersects the rectangle. I have to find out the coordinate of the intersection point. I have done that. Now the problem is I can't tell whether it is inside the rectangle or not. I used double comparison. But I think it is giving me wrong answer. Suppose the intersection point is ( x , y ). I used this checking for comparison : if( x >= 0.0 && x <= 100.0 && y >= 0.0 && y <= 100.0 ). What should I do?

//this function generates line
line genline( int x1 , int y1 , int x2 , int y2 ){
    line l ;
    l.A = y2 - y1 ;
    l.B = x1 - x2 ;
    l.C = l.A * x1 + l.B * y1 ;
    return l ;
}
//this function checks intersection
bool intersect( line m ,line n ) {
    int det = m.A * n.B - m.B * n.A ;
    if( det == 0 ){
        return false ;
    }
    else {
        double x = ( n.B * m.C - m.B * n.C ) / ( det * 1.0 ) ;
        double y = ( m.A * n.C - n.A * m.C ) / ( det * 1.0 ) ;        
        if( x >= 0.0 && x <= L && y >= 0.0 && y <= W ) { return true ; }
        else{ return false ; }
    }
}

EDIT: Both the line are stretched to infinity.

Your math looks like it's right. By the way, If a line intersects something, it is always inside that something.

Checking to see if a point is inside a rectangle is relatively easy. However, the challenge is to find the intersection between two line segments. There are a large number of corner cases to that problem and limited accuracy of floating point numbers play a huge roll here.

Your algorithm seems to be overly simplistic. For a deeper discussion about this topic you can look at this and this . This two parts article investigates the problem of finding the intersection of two lines using floating point numbers. Notice that they are about MATLAB not C++ though that does not change the problem and the algorithms are easily translatable to any language.

Depending on application, even with clever tricks floating point representation might not simply cut it for some geometry problems. CGAL is a C++ library dedicated to computational geometry that deals with these kind problems. When necessary it uses arbitrary precision arithmetic to handle degenerate cases.

When you're dealing with floating point (or double), testing for equality is naïve and will fail in edge cases. Every comparison you make should be in reference to "epsilon", an extremely small quantity that doesn't matter. If two numbers are within epsilon for each other, then they are considered equal.

For example, instead of "if(a == b)", you need:

bool isEqual(double a, double b, double epsilon = 1.E-10)
{    return fabs(a - b) <= epsilon;
}

Pick a suitable value for epsilon depending on your problem domain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM