Drawing to line segments and calculating intersection between them C# - c#

Hi i would like to know how can i get points from the second line i draw. Here is my code, for now i can draw lines with mouse event and draw lines with a button where i write the coordinates of the points.
public partial class Form1 : Form
{
Graphics drawArea;
private Point p1, p2;
List p1List = new List();
List p2List = new List();
public Form1()
{
InitializeComponent();
drawArea = panel1.CreateGraphics();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = CreateGraphics();
Pen p = new Pen(System.Drawing.Color.Black, 1);
for (int x = 0; x < p1List.Count; x++)
{
drawArea.DrawLine(p, p1List[x], p2List[x]);
}
}
private void button1_Click(object sender, EventArgs e)
{
p1.X = Convert.ToInt32(textBox1.Text);
p1.Y = Convert.ToInt32(textBox3.Text);
p2.X = Convert.ToInt32(textBox2.Text);
p2.Y = Convert.ToInt32(textBox4.Text);
Pen p = new Pen(System.Drawing.Color.Black, 2);
drawArea.DrawLine(p, p1.X, p1.Y, p2.X, p2.Y);
}
void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (p1.X == 0)
{
p1.X = e.X;
p1.Y = e.Y;
}
else
{
p2.X = e.X;
p2.Y = e.Y;
p1List.Add(p1);
p2List.Add(p2);
panel1.Invalidate();
p1.X = 0;
}
}
}
}

Related

How to remove all the drawn rectangles on the picture box? (Not on the image)

