I think its my maths that's letting me down!
I'm trying to draw a line of x length at Y degrees on a picturebox control with a North South East west, lines.
the below works but draws the line line at 250 degrees not 290!?
Bitmap bmp = new Bitmap(400, 400);
Graphics g = Graphics.FromImage(bmp);
// smooth graphics
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawLine(new Pen(Color.Black, 2), 205, 20, 205, 385);
g.DrawLine(new Pen(Color.Red, 2), 20, 205, 390, 205);
// let's draw a coordinate equivalent to (20,30) (20 up, 30 across)
g.DrawString("N", new Font("Calibri", 12 , FontStyle.Bold), new SolidBrush(Color.Black), 197, 0);
g.DrawString("S", new Font("Calibri", 12, FontStyle.Bold), new SolidBrush(Color.Black), 197, 385);
g.DrawString("W", new Font("Calibri", 12, FontStyle.Bold), new SolidBrush(Color.Black), 0, 195);
g.DrawString("E", new Font("Calibri", 12, FontStyle.Bold), new SolidBrush(Color.Black), 390, 195);
//Draw Wind line
int x = 205, y = 205;
int wSpeed = 30*3; //length of line
int angle = 290; //angle to draw line at.
int startX = x;
int startY = y;
int endX = Convert.ToInt32(Math.Round(x + wSpeed * Math.Sin(Calcs.Radians(angle))));
int endY = Convert.ToInt32(Math.Round(y + wSpeed * Math.Cos(Calcs.Radians(angle))));
g.DrawLine(new Pen(Color.Blue, 2), startX, startY, endX, endY);
PictureBox display = pictureBox1;
this.Controls.Add(display);
display.Image = bmp;
public static double Radians(double dDegrees)
{
double result = Math.PI * dDegrees / 180.0;
return result;
}
If you look at the results: its -20 degrees from 270, instead of +20 expected, meaning you v got correct Y but wrong X. I suggest check(change) the sign of X coord. Graphics is very often trial-error unless you are expert.
int endX = Convert.ToInt32(Math.Round(x - wSpeed * Math.Sin(Calcs.Radians(angle))));
Related
i am trying to develop a win form for chatting purpose. I am developing Chat bubbles using pure inbuilt functions of .Net Framework, No fancy UI, No third party libraries.
Now let's have a look on how every thing is being done.
My following function is responsible for generating a Panel dynamically for each chat message received, the Pain event is used to draw rounded rectangle and color is transparent. A picture box is used to show static avatar.
private void SetRemoteMessage(string msg)
{
PictureBox pb = new PictureBox();
pb.Bounds = new Rectangle(0, 0, 72, 72);
pb.Image = Base64ToImage(avatar_his);
Panel p = new Panel();
Label lb = new Label();
lb.BackColor = Color.Transparent;
lb.ForeColor = Color.Blue;
lb.Text = msg;
lb.Font = new Font("Arial", 14, FontStyle.Bold, GraphicsUnit.Point);
p.Bounds = new Rectangle(rX, rY, (Width / 2) - 25, pb.Height);
p.BackColor = Color.Transparent;
lb.Size = new Size(p.Width - pb.Width, p.Height);
lb.Paint += _control_Paint;
lb.Location = new Point(pb.Width + 5, 0);
p.Controls.Add(pb);
p.Controls.Add(lb);
SetPanel(p);
rY += p.Height + 20;
mY += p.Height + 20;
}
following is the Paint event binded to the parent "Container" Panel so that a simple rounded rectangle is shown for each bubble
private void _control_Paint(object sender, PaintEventArgs e)
{
Control c = (Control)sender;
if(!c.Name.Equals("lb"))
{
Graphics v = e.Graphics;
DrawRoundRect(v, Pens.Blue, e.ClipRectangle.Left, e.ClipRectangle.Top, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1, 10);
}
else
{
using (Font font1 = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point))
{
e.Graphics.DrawString(c.Text, font1, Brushes.Blue, c.Bounds);
}
}
base.OnPaint(e);
}
and the following function to actually generate rounded rectangles
private void DrawRoundRect(Graphics g, Pen p, float X, float Y, float width, float height, float radius)
{
GraphicsPath gp = new GraphicsPath();
gp.AddLine(X + radius, Y, X + width - (radius * 2), Y);
gp.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);
gp.AddLine(X + width, Y + radius, X + width, Y + height - (radius * 2));
gp.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
gp.AddLine(X + width - (radius * 2), Y + height, X + radius, Y + height);
gp.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
gp.AddLine(X, Y + height - (radius * 2), X, Y + radius);
gp.AddArc(X, Y, radius * 2, radius * 2, 180, 90);
gp.CloseFigure();
g.DrawPath(p, gp);
}
The chat message is not wrapped automatically so to wrap it, the Pain method is used as it can be seen in Paint event . .the output is good as expected instead of one thing
The Problem can be seen easily the Panel height is not increasing according when a large message is given to display in bubble.
What i tried already is
Measuring string length with Graphics class, but i was not able to implement it with success
Enabling Scrollbars, Yes this approach worked but i am not interested to use this behavior
Counting string length and increasing height, This works but not efficient, specially when form is resized all calculations of measurement then become invalid.
I need to draw a rectangle that should be around the size 2X2 Inches when printed on a paper.
I know that i can draw a rectangle using
g.DrawRectangle(pen, 100,100, 100, 200);
This application will only be used in computers.How can i convert the inches to pixels properly so that i can get the desired dimensions when printed.
To make an image print in the right size by default, it needs to have the right combination of dpi and pixels.
Let's look at an example:
// aiming at 150dpi and 4x6 inches:
float dpi = 150;
float width = 4;
float height = 6;
using (Bitmap bmp = new Bitmap((int)(dpi * width), (int)(dpi * height)))
{
// first set the resolution
bmp.SetResolution(dpi, dpi);
// then create a suitable Graphics object:
using (Graphics G = Graphics.FromImage(bmp))
using (Pen pen = new Pen(Color.Orange))
{
pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
G.Clear(Color.FloralWhite);
// using pixels here:
Size sz = new System.Drawing.Size((int)dpi * 2 - 1, (int)dpi * 2 - 1);
G.DrawRectangle(pen, new Rectangle(new Point(0, 0), sz));
G.DrawRectangle(pen, new Rectangle(new Point(0, 300), sz));
G.DrawRectangle(pen, new Rectangle(new Point(0, 600), sz));
G.DrawRectangle(pen, new Rectangle(new Point(300, 0), sz));
G.DrawRectangle(pen, new Rectangle(new Point(300, 300), sz));
G.DrawRectangle(pen, new Rectangle(new Point(300, 600), sz));
// alternative code:
// we can also set the Graphics object to measure stuff in inches;
G.PageUnit = GraphicsUnit.Inch;
// or fractions of it, let's use 10th:
G.PageScale = 0.1f;
using (Pen pen2 = new Pen(Color.MediumPurple, 1f / dpi * G.PageScale))
{
// draw one rectangle offset by an inch:
G.DrawRectangle(pen2, 10f, 10f, 20f, 20f);
}
bmp.Save(#"D:\xxx.jpg", ImageFormat.Jpeg);
}
}
Note that I had to subtract 1 pixel from the drawn size as DrawRectangle overdraws by 1 pixel!
Note that the coordinates I draw at depend on the resolution! Also note how the jpeg format creates a lot of smeared colors. Pngcreates crisper results, especially once you print text..
Also note how I had to scale down the PenWidth in the alternative code!
I'm using the method posted here
Using a matrix to rotate rectangles individually
(I hope this is not a repost, if it is maybe i'm doing something wrong)
I'm using the perfectly defined RotateRectangle method as follows
public void RotateRectangle(Graphics g, Rectangle r, float angle)
{
using (Matrix m = new Matrix())
{
m.RotateAt(angle, new PointF(r.Left + (r.Width / 2),
r.Top + (r.Height / 2)));
g.Transform = m;
g.DrawRectangle(Pens.Black, r);
g.ResetTransform();
}
}
And then on my drawing i create a label, and a rectangle outside of it
g.DrawString("e/10", fnt2, new SolidBrush(Color.Black), (int)(ecobdesenho / 10) / 2 + esp - 15, esp - 25); //15 para tras, 15 para cima
Rectangle r1 = new Rectangle((int)(ecobdesenho / 10) / 2 + esp - 15, esp - 25, 25, 12);
RotateRectangle(g, r1, 40);
(Notice the rectangle in top left corner)
Am I missing something? Or should I go eat bananas?
Your RotateRectangle is not rotating a rectangle of canvas; it's drawing a rotated rectangle.
Everything that's drawn between setting the Transform and the ResetTransform will be drawn rotated.
Therefore, if you want the DrawString to be rotated, you need to put it after you set the Transform, and before you reset it.
using (Matrix m = new Matrix())
{
m.RotateAt(angle, new PointF(r.Left + (r.Width / 2),
r.Top + (r.Height / 2)));
g.Transform = m;
g.DrawString("e/10", fnt2, new SolidBrush(Color.Black), (int)(ecobdesenho / 10) / 2 + esp - 15, esp - 25); //15 para tras, 15 para cima
g.DrawRectangle(Pens.Black, r);
g.ResetTransform();
}
heyho folks,
could you please help me to draw a circle in the middle of the desktop.
i am very frustrated about the desktop coordinates.
this is for an overlay
here is my code:
Graphics g = default(Graphics);
g = pictureBox1.CreateGraphics();
//g.DrawEllipse(Pens.Red, 10, 10, 200, 200);
int screenmiddlx = this.Width / 2;
int screenmiddly = this.Height / 2;
int kscreenmoddly = Height;
int kscreenmoddlx = Width;
g.DrawLine(Pens.Red, screenmiddlx - 10, screenmiddly, screenmiddlx + 10, screenmiddly);
g.DrawLine(Pens.Red, screenmiddlx, screenmiddly - 10, screenmiddlx, screenmiddly + 10);
g.DrawEllipse(Pens.Red,,,,);
this is my code:
Graphics kp = e.Graphics;
kp.DrawEllipse(Pen, x, y, width, height);
// exemple for you:
kp.DrawEllipse(Pens.Red, screenmiddlx, screenmiddly, 20, 20);
I'm facing a problem with DataGridView component.
I know that DataGridView component cannot merge cells!
Is there any way to merge two cells from two rows as tha above example ?
**************************
* First Name | Last Name *
* ---------- |---------- *
* | David *
* Smith |---------- *
* | Anna *
*------------|---------- *
* Michael | Daniel *
**************************
etc.
Please try to do like this,
this.Paint += new PaintEventHandler(dataGridView1_Click); //Call event while loading
private void dataGridView1_Click(object sender, PaintEventArgs e)
{
Font fnt = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point);
Rectangle rct1 = new Rectangle((dataGridView1.GetColumnDisplayRectangle(0, true).X), (dataGridView1.GetColumnDisplayRectangle(0, true).Y + dataGridView1.Columns[0].HeaderCell.ContentBounds.Height + 8), dataGridView1.GetColumnDisplayRectangle(0, true).Width - 1, (dataGridView1.GetRowDisplayRectangle((dataGridView1.Rows.Count - 1), true).Top - dataGridView1.GetRowDisplayRectangle((dataGridView1.Rows.Count - 1), true).Height));
// Create string to draw.
String drawString = "Sample Text";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
float x = 150.0F;
float y = 50.0F;
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;
// Draw string to screen.
e.Graphics.FillRectangle(Brushes.White, rct1);
e.Graphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);
Rectangle rct =new Rectangle();
rct = dataGridView1.GetRowDisplayRectangle(3, true)
rct.Height -= 1;
SizeF s =new SizeF();
s= e.Graphics.MeasureString("HORINZONTAL TEXT", dataGridView1.Font);
float lefts = (rct.Width / 2) - (s.Width / 2);
float tops = rct.Top + ((rct.Height / 2) - (s.Height / 2));
e.Graphics.FillRectangle(Brushes.White, rct);
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops);
}