Clicking on Line
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
:) I think you'll have to, but it's not that hard as u might think. Maybe this helps: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/linecurv_4bw3.asp[^] Don't try it, just do it! ;-)
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
You don't. Drawing a line does just that. To determine whether the user has clicked on it requires you to put code in your window's mouse event handlers, store off the coordinate of the line some how, and then check accordingly. ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
As others mentioned you can peek at the pixel under the line but this is crude since you can't distinguist between any same colored line. The best solution is to create "control" like objects where events are passed down just like any container-to-control. Let your Line object determine if it was clicked on or if clicking a special part of it warrents different behavior (ie. handles).
-
If i draw a line
pDC->MoveTo(x,y);
pDC->LineTo(x1,y1);How do i know if user clicks on this line ? do i have to write my own line drawing algo and then check for X,Y , i'd hate that :zzz: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
bool AmICloseToLine(CPoint p, CPoint start, CPoint stop, double Sensitivity) { //start = your point (x,y) //stop = your point (x1,y1) //p = point user clicks on //Sensitivity is how close you wish user to be to register click CSize va,vb,vc; double a,b,c,s; //Get the vectors between your start point, stop point and a third // point (p) where the user clicks va = start - p; vb = stop - p; vc = start-stop; //Calculate the length of these vectors a = sqrt(va.cx*va.cx+va.cy*va.cy*1.0); b = sqrt(vb.cx*vb.cx+vb.cy*vb.cy*1.0); c = sqrt(vc.cx*vc.cx+vc.cy*vc.cy*1.0); //Calculate the "semi-perimeter" from Heron's formula for area //of a triangle. s = (a+b+c)/2.0; //h is the perpendicular distance from user point to your line. double h = 4*s*(s-a)*(s-b)*(s-c)/(c*c); return (h<=Sensitivity); }
Paul Hooper If you spend your whole life looking over your shoulder, they will get you from the front instead. -
bool AmICloseToLine(CPoint p, CPoint start, CPoint stop, double Sensitivity) { //start = your point (x,y) //stop = your point (x1,y1) //p = point user clicks on //Sensitivity is how close you wish user to be to register click CSize va,vb,vc; double a,b,c,s; //Get the vectors between your start point, stop point and a third // point (p) where the user clicks va = start - p; vb = stop - p; vc = start-stop; //Calculate the length of these vectors a = sqrt(va.cx*va.cx+va.cy*va.cy*1.0); b = sqrt(vb.cx*vb.cx+vb.cy*vb.cy*1.0); c = sqrt(vc.cx*vc.cx+vc.cy*vc.cy*1.0); //Calculate the "semi-perimeter" from Heron's formula for area //of a triangle. s = (a+b+c)/2.0; //h is the perpendicular distance from user point to your line. double h = 4*s*(s-a)*(s-b)*(s-c)/(c*c); return (h<=Sensitivity); }
Paul Hooper If you spend your whole life looking over your shoulder, they will get you from the front instead. -
Wonderful piece of code Thanks :) C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg
No problems. Two small caveats though. First, the "sensitivity" is the distance you want the user to click within SQUARED. This saves calculating a sqrt. Secondly, I forgot to mention in the original post that this code calculates the perpendicular distance to the line defined by the two points - extended to infinity in both directions. In other words
.
.
X
\ *
\
\
X
.
.
.
* .if your line is defined by the X's then BOTH points marked with * would return true. If you want to restrict the result to only the top asterisk, you will need to add extra checking to the routine. The last line would need to be
return (h < Sensitivity && a < c && b < c);
I should also explain what the code is doing. It assumes that your start point, stop point and the click point form a triangle\* |h X------------------------X
the code calculates h - the perpendicular distance. First, we calculate the length of each side. Second, we use the three side lengths to calculate the area of the triangle using Heron's formula Area = sqrt(s(s-a)(s-b)(s-c)) where s is (a+b+c)/2; Third, we use the other formula for area of a triangle Area = 1/2 base * height. We know the area, we know the base, we can find the height. The code actually calculates h squared as described above. Finally, the
&& a < c && b < c
part of the modified last works this way.\* |h X-----------c------------X............
c is the distance between the X's and a would be the distance between the first X and the *. Because a > c, we know that the * is on the "extended" line. I hope this all makes sense. Sorry I didn't explain it better the first time. Paul Hooper If you spend your whole life looking over your shoulder, they will get you from the front instead.