Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Clicking on Line

Clicking on Line

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++graphics
8 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Monty2
    wrote on last edited by
    #1

    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

    A J A T P 5 Replies Last reply
    0
    • M Monty2

      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

      A Offline
      A Offline
      Alexander M
      wrote on last edited by
      #2

      :) 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! ;-)

      1 Reply Last reply
      0
      • M Monty2

        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

        J Offline
        J Offline
        Jim Crafton
        wrote on last edited by
        #3

        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

        1 Reply Last reply
        0
        • M Monty2

          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

          A Offline
          A Offline
          AORD
          wrote on last edited by
          #4

          You could also try someting like GetPixel to find the colour at the mouse pointer.

          1 Reply Last reply
          0
          • M Monty2

            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

            T Offline
            T Offline
            Tom Larsen
            wrote on last edited by
            #5

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

            1 Reply Last reply
            0
            • M Monty2

              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

              P Offline
              P Offline
              Paul Hooper
              wrote on last edited by
              #6

              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.

              M 1 Reply Last reply
              0
              • P Paul Hooper

                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.

                M Offline
                M Offline
                Monty2
                wrote on last edited by
                #7

                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

                P 1 Reply Last reply
                0
                • M Monty2

                  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

                  P Offline
                  P Offline
                  Paul Hooper
                  wrote on last edited by
                  #8

                  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.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups