I am trying to draw a top view of an IC package, which should look like this (sorry I couldnt even draw it good enough using windows's paint!)
I am using a path obeject, but the result of my path object is no where near what I expect. Atleast the complete rectangle itself draws fine but I have problem to make that top arc you see in my example picture. Would be nice if you can point me to the right place. Here is my code:
private GraphicsPath DrawDilBounds(Size size)
{
var p = new GraphicsPath(FillMode.Alternate);
p.StartFigure();
p.AddLine(0, 0, 0, size.Height);
p.AddLine(0, size.Height, size.Width, size.Height);
p.AddLine(size.Width, size.Height, size.Width, 0);
p.AddLine(size.Width, 0, (size.Width/2) - 10, 0);
p.AddArc(size.Width/2 - 10, 0, 10, 10, 10, 10); //This arc looks like no arc!
p.AddLine((size.Width/2) + 10, 0, 0, 0);
p.CloseFigure();
return p;
}
So what I am doing here is starting some lines from top left corner , to bottom left corner, to right bottom corner and finaly to top right corner, then I added a line from top right corner to the middle of the top , minus 10 pixels then I want to add the arc with width of 20 pixels and then finish the drawing back to the top left corner.
You specify the arc by its bounding box. Using 10 as the radius gives a box of 20 x 20 (you used 10 x 10) whose upper left corner is located at (-10, -10) from the center of the arc (you used (-10, 0)). The last two arguments must be degrees, the starting and ending angle. Since you draw it from left-to-right that will be 0 and 180 degrees (you used 10 and 10). You also fumbled the lengths of the 2 lines at the top, they should be half the width -10 (you used +10). Fix:
p.AddLine(size.Width, 0, (size.Width / 2) + 10, 0);
p.AddArc(size.Width / 2 - 10, -10, 20, 20, 0, 180);
p.AddLine((size.Width / 2) - 10, 0, 0, 0);
Which gets you:
Related
The constructor documentation states that
Rectangle(Int32, Int32, Int32, Int32) Initializes a new instance of
the Rectangle class with the specified location and size.
Where:
Parameters
x
Int32 The x-coordinate of the upper-left corner of the rectangle.
y
Int32 The y-coordinate of the upper-left corner of the rectangle.
width
Int32 The width of the rectangle.
height
Int32 The height of the rectangle.
With that in mind here's my couple of testing rectangles:
Rectangle1(25,43,11,9)
Rectangle2(35, 45, 9, 1)
As per MS documentation both x and y coordinates relate to the
upper-left corner
, that is:
Rectangles1 x coordinate goes from 25 to 36 and y goes from 43 down to 34
Rectangles2 x coordinate goes from 35 to 44 and y goes from 45 down to 44
That means they do not overlap, as Rectangle2 base (y = 44) is 1 unit above Rectangle1 top (y = 43)
As a matter of fact that conflicts with following simple test:
class Program
{
static void Main(string[] args)
{
Rectangle r1 = new Rectangle(25,43,11,9);
Rectangle r2 = new Rectangle(35, 45, 9, 1);
Rectangle r3 = new Rectangle();
r3 = Rectangle.Intersect(r1, r2);
if (!r3.IsEmpty)
{
Console.WriteLine("X = "+ r3.X);
Console.WriteLine("Y = " + r3.Y);
Console.WriteLine("Width = " + r3.Width);
Console.WriteLine("Height = " + r3.Height);
}
else
Console.WriteLine("r1 and r2 do not intersect");
Console.ReadLine();
}
}
I am quite confused now, as testing rectangles result to overlap at coordinate 35,45 for a unit. Which I can't explain.
It would seem, you are getting the y-axis wrong. R1 goes from 25, 43 to 35, 51, R2 goes from 35, 45 to 43, 45. My values are now INCLUSIVE bound, therefore it is x + width - 1 and y + height - 1. So, the intersect is exactly the pixel at 35, 45, with a size of 1x1 pixels. The calculation is therefore correct.
In the Windows Coordinate System:
The x-coordinates increase to the right; y-coordinates increase from
top to bottom.
Followed by:
For screen coordinates, the origin is the upper-left corner of the
screen.
So the upper left corner of your screen is (0, 0), and the Y values INCREASE as you go DOWN the screen from the top to the bottom.
Basically the Y-Axis has been flipped from what you're used to doing in standard math class graphing.
Here I am displaying the coordinates not only using Left and Top, but also the Right and Bottom properties:
Console.WriteLine(String.Format("r1: ({0}, {1}) --> ({2}, {3})", r1.Left.ToString(), r1.Top.ToString(), r1.Right.ToString(), r1.Bottom.ToString()));
Console.WriteLine(String.Format("r2: ({0}, {1}) --> ({2}, {3})", r2.Left.ToString(), r2.Top.ToString(), r2.Right.ToString(), r2.Bottom.ToString()));
This results in the following output:
r1: (25, 43) --> (36, 52)
r2: (35, 45) --> (44, 46)
Hopefully that helps you understand what is going on.
I've done the following, but the problem that the entire panel double borders are not getting filled correctly. The right and down line for //Inner Border is not Painted.
The target control is Panel
protected override void OnPaint(PaintEventArgs pe)
{
using (SolidBrush brush = new SolidBrush(BackColor))
pe.Graphics.FillRectangle(brush, this.Bounds);
// Inner Border
pe.Graphics.DrawRectangle(new Pen(Color.FromArgb(_InnerBorderColor.R, _InnerBorderColor.B, _InnerBorderColor.G), 1.0f), 1, 1, ClientSize.Width - 1, ClientSize.Height - 1);
using (SolidBrush brush = new SolidBrush(BackColor))
pe.Graphics.FillRectangle(brush, this.Bounds);
// Main Border
pe.Graphics.DrawRectangle(new Pen(Color.FromArgb(_BorderColor.R, _BorderColor.B, _BorderColor.G), 1.0f), 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
}
This is What I got
This is What I need
Edited
You should use this coordinates:
e.Graphics.DrawRectangle(pen1,
this.ClientRectangle.Left, this.ClientRectangle.Top,
this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);
e.Graphics.DrawRectangle(pen2,
this.ClientRectangle.Left + 1, this.ClientRectangle.Top + 1,
this.ClientRectangle.Width - 3, this.ClientRectangle.Height - 3);
Note:
For outer rectangle, you should subtract -1 from original width and height to be visible
To draw inner rectangle, you should draw from 1,1 so the width and height will be 2 point less than outer width and height and since the outer width and height are original width and height -1, so you need subtract -3 from original width and height.
You have multiple bugs. Using Bounds is wrong, that is in parent coordinates, use DisplayRectangle instead. You draw the background twice, neither is necessary, the second one overpaints the inner rectangle. You draw the inner rectangle two pixels too big. You forget to dispose the pens, you tend to get away with it but very ugly bug to diagnose when you don't. And last but not least, this should be done in OnPaintBackground so it doesn't flicker like a cheap motel.
Painting bugs are not that easy to diagnose, best way to go about it is incrementally, one piece at a time.
Corrected code looks like:
protected override void OnPaintBackground(PaintEventArgs pe) {
base.OnPaintBackground(pe);
// Inner Border
using (var pen = new Pen(_InnerBorderColor))
pe.Graphics.DrawRectangle(pen, 1, 1, ClientSize.Width - 3, ClientSize.Height - 3);
// Main Border
using (var pen = new Pen(_BorderColor))
pe.Graphics.DrawRectangle(pen, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
}
You need to subtract 2 from Client.Width/Height
pe.Graphics.DrawRectangle(new Pen(Color.FromArgb(_InnerBorderColor.R, _InnerBorderColor.B, _InnerBorderColor.G), 1.0f), 1, 1, ClientSize.Width - 2, ClientSize.Height - 2);
I would like to draw a vertical line along x=0. I've tried the code below, but instead of all the points being drawn with x=0, they are drawn with x values of 1, 2, 3, 4, 5, respectively. I am able to draw a vertical line at what appears to be any x value other than 0.
The code below also sort of works if I change the x value of any of the points to something other than 0. Is this some sort of bug with the Chart in .NET? Is there a way to draw a vertical line along x=0?
chart1.Series["Series1"].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
chart1.Series["Series1"].Points.AddXY(0, 0);
chart1.Series["Series1"].Points.AddXY(0, 2.5);
chart1.Series["Series1"].Points.AddXY(0, 5);
chart1.Series["Series1"].Points.AddXY(0, 10);
chart1.Series["Series1"].Points.AddXY(0, 20);
Chart displays incorrectly when all x values are zero
So basically i'm making healthbars for my enemies in my C# XNA game. I am getting the percentage of health left so e.g. 80/100 = 0.8 = 80% so my game knows how big to draw the green portion of the health bar. So if there is 80% hp it will draw the healthbar to 80%. The problem I am having is as soon as the health goes down from 100, the percentage automatically gets dropped to 0.0/0% and nothing is drawn. Here is my code:
//calculate the width of the green portion of healbar
//zDay.Game1.hp_top.Width = Original size of image (35px)
float size = (hp/max_hp) * zDay.Game1.hp_top.Width;
//draw percentage of health
sb.DrawString(zDay.Game1.CourierNew, (hp/max_hp).ToString(), new Vector2(50, 80), Color.Black);
//draw size of green portion
sb.DrawString(zDay.Game1.CourierNew, (size).ToString(), new Vector2(50, 50), Color.Black);
//draw green portion of health bar
Rectangle bg = new Rectangle(x - 20, y - 30, (int)size, zDay.Game1.hp_top.Height);
sb.Draw(zDay.Game1.hp_top, bg, Color.White);
Any ideas as to why this is happening?
I would guess that the issue isn't with multiplication, but division; the statement:
(hp/max_hp)
is most likely being evaluated to zero (since you're diving by int's (I assume) and the result will be between 0 and 1, or in Integer terms, 0).
Try using
((float)hp/(float)max_hp)
Instead.
I have two Point structures and I need to draw an I-Beam based on those points, where each point represents the cross-section on either side of the I-Beam. The width of the end caps should be fixed and arbitrary.
Basically I need to draw three lines. First I'll DrawLine(Point1, Point2), then I need the math to figure out how to draw the next two lines on perpendicular angles so that they are centered on Point1 and Point2.
The image below shows what I need to draw based on the center line. However, this line can be at any angle. The Point1 and Point2 that connect the line can be anywhere in a 2D space.
You can try playing around with LineCaps:
protected void DrawIBeam(Graphics g, Point fromPoint, Point toPoint)
{
using (GraphicsPath hPath = new GraphicsPath())
{
hPath.AddLine(new Point(-5, 0), new Point(5, 0));
CustomLineCap myCap = new CustomLineCap(null, hPath);
myCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
using (Pen myPen = new Pen(Color.Black, 2))
{
myPen.CustomStartCap = myCap;
myPen.CustomEndCap = myCap;
g.DrawLine(myPen, fromPoint, toPoint);
}
}
}
and call it:
DrawIBeam(e.Graphics, new Point(10, 10), new Point(60, 60));
From CustomLineCap Class
Assuming a width that's half the width of the I part of the I beam, first you find the slope of the first line you drew.
Next, you take the negative inverse of the slope, and draw a line from Point1 of length width in both directions. That's why width is half of the width you want to draw.
Finally you draw a line from Point 2 of length width in both directions.
Here's the mathematical formula for drawing a perpendicular line.