mahantesh's picture

dragging the line segment by selecting the vertex

I am drawing lines using mouse event functions,but my main goal is to select those drawn lines and resize or move to another location.how am i supposed to do that?

  1. how to select line or rectangle which is drawn using mouse event dynamically?
  2. how to move selected primitive to another location?
  3. how to re size the line by dragging the selected vertex?

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
flopoloco's picture

I have created a simple program in a couple of minutes, it's not sophisticated but it's very simple just to get things going. I have used a GLControl with WinForms but it will work the same for a GameWindow based application.

How to use it:
Right click to create a point and left click to move the point around.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
 
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
 
namespace OpenTKLineEditor
{
	class OpenTKForm : Form
	{
		public GLControl MyControl { get; private set; }
 
		public List<Vector2> MyList { get; private set; }
 
		int selectedIndex = -1;
 
		public OpenTKForm()
		{
			// Set the form
			this.Size = new Size(640, 480);
 
			// Set the OpenGL control
			MyControl = new GLControl();
			this.Controls.Add(MyControl);
			MyControl.Dock = DockStyle.Fill;
			MyControl.Load += new EventHandler(MyControl_Load);
			MyControl.Paint += new PaintEventHandler(MyControl_Paint);
			MyControl.MouseClick += new MouseEventHandler(MyControl_MouseClick);
			MyControl.MouseDown += new MouseEventHandler(MyControl_MouseDown);
			MyControl.MouseUp += new MouseEventHandler(MyControl_MouseUp);
			MyControl.MouseMove += new MouseEventHandler(MyControl_MouseMove);
 
			// Set the point list
			MyList = new List<Vector2>();
 
		}
 
		void MyControl_Load(object sender, EventArgs e)
		{
			GL.ClearColor(Color.DarkBlue);
 
			// Set size of point and width of line
			GL.PointSize(10f);
			GL.LineWidth(4f);
 
			// Set orthographic rendering
			GL.MatrixMode(MatrixMode.Projection);
			GL.LoadIdentity();
 
			GL.Ortho(MyControl.Bounds.Left, MyControl.Bounds.Right,
			         MyControl.Bounds.Bottom, MyControl.Bounds.Top, -1.0, 1.0);
			GL.Viewport(this.MyControl.Size);
		}
 
		void MyControl_Paint(object sender, PaintEventArgs e)
		{
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
			GL.MatrixMode(MatrixMode.Modelview);
      		GL.LoadIdentity();
 
      		// Draw the lines
      		GL.Color3(Color.Cyan);
      		GL.Begin(BeginMode.LineStrip);
      		foreach (Vector2 v in MyList)
      			GL.Vertex2(v);
      		GL.End();
 
			// Draw the points
 
			GL.Begin(BeginMode.Points);
			foreach (Vector2 v in MyList)
			{
				if (selectedIndex != -1 && MyList[selectedIndex].Equals(v))
					GL.Color3(Color.Red);
				else
					GL.Color3(Color.Yellow);
 
				GL.Vertex2(v);
			}
 
			GL.End();
 
			MyControl.SwapBuffers();
		}
 
		void MyControl_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
				MyList.Add(new Vector2(e.X, e.Y));
 
			MyControl.Invalidate();
		}
 
		void MyControl_MouseDown(object sender,  System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				if (selectedIndex == -1)
				{
					foreach (Vector2 v in MyList)
					{
						// Get the distance between mouse click and point
						// http://www.purplemath.com/modules/distform.htm
						Vector2 vd = Vector2.Subtract(v, new Vector2(e.X, e.Y));
						float distance = (vd.X * vd.X) + (vd.Y * vd.Y);
 
						// If the distance is lesser than 10 pixels we have
						// a valid selection. (10 is same as the size of GLPoint)
						// Console.WriteLine(distance);
						if (distance <= 20)
						{
							selectedIndex = MyList.IndexOf(v);
							break;
						}
 
					}
				}
			}
		}
 
		void MyControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				selectedIndex = -1;
			}
		}
 
		void MyControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (selectedIndex != -1)
			{
				MyList[selectedIndex] = new Vector2(e.X, e.Y);
 
				MyControl.Invalidate();
			}
		}
	}
 
	class Program
	{
		public static void Main(string[] args)
		{
			Application.Run(new OpenTKForm());
		}
	}
}

Some problems, now you can create a single linestrip. A good way to solve this problem and have many linestrips (instead of only one) is to create tuples of Lists. List<List<Vector2>> MyList2 = new List<List<Vector2>>();

mahantesh's picture

Thanks for the reply ,
Part of my doubt is cleared but i wanted to know how to drag the whole line which is being selected ,
Is there any method to select the line by clicking on any point of line and move it to another location ?
or
You used linestrip to draw many connected line,is there any method to select particular line in that array and move ?

mahantesh's picture

And even i am trying to eliminate one error in code but couldn't remove it,
1)draw line by clicking two points,
2)drag second point twice from one location to another
3)you will see second line drawn which is redundant .

I tried to change in code

void MyControl_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
		{
                       if(selectedIndex == -1)
                       {
			if (e.Button == MouseButtons.Left)
				{
                                  MyList.Add(new Vector2(e.X, e.Y));
                                }
                       }
			MyControl.Invalidate();
		}

but when i draw new line on same vertex i couldn't .
So please tell me where to change...

mahantesh's picture

I removed that error .i just want to know how to selecet particular line?plz anyone tell me how to select line!!!!!!

flopoloco's picture

Check, circle to line intersection algorithm.
http://mathworld.wolfram.com/Circle-LineIntersection.html

Circle begins from your mouse pointer up to a convenient distance around the cursor.

Also there is a possibility to make better object oriented solution so you can identify the actual selected, or movable line in more convenient way.

struct Line {
public Vector2 Position;
public bool Selected;
}
 
List<Line> lineList;