How to convert an Array of Point to a Rectangle - c#

I have an Array of Point and I want to make it a Rectangle.
There are 4 points. I draw these points as a Polygon and the output is a Rectangle.
How can I draw these four points as a Rectangle?
Meaning, I want to get the width and height of these points.
These are my four points:
p1 :48.5, 196.5
p2 :997.5, 196.5
p2 :997.5, 692.5
p2 :48.5, 692.5
So I want something like this:
RectangleF rec = new RectangleF(x, y, width, hight);
My x and y is p1.x , p1.y
How can I get the width and height from these points?
RectangleF rec = new RectangleF(p1.x, p1.y, width, hight);

Assuming that:
Point p1 = new Point(48.5, 196.5);
Point p2 = new Point(997.5, 196.5);
Point p3 = new Point(997.5, 692.5);
Point p4 = new Point(48.5, 692.5);
You can create Rectangle as follow:
RectangleF rec = new RectangleF(p1.X, p1.Y, p2.X - p1.X, p3.Y - p1.Y);

Alternative solution using GraphicsPath()
using (GraphicsPath path = new GraphicsPath())
{
PointF[] points = new PointF[] {
new PointF(48.5f, 196.5f),
new PointF(997.5f, 196.5f),
new PointF(997.5f, 692.5f),
new PointF(48.5f, 692.5f),
};
path.StartFigure();
path.AddPolygon(points);
path.CloseFigure();
e.Graphics.DrawPath(new Pen(Color.Black, 2), path);
};

Related

How to get Bounds of New Region made with PointsF?

