System.Drawing.Graphics - c#

I have one problem relating to rotate ellipse by given Center,
Suppose I have one ellipse and what should be is to rotate that ellipse by point given by user and ellipse should be rotate around that given point.
I have tried
g.RotateTransform(…)
g.TranslateTransform(…)
Code:
Graphics g = this.GetGraphics();
g.RotateTransform((float)degreeArg); //degree to rotate object
g.DrawEllipse(Pens.Red, 300, 300, 100, 200);
this works fine but how can we give our out center to rotate ellipse....
How could it be possible please any buddy can suggest……
Thanks…….

RotateTransform always rotates about the origin. So you need to first translate your centre of rotation to the origin, then rotate, then translate it back.
Something like this:
Graphics g = this.GetGraphics();
g.TranslateTransform(300,300);
g.RotateTransform((float)degreeArg); //degree to rotate object
g.TranslateTransform(-300,-300);
g.DrawEllipse(Pens.Red, 300, 300, 100, 200);

//center of the rotation
PointF center = new PointF(...);
//angle in degrees
float angle = 45.0f;
//use a rotation matrix
using (Matrix rotate = new Matrix())
{
//used to restore g.Transform previous state
GraphicsContainer container = g.BeginContainer();
//create the rotation matrix
rotate.RotateAt(angle, center);
//add it to g.Transform
g.Transform = rotate;
//draw what you want
...
//restore g.Transform state
g.EndContainer(container);
}

Related

how to draw polygon including negative points ? in C#

i am doing c# project. i have found a problem and unable to find answer of this problem that's why i am posting here/
i am implementing procedural floor plan generation in c#. at first i need to draw a polygon to on given points to generate grid. points can be positive or negative. points will be in floating.
From the Microsoft Documentation i am able to draw polygon for the floating positive points, but when i change points to negative it does not draw anything on form.
this method id drawing x,y coordinates 0,0 in the corner .
code example
public void DrawPolygonPointF(PaintEventArgs e)
{
// Create pen.
Pen blackPen = new Pen(Color.Black, 3);
// Create points that define polygon.
PointF point1 = new PointF(50.0F, 50.0F);
PointF point2 = new PointF(100.0F, 25.0F);
PointF point3 = new PointF(200.0F, 5.0F);
PointF point4 = new PointF(250.0F, 50.0F);
PointF point5 = new PointF(300.0F, 100.0F);
PointF point6 = new PointF(350.0F, 200.0F);
PointF point7 = new PointF(250.0F, 250.0F);
PointF[] curvePoints =
{
point1,
point2,
point3,
point4,
point5,
point6,
point7
};
// Draw polygon curve to screen.
e.Graphics.DrawPolygon(blackPen, curvePoints);
}
i have negative coordinates value for example pointF(300,-250) this method is not drawing nothing for negative coordinates value.
So please give me brief solution because i don't know much about drawing.
Thank you
In C# 0,0 is the top left corner of the screen. So negative values are off the left or top edge of your form. You need to transform your coordinates from your coordinate space to the form's. To place 0,0 dead center, you would do this:
int screenX = myX + windowWidth / 2;
int screenY = myY + windowHeight / 2;
Building off of the answer #pquest gave, and your newly added sample code, doing a "real" GDI transformation would look like this:
// Create pen.
Pen blackPen = new Pen(Color.Black, 3);
// Create points that define polygon.
PointF point1 = new PointF(50.0F, 50.0F);
PointF point2 = new PointF(100.0F, 25.0F);
PointF point3 = new PointF(200.0F, 5.0F);
<...snip...>
//Apply a translation Transformation to move 0,0 to the center of the
//window. You can now draw your points with negative values, without doing
//any addition to them.
int screenX = windowWidth / 2;
int screenY = windowHeight / 2;
e.Graphics.TranslateTransform((float) screenX, (float) screenY);
// Draw polygon curve to screen.
e.Graphics.DrawPolygon(blackPen, curvePoints);
GDI Transformations are very powerful. You can use them to move points around, flip points horizontally or vertically, scale things bigger or smaller, distort like a parallelogram, and even do rotations. All of these can be combined in to what is called a transformation matrix to get some very cool results.
More examples can be found on MSDN.
That's working for me to this problem.
you just need to add couple lines of code in your code.
int windowWidth = this.ClientSize.Width;
int windowHeight = this.ClientSize.Height;
int screenX = windowWidth / 2;
int screenY = windowHeight / 2;
e.Graphics.TranslateTransform((float)screenX, (float)screenY);

Draw custom ellipse in winform

