Fastest code of 2D line intersected with rectangle

Started by
15 comments, last by Emil_Halim 16 years, 9 months ago
Nice oliii , really cool .

Could you please explain the arguments in more detail , I.e what is the s , e , min ,max ......

By the way you are welcome before breakfast , before lunch ,and also before dinner. :)
Advertisement
Quote:Original post by Emil_Halim
Could you please explain the arguments in more detail , I.e what is the s , e , min ,max ......
AxisIntersect() is a support function, so you don't really need to worry about it (apart from understanding how the algorithm works, that is). As for the intersection function:
bool intersectSegmentRectangle(const Vector& start, const Vector& end, const Vector& min, const Vector& max, float &t);start : start point of line segmentend   : end point of line segmentmin   : 'min' corner of AABBmax   : 'max' corner of AABBt     : if an intersection is detected, the parametric value corresponding        to the first point of intersection will be written to this variableThe function returns 'true' if an intersection was detected, and 'false' otherwise.

ok now I understand it well , thanks.

by the way , the min point of AABB means that minmum x and minmum y of the 2 points and also the same for maxmum x,y.
I recommend creating a class to represent an intersection operation, this way relevant information can be stored in a sensible way and not passed around with in/out args or return values that aren't the entirety of what a function computes.

This also (imho) reminds the programmer that these operations are not cheap.

so, without further ado:

// a useful tooltemplate<typename T> void EnforceOrder(T & a, T & b){    if(a > b) swap(a,b);}struct line{    vec2 pt; // a point on the line    vec2 dir; // the direction of the line (this vector is parallel to the line)};struct AABB{    vec2 bl; // bottom left point    vec2 tr; // top right point};class IntersectLineAABB{public:    bool isect; // true if there is an intersection    // the solutions (NOT coordinates) for the intersections    // these values are the offsets along the line of the intersections    float sol_low;     float sol_high;    // remember the line so we can access it    const line & L;    IntersectLineAABB(const line & LINE, const AABB & box):L(LINE){        isect = false;        // degenerate cases        // warning: we ASSUME that L.dir is not (0,0)        if(L.dir.x == 0.0){            if(L.pt.x < box.bl.x || L.pt.x > box.tr.x) return;            else{                isect = true;                sol_low= (box.bl.y - L.pt.y)/L.dir.y;                sol_high = (box.tr.y - L.pt.y)/L.dir.y;                EnforceOrder(sol_low, sol_high);                return;            }        }        if(L.dir.y == 0.0){            if(L.pt.y < box.bl.y || L.pt.y > box.tr.y) return;            else{                isect = true;                sol_low = (box.bl.x - L.pt.x)/L.dir.x;                sol_high = (box.tr.x - L.pt.x)/L.dir.x;                EnforceOrder(sol_low, sol_high);                return;            }        }          float xlow, xhigh; // solution values in x        float ylow, yhigh; // solution values in y        // no trivial exclusion, solve normally        xlow = (box.bl.x - L.pt.x)/L.dir.x;        xhigh = (box.tr.x - L.pt.x)/L.dir.x;        ylow = (box.bl.y - L.pt.y)/L.dir.y;        yhigh = (box.tr.y - L.pt.y)/L.dir.y;        EnforceOrder(xlow, xhigh);        EnforceOrder(ylow, yhigh);        // if the solutions overlap then an intersection exists        if(xlow > ylow && xlow < yhigh){            sol_low = xlow;            sol_high = min(xhigh, yhigh);            isect = true;        }else if(ylow > xlow && ylow < xhigh){            sol_low = ylow;            sol_high = min(xhigh, yhigh);            isect = true;        }    }    // returns true if there is an intersection    inline bool valid(){return isect;}    // returns the location of the low-valued intersection    inline vec2 lowpt(){return L.pt + (L.dir * sol_low);    // returns the location of the high-valued intersection    inline vec2 highpt(){return L.pt + (L.dir * sol_high);    // returns the solution vector    inline vec2 solution(){return vec2(sol_low, sol_high);};    


note that if you're intersecting with a segment (line connecting two points) or a ray (an infinite line in ONE direction from a point, this code is still good for you, just remember the solution values are constrained ([0,1] for a segment, and >=0 for a ray).

Also, for the code-conscious, this code is not verbatim what I have in my libs (though it is functionally equivalent), so don't bother commenting on style or whatever.

final note; to do NON axis aligned bounding boxes, I like the clipping planes solution, do that.
Geordi
George D. Filiotis

Thanks George for your code I will study it .
BTW, what's cool with that ray-segment intersect method is that you can extend it easily to do much more interesting things. Namely, moving convex polygon-polygon collision (boxes, oriented boxes, triangles, convex polygons, ...).

a discussion about this.

http://www.gamedev.net/community/forums/topic.asp?topic_id=346956

And further extend it to get the points and normal of collisions. And then ultimately the points of contact.

Everything is better with Metal.

Quote:Original post by oliii

a discussion about this.

http://www.gamedev.net/community/forums/topic.asp?topic_id=346956



Oliii , your link is very helpful , and i think that topic must be sticky , it will help a lot for many ppl.

This topic is closed to new replies.

Advertisement