I am trying some simple collisions like this:
if (Object1.bounds.intersectWith(Object2.bounds){ }
Now I am defining a new region for each object using pointsf like this :
using (GraphicsPath gp = new GraphicsPath())
{
// Create points that define polygon.
PointF point1 = new PointF(this.Width/2, 0);
PointF point2 = new PointF(this.Width, this.Height/2);
PointF point3 = new PointF(this.Width / 2, this.Height);
PointF point4 = new PointF(0, this.Height/2);
PointF[] curvePoints =
{
point1,
point2,
point3,
point4,
};
gp.AddLines(curvePoints.ToArray());
this.Region = new Region(gp);
}
But, the intersectionWith statement is only detecting the rectangle bounds. I try a code similar to this but its not working, how can I get the new region boundaries (triangle) in order to make it work?
if (Object1.region.Bounds.IntersectsWith(Object2.region.Bounds))
(This doesn't work obviously);
Thanks in advance

Centering rotated graphicPath using the Matrix object in C#

I am writing a library that will create a graphihc path (In the shape of a polygon or rectangle) and rotate it but I want the rotated shape to be centered within its bounding rectangle. I have tried almost everything to get the shape to rotate on its center but it cutting off at the edges.
Below is some smaple code I have written to try to accomplish this
GraphicsPath path = new GraphicsPath();
path.AddPolygon(new Point[] { new Point(0, 0), new Point(100, 0), new Point(100, 100), new Point(0, 100) });
Matrix m = new Matrix();
Matrix m2 = new Matrix();
m2.Rotate(30);
m.Translate(-((path.GetBounds(m2).Width) / 2), -((path.GetBounds(m2).Height) / 2));
m.Rotate(30, MatrixOrder.Append);
m.Translate(((path.GetBounds(m2).Width)/2), ((path.GetBounds(m2).Height)/2), MatrixOrder.Append);
path.Transform(m);
Bitmap b = new Bitmap((int)path.GetBounds().Width, (int)path.GetBounds().Height);
Graphics g = Graphics.FromImage(b);
g.FillPath(Brushes.Blue, path);
b.Save(#"c:\aSSETS\sample3.png");
Please help. Thanks

Drawing a polygon according to the input coordinates

How can i draw a polygon according to the input coordinates which are given in C#.
You didn't show any code because based on those coordinate, you are applying some form of scaling to the image.
Using the Paint event of a PictureBox, here is an example using those coordinates on the screen. It fills in the polygon, then draws the border, then it loops through all the points to draw the red circle:
void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(Color.White);
// draw the shading background:
List<Point> shadePoints = new List<Point>();
shadePoints.Add(new Point(0, pictureBox1.ClientSize.Height));
shadePoints.Add(new Point(pictureBox1.ClientSize.Width, 0));
shadePoints.Add(new Point(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height));
e.Graphics.FillPolygon(Brushes.LightGray, shadePoints.ToArray());
// scale the drawing larger:
using (Matrix m = new Matrix()) {
m.Scale(4, 4);
e.Graphics.Transform = m;
List<Point> polyPoints = new List<Point>();
polyPoints.Add(new Point(10, 10));
polyPoints.Add(new Point(12, 35));
polyPoints.Add(new Point(22, 35));
polyPoints.Add(new Point(24, 22));
// use a semi-transparent background brush:
using (SolidBrush br = new SolidBrush(Color.FromArgb(100, Color.Yellow))) {
e.Graphics.FillPolygon(br, polyPoints.ToArray());
}
e.Graphics.DrawPolygon(Pens.DarkBlue, polyPoints.ToArray());
foreach (Point p in polyPoints) {
e.Graphics.FillEllipse(Brushes.Red,
new Rectangle(p.X - 2, p.Y - 2, 4, 4));
}
}
}
You may use Graphics.DrawPolygon. You can store the coordinates in an array of Point and then you can pass that to DrawPolygon method. You may wanna see:
Drawing with Graphics in WinForms using C#
private System.Drawing.Graphics g;
System.Drawing.Point[] p = new System.Drawing.Point[6];
p[0].X = 0;
p[0].Y = 0;
p[1].X = 53;
p[1].Y = 111;
p[2].X = 114;
p[2].Y = 86;
p[3].X = 34;
p[3].Y = 34;
p[4].X = 165;
p[4].Y = 7;
g = PictureBox1.CreateGraphics();
g.DrawPolygon(pen1, p);
This simple function is able to generate an array of PointF equal to the vertices of the regular polygon to be drawn, where "center" is the center of the polygon, "sides" is its number of sides, "sideLength" is the size of each side in pixels and "offset" is its slope.
public PointF[] GetRegularPolygonScreenVertex(Point center, int sides, int sideLength, float offset)
{
var points = new PointF[sides];
for (int i = 0; i < sides; i++)
{
points[i] = new PointF(
(float)(center.X + sideLength * Math.Cos((i * 360 / sides + offset) * Math.PI / 180f)),
(float)(center.Y + sideLength * Math.Sin((i * 360 / sides + offset) * Math.PI / 180f))
);
}
return points;
}
The result obtained can be used to draw a polygon, e.g. with the function:
GraphicsObject.DrawPolygon(new Pen(Brushes.Black, GetRegularPolygonScreenVertex(new Point(X, Y), 6, 30, 60f));
Which will generate a regular hexagon with a side of 30 pixels inclined by 30°.
hex

Filling Color in a hexagon in WPF

I'm having problem in filling the hexagon using this code, when this code runs it draws only the outline of the hexagon that is "White", I want to fill the hexagon with a color but it is not working.
I have searched a lot and tried many things like drawingContext.Drawing() , drawingBrush, etc.
Am I missing something in this code? This is the code:
public void DrawHexagon(DrawingContext drawingContext)
{
GeometryGroup hexaKey = new GeometryGroup();
//making lines for hexagon
hexaKey.Children.Add(
new LineGeometry(new Point(X1, Y1), new Point(X2, Y2)));
hexaKey.Children.Add(
new LineGeometry(new Point(X2, Y2), new Point(X3, Y3)));
hexaKey.Children.Add(
new LineGeometry(new Point(X3, Y3), new Point(X4, Y4)));
hexaKey.Children.Add(
new LineGeometry(new Point(X4, Y4), new Point(X5, Y5)));
hexaKey.Children.Add(
new LineGeometry(new Point(X5, Y5), new Point(X6, Y6)));
hexaKey.Children.Add(
new LineGeometry(new Point(X6, Y6), new Point(X1, Y1)));
//
// Create a GeometryDrawing.
//
GeometryDrawing hexaKeyDrawing = new GeometryDrawing();
hexaKeyDrawing.Geometry = hexaKey;
// Paint the drawing with a gradient.
hexaKeyDrawing.Brush =new SolidColorBrush(Colors.Red);
// Outline the drawing with a solid color.
hexaKeyDrawing.Pen = new Pen(Brushes.White, 2);
drawingContext.DrawGeometry(hexaKeyDrawing.Brush, hexaKeyDrawing.Pen, hexaKeyDrawing.Geometry);
}
LineGeometry doesn't have a way to fill... they're just lines. You need a path. The MSDN has an example
An example, how to fill hexagons: http://www.codeproject.com/Articles/14948/Hexagonal-grid-for-games-and-other-projects-Part-1
In your example you have a number of LineGeometry instances inside a GeometryGroup inside a GeometryDrawing.
First, I'd link to bring to your attention that you're not actually using the GeometryDrawing. In your example you've used it solely as a place holder for your GemetryGroup.
Ignoring this the problem is that LineGeometry instances were not intended to draw shapes and GeometryGroup is not able to realize that your 6 LineSegments together form a closed shape.
Despair not however as there is a way to accomplish what you want: PathGeometry. This geometry essentially defines the contour of a region that may be filled! This contour may is defined by a starting point and a series of PathSegments.
private Point GetExtremity(Point center, double radius, double orientation)
{
return new Point(
center.X + Math.Cos(orientation) * radius,
center.Y + Math.Sin(orientation) * radius
);
}
public void DrawUniformShape(DrawingContext context, Brush brush, Pen pen, Point center, double radius, int sides, double orientationRadians)
{
context.DrawGeometry(
brush,
pen,
new PathGeometry(
Enumerable.Repeat(
new PathFigure(
GetExtremity(center, radius, orientationRadians),
from vertex in Enumerable.Range(1, sides - 1)
let angle = orientationRadians + vertex * 2 * Math.PI / sides
select new LineSegment(GetExtremity(center, radius, angle), true),
true
),
1
)
)
);
}
public void DrawBarnColouredHexagon(DrawingContext context, Point center, double radius, double orientation)
{
DrawUniformShape(
context,
Brushes.Red,
new Pen(Brushes.White, 2),
center,
radius,
6,
0
);
}

c# can you get position from axis without having a form?

I have a WinForm application that I would like to convert to a service. It has two mscharts on it. I don't need to see those charts anymore because the application creates bitmaps out of them. I am drawing a line on one chart depending on data from another chart, like this:
// Get Graphics object from chart
Graphics graph = e.ChartGraphics.Graphics;
// Convert X and Y values to screen position
float pixelYMax = (float)e.ChartGraphics.GetPositionFromAxis("Default", AxisName.Y, CreatininePoint.YValues[0]);
float pixelXMax = (float)e.ChartGraphics.GetPositionFromAxis("Default", AxisName.X, CreatininePoint.XValue);
float pixelYMin = (float)e.ChartGraphics.GetPositionFromAxis("Default", AxisName.Y, CreatininePoint.YValues[0]-20);
float pixelXMin = (float)e.ChartGraphics.GetPositionFromAxis("Default", AxisName.X, CreatininePoint.XValue);
PointF point1 = PointF.Empty;
PointF point2 = PointF.Empty;
// Set Maximum and minimum points
point1.X = pixelXMax;
point1.Y = pixelYMax-10;
point2.X = pixelXMin;
point2.Y = 84;
// Convert relative coordinates to absolute coordinates.
point1 = e.ChartGraphics.GetAbsolutePoint(point1);
point2 = e.ChartGraphics.GetAbsolutePoint(point2);
float[] dashValues = { 4,2 };
Pen blackPen = new Pen(Color.Black, 1);
blackPen.DashPattern = dashValues;
//e.Graphics.DrawLine(blackPen, new Point(5, 5), new Point(405, 5));
//graph.DrawLine(blackPen, point1, point2);
// Draw connection line
graph.DrawLine(new Pen(Color.Black, 2), point2, point1);
// Create string to draw.
//String drawString = creatininept + " ng/mL";
String drawString = "67 ng/mL";
// Create font and brush.
Font drawFont = new Font("Arial", 7);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(point1.X,point1.Y+5);
// Draw string to screen.
graph.DrawString(drawString, drawFont, drawBrush, drawPoint);
is it possible to do this without having a form so that we can have a service running?
Bitmap canvas = new Bitmap(600, 480);
Graphics graph = Graphics.FromImage(canvas);
.. then proceed with drawing on graph.

Categories

Resources