In System.Drawing and System.Drawing.Drawing2D, I can only draw horizontal or vertical shape. Now i want to draw custom shape.
Given the coordinate of points A, B, C, D. I want to draw an ellipse like the blue one in the picture.
The example below is taken from MSDN:
private void RotateTransformAngle(PaintEventArgs e)
{
// Set world transform of graphics object to translate.
e.Graphics.TranslateTransform(100.0F, 0.0F);
// Then to rotate, prepending rotation matrix.
e.Graphics.RotateTransform(30.0F);
// Draw rotated, translated ellipse to screen.
e.Graphics.DrawEllipse(new Pen(Color.Blue, 3), 0, 0, 200, 80);
}
The correct solution involves:
Calculating the center
using Graphics.TranslateTransform to move the center to the origin
Calculating the Size and the Location of the bounding Rectangle
using Graphics.RotateTransform to rotate the canvas
Drawing the ellipse with Graphics.DrawEllipse
Resetting the Graphcis object
This does take a little Math but will produce real and fine ellipses..
For fun you also may want to play with a cheap, fake solution: I uses the DrawClosedCurve method with a tension.
To test I added a TrackBar set with a Maximum of 100.
Values of around 80, i.e. Tensions of around 0.8f create pretty nice ellipsoids:
private void panel1_Paint(object sender, PaintEventArgs e)
{
List<Point> points1 = new List<Point>()
{ new Point(300, 100), new Point(500, 300), new Point(400, 500), new Point(200, 300) };
List<Point> points2 = new List<Point>()
{ new Point(100, 100), new Point(500, 100), new Point(500, 400), new Point(100, 400) };
e.Graphics.DrawClosedCurve(Pens.Red, points1.ToArray(),
(float)(trackBar1.Value / 100f), System.Drawing.Drawing2D.FillMode.Alternate);
e.Graphics.DrawClosedCurve(Pens.Blue, points2.ToArray(),
(float)(trackBar1.Value / 100f), System.Drawing.Drawing2D.FillMode.Alternate);
}

c# - Rotating and centering an image

I have an image, which I want to rotate clockwise by a specified number of degrees. I don't want to cut anything off, so I calculate the width and height of the new image based on the specified rotation (a rotation of 45 degrees for example requires a taller and wider image.
//Calculate required size of new image
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new RectangleF(0f, 0f, bmpSource.Width, bmpSource.Height));
Matrix matrix = new Matrix();
matrix.Rotate(iRotationDegrees);
RectangleF rctNewSize = path.GetBounds(matrix);
//Create new image
Bitmap bmpRotated = new Bitmap(Convert.ToInt32(rctNewSize.Width), Convert.ToInt32(rctNewSize.Height));
using (Graphics g = Graphics.FromImage(bmpRotated))
{
//Set rotation point to center of image
g.TranslateTransform(bmpRotated.Width / 2, 0);
g.RotateTransform(iRotationDegrees);
//Draw the rotated image on the bitmap
g.DrawImageUnscaled(bmpSource, 0,0);
}
With an angle of 45 degrees, when I set the TranslateTransform to bmpRotated.Width / 2, 0 the rotated image is not quite centered horizontally, and the bottom left corner is cut off a bit.
I'm missing some math here that is correctly figuring out the appropriate dx/dy values to pass to TranslateTransform.

Matrix Transform of Rectangle after changing its bounds

I have a shape, for example a Rectangle which has the following bounds:
X = 100
Y = 100
Width = 100
Height = 100
I apply the following rotation to this rectangle using a new Matrix:
X = 100
Y = 100
Angle = 45
var transform = new Matrix();
transform.RotateAt(angle, point);
So the new Matrix has the following value:
0.7071068, 0.7071067, -0.7071067, 0.7071068, 150, -62.13202
I use this Matrix when I draw the Rectangle with Graphic:
protected override void OnPaint(PaintEventArgs e)
{
...
e.Graphic.Transform = transform;
g.DrawRectangle(Pen, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
The problem is the following: at a certain point I need to draw the same Rectangle but shifted by a certain offset, for example (50, 50). I have stored the Matrix transform and the Rectangle bounds. If I change only the bounds (adding the offset) the new Rectangle will be drawn in a wrong position, probably due to the previous rotation point.
How I have to change the Matrix in order to draw my Rectangle in the "right" position? that is, how can I retreive the right rotation point and the old rotation angle?
Try to add translation to the matrix using MatrixOrder.Prepend.
For offset (50, 50) it'll be:
transform.Translate(50, 50, MatrixOrder.Prepend);
Or create a separate matrix for this case:
var transformWithOffset = new Matrix();
transformWithOffset.Translate(50, 50);
transformWithOffset.RotateAt(angle, point);

Strange rotation in C# graphics

I am using OnPaint method in my class Class1 : Panel.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
}
to rotate and draw rectangle I am using
Matrix m = new Matrix();
m.RotateAt(90, rotationPoint);
g.Transform = m;
g.FillRectangle(Brushes.Black, rectangle)
the problem is, that rotation isn't working as I want it to.
Red square is rotation point and it's located in the middle-top of rectangle. How to set x, y and rotation point so rotation would work properly?
After rotating at 90 degress it should look like this
red pixel is still at the same location.
Rotation point is not the point, which you want to rotate. It is point, around which graphics is rotated. So if you draw a rectangle on the top of the graphics and want to rotate it (rectangle) - then you should set rotation point as center of graphics and rotate image to 90 degrees.
Here is example, that does almost what you want:
base.OnPaint(e);
var g = e.Graphics;
var width = g.VisibleClipBounds.Width;
var height = g.VisibleClipBounds.Height;
var rotationPoint = new PointF(width / 2, height / 2); ;
// draw center point
g.FillRectangle(Brushes.Red, new RectangleF(rotationPoint.X - 5, rotationPoint.Y - 5, 10, 10));
using (var path = new GraphicsPath())
{
var rectangle = new RectangleF((width - 10) / 2, 0, 10, 10);
var m = new Matrix();
m.RotateAt(90, rotationPoint);
path.AddRectangle(rectangle);
path.Transform(m);
// draw rotated point
g.FillPath(Brushes.Black, path);
}

Categories

Resources