Re: sorting points or rectangles

new topic     » goto parent     » topic index » view thread      » older message » newer message

22/02/2002 11:31:18 AM, tone.skoda at siol.net wrote:

>
>----- Original Message -----
>From: "Dan Moyer" <DANIELMOYER at prodigy.net>
>
>> ... if the edges of the rectangles are all vertical and horizontal with
>respect to
>> the coordinate system (the screen).
>
>I don't understand this quite. Rectangles allways have two horizontal and
>two vertical edges. If edges are not horizontal or vertical then that would
>be paralelogram or whatever, no?

Not all rectangles are vertical/horizontal. Some are rotated like a diamond
shape.

     /\
     \/


>> Do you need to handle conditions other
>> than that?
>
>No. You all responded with functions how to find out if (and how) rectangle
>is inside rectangle.
>I have around 10.000 rectangles and I have to get all rectangles which have
>at least one of their four points inside a big rectangle.
>I want to be able to use binary search on sorted rectangles for speed.
>
>If I do it like this it is too slow:
>
>function get_rects_inside_rect (sequence rectangles, sequence big_rect)
>    sequence rects_inside
>    sequence rect
>    rects_inside = {}
>    for int i = 0 to length (rects) do
>        rect = rects [i]
>        if is_rect_partially_inside_rect (rect, big_rect)  then
>            rects_inside = append (rects_inside, rect)
>        end if
>   end for
>   return rects_inside
>end function
>
>A little faster it would be if I woluld somehow sort them by their left-x,
>or something similar. Unclear to me right now.

I tried a variation of the algorithm you've got here and it was fairly fast on
my machine. I'm
getting 200,000 hits in 0.28 seconds. 

 ------------
 sequence testdata
 -- Generate some test data.
 function randrange(object range)
    if atom(range) then
        return rand(range)
    end if

    return rand(range[2]-range[1]+1) + range[1] - 1
 end function

 testdata = repeat({0,0,0,0}, 200000)

 for i = 1 to length(testdata) do
     testdata[i][1] = randrange({50,950})
     testdata[i][2] = randrange({50,950})
     testdata[i][3] = testdata[i][1] + randrange(100)
     testdata[i][4] = testdata[i][2] + randrange(100)
 end for


 -- See how many hits I make
 integer hi
 sequence BigRectangle 
 sequence hits
 atom startt

 startt = time()
 hits = repeat(0, length(testdata))
 hi = 0
 BigRectangle = {200,200,699,699}

 for i = 1 to length(testdata) do
    if testdata[i][1] <= BigRectangle[3] and
       testdata[i][2] <= BigRectangle[4] and
       testdata[i][3] >= BigRectangle[1] and
       testdata[i][4] >= BigRectangle[2] then
       hi += 1
       hits[hi] = i
    end if
 end for
 hits = hits[1..hi]
 printf(1, "Number of hits: %d in %g seconds \n", {length(hits), time()-startt})

 ------------


---------
Cheers,
Derek Parnell

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu