MFC Line drawing and selection problem.....
Author 
Message 
Opal #1 / 18

MFC Line drawing and selection problem.....
Hi, I'm trying to make a program where you can draw lines and select them. So far I can do this, but I have a problem. To select a line, you have to make a selection rectangle around the line. This would be okay, except for sometimes the larger lines' rectangles cover the smaller lines' selection rectangles, and they become unselectable. now, I know there is a way to make the line only selectable by clicking near to it (like 10 or so points away), without having a massive selection rectangle. Is there anyone who knows the code snippet, or who has it anywhere, that could bung it up on here to help me ? I'd be sooo greatful... My current code for selection looks like this : BOOL CLine::PtInLine(POINT point) { int dx = abs(m_ptFrom.x  m_ptTo.x); int dy = abs(m_ptFrom.y  m_ptTo.y); if (abs(m_ptFrom.x  point.x) < (dx30) && abs(m_ptTo.x  point.x) < (dx30)) { if (abs(m_ptFrom.y  point.y) < (dy30) && abs(m_ptTo.y  point.y) < (dy30)) { return TRUE; } else { return FALSE; } } else { return FALSE; } Quote: } // end BOOL CLine::PtInLine(POINT point)
Any help greatfully received. Regards Dan

Thu, 24 Oct 2002 03:00:00 GMT 


Schik #2 / 18

MFC Line drawing and selection problem.....
Hi Opal, I've done this with CRgn. In my program there are several objects with lines,curves etc. for select them with the mouse I use: pDC>BeginPath pDC>..DrawingFcts pDC>EndPath CreateRgnFromPath rgn.PtInRgn By Schiko
Quote: > Hi, > I'm trying to make a program where you can draw lines and select them. So > far I can do this, but I have a problem. To select a line, you have to make > a selection rectangle around the line. This would be okay, except for > sometimes the larger lines' rectangles cover the smaller lines' selection > rectangles, and they become unselectable. > now, I know there is a way to make the line only selectable by clicking near > to it (like 10 or so points away), without having a massive selection > rectangle. Is there anyone who knows the code snippet, or who has it > anywhere, that could bung it up on here to help me ? I'd be sooo greatful... > My current code for selection looks like this : > BOOL CLine::PtInLine(POINT point) > { > int dx = abs(m_ptFrom.x  m_ptTo.x); > int dy = abs(m_ptFrom.y  m_ptTo.y); > if (abs(m_ptFrom.x  point.x) < (dx30) && abs(m_ptTo.x  point.x) < > (dx30)) > { > if (abs(m_ptFrom.y  point.y) < (dy30) && abs(m_ptTo.y  point.y) < > (dy30)) > { > return TRUE; > } > else > { > return FALSE; > } > } > else > { > return FALSE; > } > } // end BOOL CLine::PtInLine(POINT point) > Any help greatfully received. > Regards > Dan

Thu, 24 Oct 2002 03:00:00 GMT 


Tenebra #3 / 18

MFC Line drawing and selection problem.....
I'm also looking for it... the way would be to remember my geometry course, and calculate the distance between a point and a line... if you find it, it would be great to mail me...(and if I find, I'll mail you...) Thanx. You wanna see what a bug is?: visit http://graff.ctw.net and download Graff beta 1.02 (in french, if you want an english version mail me)

Thu, 24 Oct 2002 03:00:00 GMT 


Joseph M. Newcome #4 / 18

MFC Line drawing and selection problem.....
I was suggesting a divideandconquer algorithm in an earlier post. If you don't have hundreds or thousands of objects, the solution below is excellent. joe On Sun, 7 May 2000 15:52:04 +0200, "Schiko" Quote:
>Hi Opal, >I've done this with CRgn. >In my program there are several objects with lines,curves etc. >for select them with the mouse I use: >pDC>BeginPath >pDC>..DrawingFcts >pDC>EndPath >CreateRgnFromPath >rgn.PtInRgn >By Schiko
>> Hi, >> I'm trying to make a program where you can draw lines and select them. So >> far I can do this, but I have a problem. To select a line, you have to >make >> a selection rectangle around the line. This would be okay, except for >> sometimes the larger lines' rectangles cover the smaller lines' selection >> rectangles, and they become unselectable. >> now, I know there is a way to make the line only selectable by clicking >near >> to it (like 10 or so points away), without having a massive selection >> rectangle. Is there anyone who knows the code snippet, or who has it >> anywhere, that could bung it up on here to help me ? I'd be sooo >greatful... >> My current code for selection looks like this : >> BOOL CLine::PtInLine(POINT point) >> { >> int dx = abs(m_ptFrom.x  m_ptTo.x); >> int dy = abs(m_ptFrom.y  m_ptTo.y); >> if (abs(m_ptFrom.x  point.x) < (dx30) && abs(m_ptTo.x  point.x) < >> (dx30)) >> { >> if (abs(m_ptFrom.y  point.y) < (dy30) && abs(m_ptTo.y  point.y) >< >> (dy30)) >> { >> return TRUE; >> } >> else >> { >> return FALSE; >> } >> } >> else >> { >> return FALSE; >> } >> } // end BOOL CLine::PtInLine(POINT point) >> Any help greatfully received. >> Regards >> Dan
Joseph M. Newcomer [MVP]
Web: http://www3.pgh.net/~newcomer MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

Thu, 24 Oct 2002 03:00:00 GMT 


Tenebra #5 / 18

MFC Line drawing and selection problem.....
yes but no... Rgn are good if you want to know if the user clicked exactly on the line, but not around the line... (and it become stranger with a set of line segment...). So if you have a better solution it would be good ;) Tenebrax

Thu, 24 Oct 2002 03:00:00 GMT 


Tenebra #6 / 18

MFC Line drawing and selection problem.....
Quote: > I was suggesting a divideandconquer algorithm in an earlier post. If > you don't have hundreds or thousands of objects, the solution below is > excellent.
It would be very kind if you could gimme more info about this divideandconquer algo... (url or post) Thanx Tenebrax note: I'm on this newsgroup for not a long time, so I don't have all the post (and don't have enough money to download all the post....).

Thu, 24 Oct 2002 03:00:00 GMT 


#7 / 18

MFC Line drawing and selection problem.....

Fri, 19 Jun 1992 00:00:00 GMT 


Opal #8 / 18

MFC Line drawing and selection problem.....
Hi ppl !!! ok, i've got a Half working answer.... but this only works for straight lines !!! I'll give you the description, then i'll post the code... Going back to my old ALevel maths books (yes, i'm English ;D ) I found some stuff on coordinate geometry. Now basically, for straight lines... if you work out the Gradient of the line, this is derived from : increase in Y  increase in X then, once you have drawn a line, you "Should" know it's start and end points. Using the equation of a line, which is derived from : Y = GXC put in any point on the line, the start point will do, and the gradient. ReArrange to get C. C = GX  Y Ok, once you have the answer to C, then you want to do a hit test. so take the point.x and point.y from the mouse and test them. using the first equation Y=GXC put in the X value from the mouse. Put in the gradient of the line you are checking. Put in the value of C you got earlier. if point.y = y from the equation, then HIT = TRUE !!!! ;) yay. so far, this only works for hitting right on the line though, and we also want be able to have a small buffer area around the line so that you don't have to click right to the very pixel on the line. Not only this, the equations are a bit erroneuos as POINTS are always INTs. so rearranging the equation to give us a buffer and only use integers gives us this...... substituting the gradient out. c(xInc) = point.y(xInc) yInc(point.x). This WORKS !!!!! I'll show the code in a sec and all will become clearer. The only problem with this is that there is no bounds checking. If you follow a line's gradient past the end of a line, it is still selectable (the mouseclick POINT still falls on the line according to the line's equation). I've tried bound testing this, but to no avail, so someone please help us out here ! We'll have a killer method if we can crack it !!! Regards Dan Code follows.  BOOL CLine::PtInLine(POINT point) { // we need to find the gradient of the line so // as stated in my old ALevel maths book... // increase in y/increase in x = gradient. int xInc = (m_ptFrom.x  m_ptTo.x); int yInc = (m_ptFrom.y  m_ptTo.y); // Now, we need the equation of the line. // This is given by y=gx+c... // we need to rearrange this to get c // c = y  gx // take into consideration that INT is more // accurate than LONG or DOUBLE, lets rearrange // the equation so we don't have to do any division // subs g(gradient) for yInc/xInc gives us..... // y(xInc) = x(yInc)  c(xInc) // these are calculated below int cxInc = ( (m_ptFrom.y*xInc)  (m_ptFrom.x*yInc) ); int yxInc = (point.y*xInc); int xyInc = (point.x*yInc); // these are to give us a small buffer area around the // line so you don't have to click right on the line int cxIncLo = cxInc  2000; int cxIncHi = cxInc + 2000; // I don't know why 2000, but it seems to work. // then the equation if (yxInc > (xyInc + cxIncLo) && yxInc < (xyInc + cxIncHi) ) { return TRUE; } else { return FALSE; } Quote: } // end
>yes but no... >Rgn are good if you want to know if the user clicked exactly on the line, >but not around the line... (and it become stranger with a set of line >segment...). So if you have a better solution it would be good ;) >Tenebrax

