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));
}
}
Related
I set the points and when the points of the same color form a square, I draw a polygon. But when a new square is formed, the old one disappears.
can you tell me how to make sure that when drawing a new polygon, the old one does not disappear?
in the checkpoint() function, I check whether there is a square of points of the same color and return e coordinates for drawing.
public partial class Form1 : Form
{
private Class1 Class1 = new Class1();
private CellState currentPlayer = CellState.Red;
public const int SIZE = 11;
public const int Icon_Size = 30;
public Form1()
{
InitializeComponent();
}
//ставит точки
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
var p = new Point((int)Math.Round(1f * e.X / Icon_Size), (int)Math.Round(1f * e.Y / Icon_Size));
if (Class1[p] == CellState.Empty)
{
Class1.SetPoint(p, currentPlayer);
currentPlayer = Class1.Inverse(currentPlayer);
Invalidate();
}
}
//рисуем
private void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.ScaleTransform(Icon_Size, Icon_Size);
//рисуем сеточку
using (var pen = new Pen(Color.Gainsboro, 0.1f))
{
for (int x = 1; x < SIZE; x++)
e.Graphics.DrawLine(pen, x, 1, x, SIZE - 1);
for (int y = 1; y < SIZE; y++)
e.Graphics.DrawLine(pen, 1, y, SIZE - 1, y);
}
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//рисуем точки
using (var brush = new SolidBrush(Color.White))
for (int x = 1; x < Form1.SIZE; x++)
for (int y = 1; y < Form1.SIZE; y++)
{
var p = new Point(x, y);
var cell = Class1[p];
if (cell != CellState.Empty)
{
brush.Color = StateToColor(cell);
e.Graphics.FillEllipse(brush, x - 0.2f, y - 0.2f, 0.4f, 0.4f);
}
}
using (var PenP = new Pen(Color.Black, 0.1f))
using (var brush = new SolidBrush(Color.White))
{
Class1.CheckPoint();
int i = Class1.CheckPoint()[0];
int j = Class1.CheckPoint()[1];
int cp = Class1.CheckPoint()[2];
if (cp == 1)
{
PenP.Color = Color.Red;
brush.Color = Color.IndianRed;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
if (cp == 2)
{
PenP.Color = Color.Blue;
brush.Color = Color.RoyalBlue;
Point[] a = { new Point(i, j), new Point(i + 1, j), new Point(i + 1, j + 1), new Point(i, j + 1) };
e.Graphics.FillPolygon(brush, a);
e.Graphics.DrawPolygon(PenP, a);
}
}
}
//условие смены цвета под ход игрока
Color StateToColor(CellState state, byte alpha = 255)
{
var res = state == CellState.Blue ? Color.Blue : Color.Red;
return Color.FromArgb(alpha, res);
}
}
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;
}
}
}
}
In C# I have written an application where you select a box to take a screen shot of and what happens is if you are above a 0 on the X axis it doesn't take a picture. I drew a small image to show what I mean:
Red = Image will actually not be of that section
Black = Ok
My code is as follows:
#region testing
private Point start = Point.Empty;
private Point end = Point.Empty;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) != 0)
{
start.X = e.X;
start.Y = e.Y;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if (((e.Button & MouseButtons.Left) != 0) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
if (end != Point.Empty)
{
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
}
end.X = e.X;
end.Y = e.Y;
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
}
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if ((end != Point.Empty) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2),
Color.Black, FrameStyle.Dashed);
int x1 = p1.X;
int y1 = p1.Y;
int x2 = p2.X;
int y2 = p2.Y;
int x = x2 - x1;
int y = y2 - y1;
string[] xsp;
int rx = 0;
string[] ysp;
int ry = 0;
if (x.ToString().Contains("-"))
{
xsp = x.ToString().Split('-');
rx = Convert.ToInt32(xsp[1]);
}
else
{
rx = x;
}
if (y.ToString().Contains("-"))
{
ysp = y.ToString().Split('-');
ry = Convert.ToInt32(ysp[1]);
}
else
{
ry = y;
}
using (Bitmap bmpScreenCapture = new Bitmap(rx, ry, g))
{
using (Graphics gra = Graphics.FromImage(bmpScreenCapture))
{
if(x.ToString().Contains("-"))
{
gra.CopyFromScreen(x2, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if(!x.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if(y.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y2, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if (!y.ToString().Contains("-"))
{
gra.CopyFromScreen(x1, y1, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
else if (x.ToString().Contains("-") && y.ToString().Contains("-"))
{
gra.CopyFromScreen(x2, y2, 0, 0, bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
}
string filename = GenerateRandomString(20) + ".png";
bmpScreenCapture.Save(Path.GetTempPath() + "" + filename,
ImageFormat.Png);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints
(new Point(0), new Point(0)), Color.Black, FrameStyle.Dashed);
//Upload(Path.GetTempPath() + "" + filename, filename);
}
}
}
}
start = Point.Empty;
end = Point.Empty;
}
private Rectangle GetRectangleForPoints(Point beginPoint, Point endPoint)
{
int top = beginPoint.Y < endPoint.Y ? beginPoint.Y : endPoint.Y;
int bottom = beginPoint.Y > endPoint.Y ? beginPoint.Y : endPoint.Y;
int left = beginPoint.X < endPoint.X ? beginPoint.X : endPoint.X;
int right = beginPoint.X > endPoint.X ? beginPoint.X : endPoint.X;
rect = new Rectangle(left, top, (right - left), (bottom - top));
return rect;
}
#endregion
I have attempted to correct it and I have had no success. I mean the picture still shows up but it is not the right region of the screen.
I started to use a different selection method and that allowed for me to get the rectangles X and Y and Size. A lot better solution :)
Code:
#region testing
private Point start = Point.Empty;
private Point end = Point.Empty;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) != 0)
{
start.X = e.X;
start.Y = e.Y;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
//this.Invalidate();
Point p1;
Point p2;
if (((e.Button & MouseButtons.Left) != 0) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
g.Clear(this.BackColor);
p1 = PointToScreen(start);
if (end != Point.Empty)
{
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
}
end.X = e.X;
end.Y = e.Y;
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
}
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
Point p1;
Point p2;
if ((end != Point.Empty) && (start != Point.Empty))
{
using (Graphics g = this.CreateGraphics())
{
p1 = PointToScreen(start);
p2 = PointToScreen(end);
ControlPaint.DrawReversibleFrame(GetRectangleForPoints(p1, p2), Color.Black, FrameStyle.Dashed);
int x1 = p1.X;
int y1 = p1.Y;
int x2 = p2.X;
int y2 = p2.Y;
int x = x2 - x1;
int y = y2 - y1;
string[] xsp;
int rx = 0;
string[] ysp;
int ry = 0;
if (x.ToString().Contains("-"))
{
xsp = x.ToString().Split('-');
rx = Convert.ToInt32(xsp[1]);
}
else
{
rx = x;
}
if (y.ToString().Contains("-"))
{
ysp = y.ToString().Split('-');
ry = Convert.ToInt32(ysp[1]);
}
else
{
ry = y;
}
using (Bitmap bmpScreenCapture = new Bitmap(rect.Width, rect.Height, g))
{
using (Graphics gra = Graphics.FromImage(bmpScreenCapture))
{
gra.CopyFromScreen(rect.X, rect.Y, 0, 0, bmpScreenCapture.Size, CopyPixelOperation.SourceCopy);
string filename = GenerateRandomString(20) + ".png";
bmpScreenCapture.Save(Path.GetTempPath() + "" + filename, ImageFormat.Png);
g.Clear(this.BackColor);
//Upload(Path.GetTempPath() + "" + filename, filename);
}
}
}
}
start = Point.Empty;
end = Point.Empty;
}
private Rectangle GetRectangleForPoints(Point beginPoint, Point endPoint)
{
int top = beginPoint.Y < endPoint.Y ? beginPoint.Y : endPoint.Y;
int bottom = beginPoint.Y > endPoint.Y ? beginPoint.Y : endPoint.Y;
int left = beginPoint.X < endPoint.X ? beginPoint.X : endPoint.X;
int right = beginPoint.X > endPoint.X ? beginPoint.X : endPoint.X;
rect = new Rectangle(left, top, (right - left), (bottom - top));
return rect;
}
#endregion
The program has a ball, bat and rectangle. I have managed to get the ball to correctly collide with the bat, that's fine. The problem is with the rectangle.
With the rectangle from what I have attempted so far it does detect collisions from the top side and left side, but I am struggling to get the same affect with the bottom and right side.
Any pointers as to where I am going wrong I would much appreciate. I have included code below for clarity. Also, when the ball does collide correctly, it rebounds towards the top left.
Graphics paper;
SolidBrush brush;
private Random randomNum;
Rectangle ball, bat, brick;
int x, y, yChange, xChange, batX;
public Form1()
{
InitializeComponent();
paper = picBox.CreateGraphics();
randomNum = new Random();
bat = new Rectangle();
brick = new Rectangle();
}
private void MoveBall()
{
timer1.Interval = randomNum.Next(80, 200);
timer1.Enabled = true;
x = x + xChange;
y = y + yChange;
if (x >= picBox.Width)
xChange = -xChange;
if (y >= picBox.Height)
yChange = -yChange;
if (x <= 0)
xChange = -xChange;
if (y <= 0)
yChange = -yChange;
}
private void DrawBall()
{
brush = new SolidBrush(Color.Red);
ball = new Rectangle(x, y, 14, 14);
paper.FillEllipse(brush, ball);
}
private void DrawBat()
{
int batXpos, batYpos;
batXpos = batX - 25; batYpos = picBox.Height - 40;
bat = new Rectangle(batXpos, batYpos, 100, 20);
brush = new SolidBrush(Color.Green);
paper.FillRectangle(brush, bat);
}
private void DrawBricks()
{
brick = new Rectangle(200, 100, 100, 50);
brush = new SolidBrush(Color.Pink);
paper.FillRectangle(brush, brick);
}
private void CheckCollision()
{
int ballTop, ballRight, ballDown, ballLeft;
ballTop = ball.Y + 7; ballDown = ball.Y + 14 + (ball.X + 7); //THESE WERE JUST SOME ATTEMPTS TO GET
ballRight = ball.X + 14 + (ball.Y + 7); ballLeft = ball.Y + 7; //LOCATION OF THE BALL AND BRICK X AND Y
//COORDS BUT STILL HAD PROBLEMS
int brickTL, brickTR, brickBL, brickBR;
brickTL = brick.X; brickTR = brick.X + 100;
brickBL = brick.Y + 50; brickBR = brick.X + 100 + (brick.Y + 50);
if (ball.IntersectsWith(bat)) //NO PROBLEMS HERE
{
yChange = -10;
}
if (ball.IntersectsWith(brick)) //WORKS FINE FOR DETECTION ON THE TOP SIDE
{
xChange = -5;
}
if (ball.IntersectsWith(brick)) //WORKS FINE FOR THE RIGHT SIDE
{
yChange = -5;
}
if ((ballTop >= brickBR) && (x < picBox.Width))
{
yChange = 5;
}
}
private void btnStart_Click(object sender, EventArgs e)
{
timer1.Interval = randomNum.Next(80, 200);
timer1.Enabled = true;
x = randomNum.Next(5, picBox.Width);
y = randomNum.Next(5, picBox.Height);
xChange = randomNum.Next(5, 15);
yChange = randomNum.Next(5, 15);
}
private void timer1_Tick(object sender, EventArgs e)
{
paper.Clear(Color.Gray);
DrawBall();
MoveBall();
DrawBat();
CheckCollision();
DrawBricks();
}
private void picBox_MouseMove(object sender, MouseEventArgs e)
{
batX = e.X;
}
I imagine your conditionals are getting hit just fine.. but you are not actually affecting the ball movement.
When the ball is moving up it will have a negative delta, and when moving left will also have a negative delta.
When a collision is detected you need to reverse the sign of the delta.. like:
xChange *= -1; and yChange *= -1;
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);