I have tried using the following code:
pictureBox1.Invalidate();
//or
pictureBox1.Update();
//or
Refresh();
But it just did nothing on it. I want to clear all the drawn graphics on my picture box as after I click the next page I want to draw the new rectangles on it. So, please don't provide me such a solution:
g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height))
or
Graphics.Clear();
Anyone want to share the solution with me? I am appreciated with it.
page 2
page 3
Form2.cs
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Red, 2);
e.Graphics.DrawRectangle(pen, rect);
}
bool draw;
int x_start, y_start;
Rectangle rect;
//UserRect rect;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
}
else if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
pictureBox1.Cursor = Cursors.Cross;
draw = true;
x_start = e.X;
y_start = e.Y;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
}else if(e.Button == MouseButtons.Right)
{
pictureBox1.Cursor = Cursors.Cross;
}
if (!draw) return;
LocalMousePosition = pictureBox1.PointToClient(Cursor.Position);
int x = Math.Min(x_start, LocalMousePosition.X);
int y = Math.Min(y_start, LocalMousePosition.Y);
int width = Math.Max(x_start, LocalMousePosition.X) - Math.Min(x_start, LocalMousePosition.X);
int height = Math.Max(y_start, LocalMousePosition.Y) - Math.Min(y_start, LocalMousePosition.Y);
rect = new Rectangle(x, y, width, height);
xx = x;
yy = y;
ww = width;
hh = height;
Refresh();
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
//pictureBox1.Cursor = Cursors.Default;
draw = false;
rectang = new UserRect(rect);
rect = new Rectangle(e.X, e.Y, 0, 0);
rectang.SetPictureBox(this.pictureBox1);
}
else if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
pictureBox1.Cursor = Cursors.Default;
_tracking = false;
}
}
UserRect.cs
public void Draw(Graphics g)
{
g.DrawRectangle(new Pen(Color.Green), rect);
foreach (PosSizableRect pos in Enum.GetValues(typeof(PosSizableRect)))
{
g.DrawRectangle(new Pen(Color.Red), GetRect(pos));
}
}
public void SetPictureBox(PictureBox p)
{
this.mPictureBox = p;
mPictureBox.MouseDown += new MouseEventHandler(mPictureBox_MouseDown);
mPictureBox.MouseUp += new MouseEventHandler(mPictureBox_MouseUp);
mPictureBox.MouseMove += new MouseEventHandler(mPictureBox_MouseMove);
mPictureBox.Paint += new PaintEventHandler(mPictureBox_Paint);
}
private void mPictureBox_Paint(object sender, PaintEventArgs e)
{
try
{
Draw(e.Graphics);
}
catch (Exception exp)
{
System.Console.WriteLine(exp.Message);
}
}
private void mPictureBox_MouseDown(object sender, MouseEventArgs e)
{
mIsClick = true;
nodeSelected = PosSizableRect.None;
nodeSelected = GetNodeSelectable(e.Location);
if (rect.Contains(new Point(e.X, e.Y)))
{
mMove = true;
}
oldX = e.X;
oldY = e.Y;
}
private void mPictureBox_MouseUp(object sender, MouseEventArgs e)
{
//MessageBox.Show(rect.ToString());
mIsClick = false;
mMove = false;
}
private void mPictureBox_MouseMove(object sender, MouseEventArgs e)
{
ChangeCursor(e.Location);
if (mIsClick == false)
{
return;
}
Rectangle backupRect = rect;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
switch (nodeSelected)
{
case PosSizableRect.LeftUp:
rect.X += e.X - oldX;
rect.Width -= e.X - oldX;
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
case PosSizableRect.LeftMiddle:
rect.X += e.X - oldX;
rect.Width -= e.X - oldX;
break;
case PosSizableRect.LeftBottom:
rect.Width -= e.X - oldX;
rect.X += e.X - oldX;
rect.Height += e.Y - oldY;
break;
case PosSizableRect.BottomMiddle:
rect.Height += e.Y - oldY;
break;
case PosSizableRect.RightUp:
rect.Width += e.X - oldX;
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
case PosSizableRect.RightBottom:
rect.Width += e.X - oldX;
rect.Height += e.Y - oldY;
break;
case PosSizableRect.RightMiddle:
rect.Width += e.X - oldX;
break;
case PosSizableRect.UpMiddle:
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
default:
if (mMove)
{
rect.X = rect.X + e.X - oldX;
rect.Y = rect.Y + e.Y - oldY;
}
break;
}
}
oldX = e.X;
oldY = e.Y;
if (rect.Width < 5 || rect.Height < 5)
{
rect = backupRect;
}
TestIfRectInsideArea();
mPictureBox.Invalidate();
}
Generally, I would split drawing graphics between _Paint event as you have it (for interactive drawing, such as selection box and mouse-move related stuff) and separate underlaying image.
There are several reasons for that, such as control over what you want to draw (imagine you want to draw only retangle 1, 3 and 5, if a some checkbox is not checked and then draw all of 1 to 6 if it is checked) and performance (with large amount of data).
You can do all of that in _Paint, but it will bloat. In contrast to that, you can split draw task into several functions, which is very handy for large drawing.
Very simplified example - VB.NET:
Dim UnderlayingImage as Image
UnderLayingImage = New Bitmap(Me.PictureBox1.Width, Me.Picturebox1.Height)
Dim g As Graphics = Graphics.FromImage(UnderLayingImage)
Dim bgBrush As SolidBrush = New SolidBrush(Color.LightSlateGray)
Dim bgBrushWhite As SolidBrush = New SolidBrush(Color.White)
Dim shPen As Pen = New Pen(Color.Black)
Dim rect As RectangleF = New RectangleF(50, 50, 100, 100)
g.FillRectangle(bgBrush, rect)
g.DrawRectangle(Pens.Black, Rectangle.Round(rect))
Me.PictureBoxDrawing.Image = UnderLayingImage
Translated to C#:
Image UnderlayingImage;
UnderLayingImage = new Bitmap(this.PictureBox1.Width, this.Picturebox1.Height);
Graphics g = Graphics.FromImage(UnderLayingImage);
SolidBrush bgBrush = new SolidBrush(Color.LightSlateGray);
SolidBrush bgBrushWhite = new SolidBrush(Color.White);
Pen shPen = new Pen(Color.Black);
RectangleF rect = new RectangleF(50, 50, 100, 100);
g.FillRectangle(bgBrush, rect);
g.DrawRectangle(Pens.Black, Rectangle.Round(rect));
this.PictureBoxDrawing.Image = UnderLayingImage;
And back to your question: This way you don't Clear your drawing, but you redraw it and in the process you decide what to include and what to ommit.

Draw line in picture box with two mouse clicks in C# windows form