Fri, 25 Oct 2002 03:00:00 GMT 


#9 / 18

MFC Line drawing and selection problem.....

Fri, 19 Jun 1992 00:00:00 GMT 


Jaco A. Imthor #10 / 18

MFC Line drawing and selection problem.....
Quote: > I'm trying to make a program where you can draw lines and select them.
Here's some code that works for me. I didn't write it myself, though! In the code below, a line can consist of multiple line fragments, which by themselves are straight lines between coordinates. In other words, a line consists of a list (m_list) of coordinates. The function returns the smallest distance between a point (parameter CPoint point; in my app usually the mous cursor) and the nearestby line fragment. On return, the parameter NearestLine contains the index (in m_list) to the line fragment that's closest to CPoint point; the parameter NearestPoint holds the point ON that line fragment that is closest (again) to CPoint point. I emailed the code below to someone else before, and he ported it to his app without problems. So I hope this helps for you too! Cheers, Jaco. ====================================================================== #include <math.h> #define sqr(x) ((x)*(x)) float CLine::IsHit(CPoint point, CPoint &NearestPoint, int &NearestLine) { double SmallestDistance = 2000.0f, Distance, Factor, Length; int PointX, PointY, LineX, LineY; for(int Coor = 0; Coor < m_list.GetSize()  1; Coor++) { LineX = m_list[Coor + 1].x  m_list[Coor].x; LineY = m_list[Coor + 1].y  m_list[Coor].y; PointX = point.x  m_list[Coor].x; PointY = point.y  m_list[Coor].y; Length = sqrt(sqr(LineX) + sqr(LineY)); Factor = ((LineX / Length) * PointX + (LineY / Length) * PointY) / Length; if(Factor > 0.0f && Factor < 1.0) { PointX = (int) (m_list[Coor].x + Factor * LineX); PointY = (int) (m_list[Coor].y + Factor * LineY); Distance = sqr(point.x  PointX) + sqr(point.y  PointY); if(Distance < SmallestDistance) { NearestPoint.x = PointX; NearestPoint.y = PointY; SmallestDistance = Distance; NearestLine = Coor; } } else { Distance = sqr(point.x  m_list[Coor].x) + sqr(point.y  m_list[Coor].y); if(Distance < SmallestDistance) { NearestPoint = m_list[Coor]; SmallestDistance = Distance; NearestLine = Coor; } Distance = sqr(point.x  m_list[Coor + 1].x) + sqr(point.y  m_list[Coor + 1].y); if(Distance < SmallestDistance) { NearestPoint = m_list[Coor + 1]; SmallestDistance = Distance; NearestLine = Coor + 1; } } } return (float) sqrt(SmallestDistance); Quote: }
===============================================================

Fri, 25 Oct 2002 03:00:00 GMT 


#11 / 18

MFC Line drawing and selection problem.....

Fri, 19 Jun 1992 00:00:00 GMT 


Joseph M. Newcome #12 / 18

