I'm currently writing an application which displays all the main roads of my country. These roads are displayed as a lot of small pieces of polylines. The coordinates of these polylines are in a file and I've succeeded in displaying them.
Now I was wondering, does visual c++ have some sort of object type which looks like a line and it can be detected if that object has been clicked?
The reason I'm asking this is because now, if I click on a line, I have to discover the coordinates where I clicked, and go over all the lines (all 33000 of them) and see if that line is the one which has been clicked.
It's a long shot, but still... maybe someone has a good idea....
I don't belive there is a control that fits your specifications but it would be simple enough to create one either by subclassing or superclassing an existing control or, arguably simpler, just creating a custom control yourself.
Alternatively, you might consider refining your search algorithm to something perhaps better suited to searching through 33000 items of data.
> and go over all the lines (all 33000 of them) and see if that line is the one which has been clicked.
Imagine each line segment surrounded by a bounding rectangle.
Create an ordered 2D array
- sorted by left edge
- sorted by bottom edge
So for example, given a point x,y, you can immediately reject any rectangle which has either of these true
if ( p.x > rect[i].trx || p.x < rect[i].blx ) // tr=top right, bl=bottom left
Also do the same for the p.y comparing with the bottom and top edges of each bounding rectangle.
You should only need to do the rather expensive "point clicks a line" test on a small subset of lines.
After the bounds check, this might work for the line test (untested).
x1, y1 and x2, y2 are the line endpoints:
Since it's hard to click on a single pixel, maybe use a within-range test instead of the equality test.
dx1 = abs(mousex - x1);
dx2 = abs(mousex - x2);
dy1 = abs(mousey - y1);
dy2 = abs(mousey - y2);
w = abs(x1 - x2);
h = abs(y1 - y2);
if( ((dx1 + dx2) == w) && ((dy1 + dy2) == h) )
Another filter is to record the colorref (colour) used to draw the 'road' and test the colour of the point selected or a small rectangle ie 3x3 to allow for the user 'missing'. I would use it to filter out the clicks not on 'roads'.
GetPixel() (this is not all that fast)
For matching mouse location to a rectangle. Ensure you convert to the same cood system ie both relative to same top left point, window or screen.
ClientToScreen() (convert rect and point to screen coods)
IsPtInRect() (determine if the clicked point is in a particular rect)