I need help drawing line on picture box.
I get coordinates for point2 and point2 on mouse click and I drew line between this two coordinates.
What I need to do is to take value for point1 and start drawing the line from that point1, and line should follow my cursor and when I click second time on picture box it should be drawn.
Any help would be appreciated.
This is what I have so far
// Points p1(x1,y1), p2(x2,y2)
private Point p1, p2;
List<Point> p1List = new List<Point>();
List<Point> p2List = new List<Point>();
int count = 0;
// Click 2 times on image to get coordinate values for p1 & p2
private void pbChooseDirection_MouseDown(object sender, MouseEventArgs e)
{
if(count/2 == 0)
{
pbChooseDirection.Image = drawingLineImage;
}
if (p1.X == 0)
{
p1.X = e.X;
p1.Y = e.Y;
count++;
}
else
{
p2.X = e.X;
p2.Y = e.Y;
count++;
p1List.Add(p1);
p2List.Add(p2);
Invalidate();
// Sets X to 0 and choose p1 again
p1.X = 0;
}
}
private void pbChooseDirection_Paint_1(object sender, PaintEventArgs e)
{
using (var p = new Pen(Color.Blue, 4))
{
for (int x = 0; x < p1List.Count; x++)
{
e.Graphics.DrawLine(p, p1List[x], p2List[x]);
}
}
}

Converting C# Graph into a proper mathematical graph

Recently, I have been working on this graphing system in C#, and I am having problems with the coordinate system. As we all know, C# uses the top left corner as 0,0 coordinates. What I want to accomplish is to make 0 in the middle of the windows form.
Currently, this is what I have...
As you can see, 0,0 is on the top left, making the center of the graph 400. So is there a way to transform the coordinates into a proper mathematical graph coordinate?
I hope I was able to explain this situation well as my English is not very well.
public partial class Form1 : Form
{
public static int _wWidth;
public static int _wHeight;
int mouseX, mouseY;
Point _center = new Point(_wWidth / 2, _wHeight / 2);
public Form1()
{
InitializeComponent();
foreach (Control c in this.Controls)
{
c.MouseDown += ShowMouseDown;
}
this.MouseDown += (s, e) => { this.label3.Text = "{X: " + e.X + " Y:" + e.Y + "}"; mouseX = e.X; mouseY = e.Y; };
}
private void ShowMouseDown(object sender, MouseEventArgs e)
{
var x = e.X + ((Control)sender).Left;
var y = e.Y + ((Control)sender).Top;
this.label3.Text = x + " " + y;
}
public void Form1_Load(object sender, EventArgs e)
{
this.ClientSize = new Size(800, 800);
int windowWidth = this.ClientSize.Width;
int windowHeight = this.ClientSize.Height;
_wWidth = windowWidth;
_wHeight = windowHeight;
button1.Location = new Point(_wWidth - button1.Width,0);
//AllocConsole(); /***** Enable console for debugging *****/
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();
public void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
_drawPlain(e);
}
public void _drawPlain(PaintEventArgs e){
Graphics formGraphics = this.CreateGraphics();
for(int x = 0; x < _wHeight; x+=50)
{
e.Graphics.DrawLine(new Pen(Color.FromArgb(80, 75, 75)), new Point(0, x), new Point(_wWidth, x));
Console.ForegroundColor = ConsoleColor.Green; if (x == 20) { Console.Write("X - "); } Console.WriteLine(x);
e.Graphics.DrawString(x.ToString(), new Font("Arial", 10), new SolidBrush(Color.White), new Point(_wWidth/2,x));
}
for (int y = 0; y < _wWidth; y += 50)
{
e.Graphics.DrawLine(new Pen(Color.FromArgb(80, 75, 75)), new Point(y, 0), new Point(y, _wHeight));
Console.ForegroundColor = ConsoleColor.Red; if (y == 20) { Console.Write("Y - "); } Console.WriteLine(y);
int num = y;
e.Graphics.DrawString(num.ToString(), new Font("Arial", 10), new SolidBrush(Color.White), new Point(y, _wHeight/2));
}
e.Graphics.DrawLine(Pens.Green, new Point(0, _wHeight/2), new Point(_wWidth, _wHeight/2));
e.Graphics.DrawLine(Pens.DarkRed, new Point(_wWidth/2, 0), new Point(_wWidth/2, _wHeight));
//e.Graphics.DrawString("0", new Font("Arial", 10), new SolidBrush(Color.White), new Point(_wWidth / 2, _wHeight / 2));
//// Create pen.
//Pen blackPen = new Pen(Color.Black, 3);
//// Create points that define polygon.
//Point point1 = new Point(100, 200);
//Point point2 = new Point(300, 200);
//Point point3 = new Point(200, 50);
//Point[] curvePoints =
// {
// point1,
// point2,
// point3
// };
//// Draw polygon to screen.
//e.Graphics.DrawPolygon(blackPen, curvePoints);
}
public static int _yCellCount()
{
int _cell = 0;
for (int i = 0; i < 20; i++)
{
_cell++;
}
return _cell;
}
private void button1_Click(object sender, EventArgs e)
{
this.Refresh();
}
private void Form1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawLine(Pens.Yellow,new Point(mouseX,mouseY),new Point(_wWidth/2,400));
}
}

C# class and Graphics

Continuation of thread: C# Invalidate troubles. I created the class but now I get an Error 2 Embedded statement cannot be a declaration or labeled statement. And I am trying to create the "Car" by Car aCar = new Car(50,100); that is where I am getting the error.
Thanks for the suggestions.
class Car
{
private Pen pen1 = new Pen(Color.Blue, 2F);
private Pen pen2 = new Pen(Color.Green, 2F);
int cost = 0;
int x, y;
Graphics g;
public Car(int x, int y)
{
this.x = x;
this.y = y;
}
public void printCar()
{
g.DrawEllipse(pen1, x, y, 30, 30);
g.DrawEllipse(pen1, x + 100, y, 30, 30);
g.DrawRectangle(pen2, x - 5, y + 50, 140, 50);
g.DrawLine(pen2, x + 15, y + 50, x + 30, y + 90);
g.DrawLine(pen2, x + 30, y + 90, x + 90, y + 90);
g.DrawLine(pen2, x + 90, y + 90, x + 110, y + 50);
// Create string to draw.
String drawString = "Price: " + (cost).ToString("C");
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(50, 95);
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawPoint);
}
public partial class Form1 : Form
{
private Pen pen1 = new Pen(Color.Blue, 2F);
private Pen pen2 = new Pen(Color.Green, 2F);
private double cost ;
private int days = 0;
private double air;
private double automatic;
int count;
int m = 50;
Car aCar = new Car(50, 60);
public Form1()
{
InitializeComponent();
days = int.Parse(textBox1.Text);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem.ToString() == "Van")
{
cost = 110;
label1.Text = "The Cost of van per day" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
else if (comboBox1.SelectedItem.ToString() == "Car")
{
cost = 85.20;
label1.Text = "The Cost of car per day" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
else
{
cost = 135;
label1.Text = "Van" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
}
private void button1_Click(object sender, EventArgs e)
{
count++;
button1.Text = "Move";
pictureBox1.Invalidate();
if(count == 2)
button1.Text = "Reset";
if (count == 3)
{
textBox1.Text = "0";
count = 0;
comboBox1.Text = "select type of vehical";
checkBox1.Checked = false;
checkBox2.Checked = false;
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
if (count == 1)
aCar.printCar();
if (count == 2)
}
private void Form1_Load(object sender, EventArgs e)
{
}
The end of your picturebox1_Paint method opens an if statement but doesn't actually contain a body. That is illegal:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
if (count == 1)
aCar.printCar();
if (count == 2) // <-- This is illegal since the if statement is just dangling
}
You have to pass the Graphic object you are getting from the Paint event:
Public void printCar(Graphic g)
{
// etc, etc
}
So that when you call it:
aCar.printCar(e.Graphics);

C#: Why does this not zoom using the mouse as center?

I'm trying to make a canvas where you can zoom and pan. The panning works, but zooming at the mouse position won't work.
EDIT: This almost works. The center for zoom is slightly offset however...
This is the code for the zooming:
public partial class Form1 : Form
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1.0F;
public Form1()
{
InitializeComponent();
mouseDown = new PointF(0F, 0F);
this.panel1.Paint += new PaintEventHandler(panel1_Paint);
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = e.Graphics;
dc.SmoothingMode = SmoothingMode.AntiAlias;
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor);
Color lineColor = Color.FromArgb(200, 200, 200);
Pen linePen = new Pen(lineColor,1*zoomFactor);
dc.DrawLine(linePen, 100, 100, 200, 200);
textBox1.Text = newX.ToString();
textBox2.Text = newY.ToString();
}
private void panel1_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
mouseDown = mouse.Location;
mouseDown.X = mouseDown.X - newX;
mouseDown.Y = mouseDown.Y - newY;
}
}
private void panel1_MouseMove(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
Point mousePosNow = mouse.Location;
float deltaX = mousePosNow.X - mouseDown.X;
float deltaY = mousePosNow.Y - mouseDown.Y;
newX = deltaX;
newY = deltaY;
panel1.Invalidate();
}
}
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (e.Delta > 0)
{
if (zoomFactor + 0.2 < 10)
{
zoomFactor += 0.2F;
}
}
else if (e.Delta < 0)
{
if (zoomFactor - 0.2 > 0.2)
{
zoomFactor -= 0.2F;
}
}
float x = (mouse.Location.X - newX) * zoomFactor;
float y = (mouse.Location.Y - newY) * zoomFactor;
newX = mouse.Location.X - x;
newY = mouse.Location.Y - y;
panel1.Invalidate();
}
}
I finally figured it out, so here's the solution.
public partial class Form1 : Form
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1.0F;
public Form1()
{
InitializeComponent();
mouseDown = new PointF(0F, 0F);
this.panel1.Paint += new PaintEventHandler(panel1_Paint);
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = e.Graphics;
dc.SmoothingMode = SmoothingMode.AntiAlias;
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend);
Color lineColor = Color.FromArgb(200, 200, 200);
Pen linePen = new Pen(lineColor,1*zoomFactor);
dc.DrawLine(linePen, 100, 100, 200, 100);
dc.DrawLine(linePen, 200, 100, 200, 200);
dc.DrawLine(linePen, 200, 200, 100, 200);
dc.DrawLine(linePen, 100, 200, 100, 100);
dc.DrawLine(linePen, 100, 100, 200, 200);
dc.DrawLine(linePen, 200, 100, 100, 200);
}
private void panel1_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
mouseDown = mouse.Location;
mouseDown.X = mouseDown.X - newX;
mouseDown.Y = mouseDown.Y - newY;
}
}
private void panel1_MouseMove(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
PointF mousePosNow = mouse.Location;
float deltaX = mousePosNow.X - mouseDown.X;
float deltaY = mousePosNow.Y - mouseDown.Y;
newX = deltaX;
newY = deltaY;
panel1.Invalidate();
}
}
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
PointF mP = mouse.Location;
if (e.Delta > 0)
{
if (zoomFactor >= 1 && zoomFactor <= 10)
{
zoomFactor += 1F;
newX = newX - ((mP.X - newX) / (zoomFactor - 1));
newY = newY - ((mP.Y - newY) / (zoomFactor - 1));
}
else if (zoomFactor == 0.5)
{
zoomFactor = zoomFactor * 2;
newX = newX - ((mP.X - newX) );
newY = newY - ((mP.Y - newY) );
}
else if (zoomFactor < 0.5)
{
zoomFactor = zoomFactor * 2;
newX = newX - ((mP.X - newX) );
newY = newY - ((mP.Y - newY) );
}
}
else if (e.Delta < 0)
{
if (zoomFactor >2)
{
zoomFactor -= 1F;
newX = newX + (((mP.X - newX)) / (zoomFactor+1 ));
newY = newY + (((mP.Y - newY)) / (zoomFactor+1));
}
else if (zoomFactor == 2) {
zoomFactor -= 1F;
newX = newX + ((mP.X - newX)/2);
newY = newY + ((mP.Y - newY)/2);
}else if(zoomFactor <= 1 && zoomFactor > 0.2)
{
zoomFactor = zoomFactor / 2;
newX = newX + ((mP.X - newX) / 2);
newY = newY + ((mP.Y - newY) / 2);
}
}
panel1.Invalidate();
}
}
Maybe your MousePosition is different from PanelPosition? I mean on is relative to the control and one relative to the screen?
Control.PointToScreen is your friend!

Categories

Resources