Moving a drawn line with the mouse

后端 未结 2 537
南笙
南笙 2021-01-01 07:47

I am trying to move a drawn line by grabbing it with the mouse.

The line have already been drawn with Graphics.DrawLine(Pen P, Point A, Point B).

<
相关标签:
2条回答
  • 2021-01-01 08:23

    I suggest you create a rectangle that is the width of the line and the length of the line, then you can use

    if(rectangle.Contains(Point p))
    {
       // do your move
    }
    

    You can also inflate the rectangle to make it easier to grab with:

    rectangle.Inflate(1, 1);
    
    0 讨论(0)
  • 2021-01-01 08:40

    Let's start with the basics, getting a line on the screen. I created a custom class to handle some of the functions I want available to me for this process:

    public class MyLine
    {
        public Pen pen { get; set; }
        public Point Start { get; set; }
        public Point End { get; set; }
    
        public MyLine(Pen p, Point p1, Point p2)
        {
            pen = p;
            Start = p1;
            End = p2;
        }
    
        public float slope
        {
            get
            {
                return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
            }
        }
        public float YIntercept
        {
            get
            {
                return Start.Y - slope*Start.X;
            }
        }
    
        public bool IsPointOnLine(Point p, int cushion)
        {
            float temp = (slope * p.X + YIntercept);
            if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    

    This class provides a few helper functions that will make our life easier. We have properties that return the slope and the Y-intercept, so we can determine if a certain point is on the line. We then provide a helper function IsPointOnLine() that takes a point and a cushion. The cushion is used to simply allow for a user to click close enough to the line to get it to return true.

    Next I am going to instantiate the line and draw it in the Form's paint event:

    MyLine m;
    
    private void Form1_Load(object sender, EventArgs e)
    {
        m= new MyLine(Pens.Black, new Point(20, 20), new Point(40, 40));
    }
    
    
    
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawLine(m.pen, m.Start, m.End);     
    }
    

    Now you should be able to run your application and see a line that goes from 20,20 to 40,40 on the screen.

    Now I want to handle the mouse interaction with the line, so on MouseDown, we will see if the click point intersects the line and if it is set a flag and keep our deltas from the endpoints. On the MouseMove event, we will see if the line has been clicked but not released and reset the coordinates appropriately. In the MouseUp event, we simple reset our flag:

    Point deltaStart;
    Point deltaEnd;
    bool dragging = false;
    
    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
    
        if (e.Button == System.Windows.Forms.MouseButtons.Left && m.IsPointOnLine(e.Location, 5))
        {
            dragging = true;
            deltaStart = new Point(m.Start.X - e.Location.X, m.Start.Y - e.Location.Y);
            deltaEnd = new Point(m.End.X - e.Location.X, m.End.Y - e.Location.Y);
        }
    }
    
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging && deltaStart != null && deltaEnd != null )
        {
            m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
            m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
            this.Refresh();
        }
    }
    
    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }
    

    Now you should be able to click within 5 pixels of the line and have it move with your mouse.

    Note, there are some spots in the code that need additional error handling, especially to handle division by 0 errors.

    0 讨论(0)
提交回复
热议问题