# Clickable line

• 03-24-2006
IdunnO
Clickable line
Hi there,

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....

Thnx.

IdunnO
• 03-24-2006
Ken Fitlike
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.
• 03-25-2006
Salem
> 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.
• 03-25-2006
joed
After the bounds check, this might work for the line test (untested).
x1, y1 and x2, y2 are the line endpoints:

Code:

```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) )     point_is_on_line...```
Since it's hard to click on a single pixel, maybe use a within-range test instead of the equality test.
• 03-26-2006
novacain
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)