MFC Line drawing and selection problem.....
You need to add a simple test: compute a normalized bounding box of the line, that is, create a CRect r(x0, y0, x1, y1) and call r.NormalizeRect() which gets it into the right order in case the line was drawn righttoleft or bottomtotop. Then test if mousex > r.right or mousex < r.left or mousex > r.bottom or mousex < r.top and if any of those are true, you are outside the line. Note also that in the regionhitpoint test method, there is nothing that says you have to draw the path with the samesize pen as you drew the line or curve; if, instead, you draw it with a wider pen (your buffer zone size), then the region hit test should do the job. joe On Mon, 08 May 2000 12:18:29 GMT, "Opal" Quote:
>Hi ppl !!! >ok, i've got a Half working answer.... but this only works for straight >lines !!! >I'll give you the description, then i'll post the code... >Going back to my old ALevel maths books (yes, i'm English ;D ) I found >some stuff on coordinate geometry. Now basically, for straight lines... >if you work out the Gradient of the line, this is derived from : >increase in Y > >increase in X >then, once you have drawn a line, you "Should" know it's start and end >points. >Using the equation of a line, which is derived from : >Y = GXC >put in any point on the line, the start point will do, and the gradient. >ReArrange to get C. >C = GX  Y >Ok, once you have the answer to C, then you want to do a hit test. >so take the point.x and point.y from the mouse and test them. >using the first equation Y=GXC >put in the X value from the mouse. >Put in the gradient of the line you are checking. >Put in the value of C you got earlier. >if point.y = y from the equation, then HIT = TRUE !!!! ;) yay. >so far, this only works for hitting right on the line though, and we also >want be able to have a small buffer area around the line so that you don't >have to click right to the very pixel on the line. Not only this, the >equations are a bit erroneuos as POINTS are always INTs. so rearranging the >equation to give us a buffer and only use integers gives us this...... >substituting the gradient out. >c(xInc) = point.y(xInc) yInc(point.x). >This WORKS !!!!! I'll show the code in a sec and all will become clearer. >The only problem with this is that there is no bounds checking. If you >follow a line's gradient past the end of a line, it is still selectable (the >mouseclick POINT still falls on the line according to the line's equation). >I've tried bound testing this, but to no avail, so someone please help us >out here ! We'll have a killer method if we can crack it !!! >Regards >Dan >Code follows. > >BOOL CLine::PtInLine(POINT point) >{ > // we need to find the gradient of the line so > // as stated in my old ALevel maths book... > // increase in y/increase in x = gradient. > int xInc = (m_ptFrom.x  m_ptTo.x); > int yInc = (m_ptFrom.y  m_ptTo.y); > // Now, we need the equation of the line. > // This is given by y=gx+c... > // we need to rearrange this to get c > // c = y  gx > // take into consideration that INT is more > // accurate than LONG or DOUBLE, lets rearrange > // the equation so we don't have to do any division > // subs g(gradient) for yInc/xInc gives us..... > // y(xInc) = x(yInc)  c(xInc) > // these are calculated below > int cxInc = ( (m_ptFrom.y*xInc)  (m_ptFrom.x*yInc) ); > int yxInc = (point.y*xInc); > int xyInc = (point.x*yInc); > // these are to give us a small buffer area around the > // line so you don't have to click right on the line > int cxIncLo = cxInc  2000; > int cxIncHi = cxInc + 2000; > // I don't know why 2000, but it seems to work. > // then the equation > if (yxInc > (xyInc + cxIncLo) && > yxInc < (xyInc + cxIncHi) ) > { > return TRUE; > } > else > { > return FALSE; > } >} // end
>>yes but no... >>Rgn are good if you want to know if the user clicked exactly on the line, >>but not around the line... (and it become stranger with a set of line >>segment...). So if you have a better solution it would be good ;) >>Tenebrax
Joseph M. Newcomer [MVP]
Web: http://www3.pgh.net/~newcomer MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

Fri, 25 Oct 2002 03:00:00 GMT 


Tenebra #13 / 18

MFC Line drawing and selection problem.....
Quote: > Note also that in the regionhitpoint test method, there is nothing > that says you have to draw the path with the samesize pen as you drew > the line or curve; if, instead, you draw it with a wider pen (your > buffer zone size), then the region hit test should do the job.
GOOD!!!!! Now I know why people call you expert... and why they call me newbie ;)... That's THE easier way (cause it works with quite everything...)... I'll play with it... really thanx !!! Tenebrax  newbie of the newbie...

Fri, 25 Oct 2002 03:00:00 GMT 


#14 / 18

MFC Line drawing and selection problem.....

Fri, 19 Jun 1992 00:00:00 GMT 


Joseph M. Newcome #15 / 18

MFC Line drawing and selection problem.....
It is well over 20 years old now; I remember when it first came out, and it was one of the coolest algorithms we'd seen. There was Warnock's algorithm, and another that came out a couple months before or after, which was equally cool. You might try the backissue index at www.acm.org, I think they were both Communications of the ACM (CACM) articles. The divideandconquer technique is fairly well documented in the literature; I haven't written one in C, although I wrote one in the mid1980s on a machine long forgotten in a language virtually unknown, and all I have is a printed listing somewhere in fifty boxes of archives. I don't know if you saw my other post, but there is no reason to use the region technique on the same width line as you drew; draw a wider line when computing the region!
Quote: >yes but no... >Rgn are good if you want to know if the user clicked exactly on the line, >but not around the line... (and it become stranger with a set of line >segment...). So if you have a better solution it would be good ;) >Tenebrax
Joseph M. Newcomer [MVP]
Web: http://www3.pgh.net/~newcomer MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

Fri, 25 Oct 2002 03:00:00 GMT 


Page 1 of 2

[ 18 post ] 

Go to page:
[1]
[2] 
