Say you stored the window rectangle as bottom,left,top,right in variable and window_rect, and the segment rectangle in bottom,left,top,right in segment_rect. Then this test checks if the rectangles intersect (assuming y axis points upwards rather than down). I'm also assuming a convention where rectangles contain the bottom and left boundary but not the right or top boundary.
Code:
rects_intersect =
segment_rect.right > window_rect.left &&
segment_rect.left < window_rect.right &&
segment_rect.top > window_rect.bottom &&
segment_rect.bottom < window_rect.top
I'd be inclined to do this before any other tests since if it shows there is no possibility of intersection you don't need to do anything else at all and a good compiler will optimise this test well.
Now maybe we can do the test for the centre of the window being near enough the segment since if that fails we know that there is no intersection with the actual segment. However, I suspect this test won't exclude many segments from further consideration, and it might not be very worthwhile.
In fact if you do it it might be best to do it first.
Next I'd check if either end point was in the rectangle like this:
Code:
contains_end_point =
window_rect.left <= end_point[0].x &&
window_rect.right > end_point[0].x &&
window_rect.bottom <= end_point[0].y &&
window_rect.top > end_point[0].y
and a similar test for the other end point if the first one is not inside the window.
Now we have decided whether the segment intersects the window except in the case where the rectangles overlap and both end points are outside the window. In this case either the segment rectangle contains parts of two opposite sides in which case there is again an intersection, or it contains a corner, in which case we are not sure.
the test
Code:
segment_must_intersect =
segment_rect.left < window_rect.left &&
segment_rect.right > window_rect.right ||
segment_rect.bottom < window_rect.bottom &&
segment_rect.top > window_rect.top
deals with the first of the two cases. If this is true the segment intersects the window.
Now if we are still in doubt the line is either wholly outside the window rectangle (but perhaps quite close if we did the centre distance test) or cuts through two adjacent sides, so that at one corner of the window is on the opposite side of the line to the others.
So finally we do this test, assuming line is ax+by+c=0
Code:
side = a*window_rect.left + b*window_rect.bottom + c
if (side < 0)
intersect =
a*window_rect.right + b*window_rect.bottom +c >= 0 ||
a*window_rect.right + b*window_rect.top +c >= 0 ||
a*window_rect.left + b*window_rect.top +c >= 0
else
intersect =
a*window_rect.right + b*window_rect.bottom +c <= 0 ||
a*window_rect.right + b*window_rect.top +c <= 0 ||
a*window_rect.left + b*window_rect.top +c <= 0 With these tests we hope most of the time only to do a few comparisons. Even if we have to do the final set of tests we can hope to be lucky and find that we only have to calculate the distance of only two or three of the window corners from the line.
I can't guarantee this will be faster than what you are doing, but it might be worth trying.