Reputation: 47
I am using visual studio c# windows form, I need help to draw a circle using the Mouse click.. first click will give me the center of the circle equal to the cursor position and the second click will give me a point on the border of the circle equal to the second position of the cursor, the distance between the to points will give me the radius..now I have radius and point ..I can draw a circle ..The code doesn't work because I only can get one position of the cursor no matter how many times I click the mouse
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
int lastX = Cursor.Position.X;//the first click x cursor position
int lastY = Cursor.Position.Y;//the first click y cursor position,
//is there any way to reuse the Cursor.Position for different point ??
int x = Cursor.Position.X;//the second click x cursor position
int y = Cursor.Position.Y;//the second click y cursor position
Graphics g;
double oradius=Math.Sqrt(((lastX-x)^2) +((lastY-y)^2));
//double newy = Math.Sqrt(lastY);
// int newxv = Convert.ToInt32(newx);
int radius= Convert.ToInt32(oradius);
g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, x, y,radius,radius);
}
private void DrawCircle(PaintEventArgs e, int x, int y, int width, int height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
e.Graphics.DrawEllipse(pen, x - width / 2, y - height / 2, width, height);
}
}
Upvotes: 0
Views: 1340
Reputation: 1054
private int _firstX;
private int _firstY;
private int _secondX;
private int _secondY;
private bool _isSecondClick;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (_isSecondClick)
{
_secondX = Cursor.Position.X;
_secondY = Cursor.Position.Y;
var radious1 = Math.Pow(_firstX - _secondX, 2);
var radious2 = Math.Pow(_firstY - _secondY, 2);
var radious = Math.Sqrt(radious1 + radious2);
Graphics g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, _secondX, _secondY, radious, radious);
}
else
{
_firstX = Cursor.Position.X;
_firstY = Cursor.Position.Y;
_isSecondClick = true;
}
}
private void DrawCircle(PaintEventArgs arg, int x, int y, double width, double height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
var xL = Convert.ToInt32(x - width / 2);
var yL = Convert.ToInt32(y - height / 2);
var hL = Convert.ToInt32(height);
var wL = Convert.ToInt32(width);
arg.Graphics.DrawEllipse(pen, xL, yL, wL, hL);
}
Upvotes: 0
Reputation: 3363
There are many things fundamentally wrong with this code, here is a complete, working example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Point clickCurrent = Point.Empty;
private Point clickPrev = Point.Empty;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
clickPrev = clickCurrent;
clickCurrent = this.PointToClient(Cursor.Position);
if (clickPrev == Point.Empty) return;
Graphics g;
double oradius = Math.Sqrt((Math.Pow(clickPrev.X - clickCurrent.X, 2)) + (Math.Pow(clickPrev.Y - clickCurrent.Y, 2)));
int radius = Convert.ToInt32(oradius);
g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, clickPrev.X, clickPrev.Y, radius * 2, radius * 2);
clickCurrent = Point.Empty;
}
private void DrawCircle(PaintEventArgs e, int x, int y, int width, int height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
e.Graphics.DrawEllipse(pen, x - width / 2, y - height / 2, width, height);
}
}
Upvotes: 0
Reputation: 82474
Your lastX
and lastY
are local variables, and you initialize them in the beginning of the MouseDown event handler. They should be class level variables and should be populated at the end of the MouseDown event handler.
Also, you should test if they already have a value, and only if they have value then draw the circle and then clear them (so that the next circle will have it's own center).
Here is an improvement of your code. Note I've used the using
keyword with the graphics object and with the pen - get used to use it every time you are using an instance of anything that's implementing the IDisposable
interface.
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (_lastPosition != Point.Empty)
{
var currentPosition = Cursor.Position;
var oradius = Math.Sqrt(((_lastPosition.X - currentPosition.X) ^ 2) + ((_lastPosition.Y - currentPosition.Y) ^ 2));
var radius = Convert.ToInt32(oradius);
using (var g = this.CreateGraphics())
{
var arg = new PaintEventArgs(g, new Rectangle());
DrawCircle(arg, currentPosition, radius, radius);
}
_lastPosition = Point.Empty;
}
else
{
_lastPosition = Cursor.Position;
}
}
private void DrawCircle(PaintEventArgs e, Point position, int width, int height)
{
using (var pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3))
{
e.Graphics.DrawEllipse(pen, position.X - width / 2, position.Y - height / 2, width, height);
}
}
Note: This code can be improved even further.
Upvotes: 1
Reputation: 3222
You need to store the first click as well before you start doing the calculations. One way to do this is to create a class that simply throws an event every second time you pass it x and y coordinates like this:
public class CircleDrawer
{
private int _firstX;
private int _firstY;
private int _secondX;
private int _secondY;
private bool _isSecondClick;
private event EventHandler OnSecondClick;
public void RegisterClick(int x, int y)
{
if(_isSecondClick)
{
_secondX = x;
_secondY = y;
if(OnSecondClick != null)
OnSecondClick(this, null);
}
else
{
_firstX = x;
_firstY = y;
_isSecondClick = true;
}
}
}
You can then in your code simply call your methods:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
int lastX = Cursor.Position.X;//the first click x cursor position
int lastY = Cursor.Position.Y;//the first click y cursor position,
_circleDrawer.RegisterClick(lastX, lastY);
}
And in your constuctor:
public MyForm()
{
_circleDrawer = new CircleDrawer();
_circleDrawer.OnSecondClick += DrawCircle();
}
public void DrawCircle()
{
// Your drawing code
}
Upvotes: 2