How do I rotate a Regular polygon in C# - c#

I need to rotate the regular polygon around a set center by a given degree can somebody help?
Im using this code the generate the regular polygon
private static void DrawRegularPolygon(PointF center, // center Coordinates of circle
int vertexes, // Number of vertices
float radius, // Radius
Graphics graphics)
{
Pen pen;
var angle = Math.PI * 2 / vertexes;
var Rotationangle = (45/180) * Math.PI;
var points = Enumerable.Range(0, vertexes)
.Select(i => PointF.Add(center, new SizeF((float)Math.Sin(i * angle) * radius, (float)Math.Cos(i * angle) * radius )));
if (vertexes%2 == 0)
{
pen = new Pen(Color.Red);
}
else
{
pen = new Pen(Color.Black);
}
graphics.DrawPolygon(pen, points.ToArray());
//graphics.DrawEllipse(Pens.Aqua, new RectangleF(PointF.Subtract(center, new SizeF(radius, radius)), new SizeF(radius * 2, radius * 2)));
}

Try these lines :
graphics.TranslateTransform(center.X, center.Y);
graphics.RotateTransform(180f);
graphics.TranslateTransform(-center.X, -center.Y);
graphics.DrawPolygon(pen, points.ToArray());
I can rotate the polygon 180 degrees, before drawing it.

Related

Finding the new coordinate of a pixel in an image rotated by center

I have an image on which I choose a random point. The image is rotated by any degree the user wishes. The goal here is to find the new coordinate of the pixel. I have tried it this way with the function RotatePoint where the original position of the pixel was (100, 370) and the image gets rotated by 270 degrees, but the new coordinate is not correct. How would I be able to get the correct new coordinate?
static public void RotatePoint(float angle)
{
var a = angle * System.Math.PI / 180.0;
float cosa = (float)Math.Cos(a), sina = (float)Math.Sin(a);
float x = 100 * cosa - 370 * sina;
float y = 100 * sina + 370 * cosa;
Console.WriteLine(x);
Console.WriteLine(y);
}
private static Bitmap RotateImage(Bitmap bmp, float angle)
{
Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);
rotatedImage.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
using (Graphics g = Graphics.FromImage(rotatedImage))
{
// Set the rotation point to the center in the matrix
g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
// Rotate
g.RotateTransform(angle);
// Restore rotation point in the matrix
g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
// Draw the image on the bitmap
g.DrawImage(bmp, new Point(0, 0));
}
return rotatedImage;
}
You perform 2 translation transformations on your image that you don't take into account into your coordinate calculations:
// Set the rotation point to the center in the matrix
g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
and
// Restore rotation point in the matrix
g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
Here is a fix, with both translations taken into account, where xRotationCenter and yRotationCenter should be your bitmap width and height:
public static void RotatePoint(float x = 100, float y = 377, float xRotationCenter, float yRotationCenter, float angleInDegree)
{
var angleInRadiant = (angleInDegree / 180.0) * Math.PI;
var cosa = (float)Math.Cos(angleInRadiant);
var sina = (float)Math.Sin(angleInRadiant);
// First translation
float t1x = x - xRotationCenter;
float t1y = y - yRotationCenter;
// Rotation
float rx = t1x * cosa - t1y * sina;
float ry = t1x * sina + t1y * cosa;
// seconde translation
float x = rx + xRotationCenter;
float y = ry + yRotationCenter;
Console.WriteLine(x);
Console.WriteLine(y);
}

how i can draw small circle inside big one on c#?

i draw a circle and i know
the radius of it and center point
so
how i can draw a small circle inside it and on the center
that's is the code of the big circle
g.DrawEllipse(
yellowPen,
(float)(Properties.Settings.Default.CenterXBall - rad),
(float)(Properties.Settings.Default.CenterYBall - rad),
(float)(rad * 2),
(float)(rad * 2));
//CenterXBall is the X of center big Circle
//CenterYBall is the X of center big Circle
//rad is radius
i want to draw small circle on the center of this circle on code
You just need to offset the position using the Radius size.
The Offset is PointF(CenterX - Radius1, CenterY - Radius2).
The Size of the drawing rectangle will then be 2 * Radius in each dimension.
Here I assume the inner circle is half the size of the outer one.
The center point is set to PointF(120, 120).
The drawing is performed in the Paint event of a PictureBox.
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
float Radius1a = 100F;
float Radius1b = 100F;
float Radius2a = Radius1a / 2;
float Radius2b = Radius1b / 2;
PointF CentrePoint = new PointF(120, 120);
PointF Position1 = new PointF(CentrePoint.X - Radius1a, CentrePoint.Y - Radius1b);
PointF Position2 = new PointF(CentrePoint.X - Radius2a, CentrePoint.Y - Radius2b);
RectangleF Rectangle1 = new RectangleF(Position1, new SizeF(Radius1a * 2, Radius1b * 2));
RectangleF Rectangle2 = new RectangleF(Position2, new SizeF(Radius2a * 2, Radius2b * 2));
e.Graphics.DrawEllipse(new Pen(Brushes.Black, 2), Rectangle1);
e.Graphics.DrawEllipse(new Pen(Brushes.Red, 2), Rectangle2);

Fill regular polygons with 2 colors

I have drawn regular polygons and divided those into equal parts.
It's like this :
but I want to fill it with 2 colors like this :
How do I implement this?
Code how to draw polygons is below:
Graphics g = e.Graphics;
nPoints = CalculateVertices(sides, radius, angle, center);
g.DrawPolygon(navypen, nPoints);
g.FillPolygon(BlueBrush, nPoints);
Point center = new Point(ClientSize.Width / 2, ClientSize.Height / 2);
for(int i = 0; i < sides; i++) {
g.DrawLine(new Pen(Color.Navy), center.X, center.Y, nPoints[i].X, nPoints[i].Y);
}
private PointF[] CalculateVertices(int sides, int radius, float startingAngle, Point center)
{
if (sides < 3) {
sides = 3;
}
//throw new ArgumentException("Polygon must have 3 sides or more.");
List<PointF> points = new List<PointF>();
float step = 360.0f / sides;
float angle = startingAngle; //starting angle
for (double i = startingAngle; i < startingAngle + 360.0; i += step) //go in a circle
{
points.Add(DegreesToXY(angle, radius, center));
angle += step;
}
return points.ToArray();
}
private PointF DegreesToXY(float degrees, float radius, Point origin)
{
PointF xy = new PointF();
double radians = degrees * Math.PI / 180.0;
xy.X = (int)(Math.Cos(radians) * radius + origin.X);
xy.Y = (int)(Math.Sin(-radians) * radius + origin.Y);
return xy;
}
There are several ways but the most straight-forward is to draw the polygons (triangles) of different colors separately.
Assumig a List<T> for colors:
List<Color> colors = new List<Color> { Color.Yellow, Color.Red };
You can add this before the DrawLine call:
using (SolidBrush brush = new SolidBrush(colors[i%2]))
g.FillPolygon(brush, new[] { center, nPoints[i], nPoints[(i+1)% sides]});
Note how I wrap around both the nPoints and the colors using the % operator!

DrawEllipse from two joint (Point, or rather X and Y coordinates)

I'm looking to show skeleton by ellipse and not by line. I have two Point with coordinates for X and Y.
When i want to draw an ellipse i need
public abstract void DrawEllipse(
Brush brush,
Pen pen,
Point center,
double radiusX,
double radiusY
)
so i have tried with this code but there is some error(don't know radiusY):
double centerX = (jointPoints[jointType0].X + jointPoints[jointType1].X) / 2;
double centerY = (jointPoints[jointType0].Y + jointPoints[jointType1].Y) / 2;
double radiusX =Math.Sqrt( (Math.Pow((jointPoints[jointType1].X - jointPoints[jointType0].X), 2)) + (Math.Pow((jointPoints[jointType1].Y - jointPoints[jointType0].Y), 2)));
drawingContext.DrawEllipse(null, drawPen, new Point(centerX, centerY), radiusX, radiusX/5);
Can anyone help me?
private void DrawBone(IReadOnlyDictionary<JointType, Joint> joints, IDictionary<JointType, Point> jointPoints, JointType jointType0, JointType jointType1, DrawingContext drawingContext, Pen drawingPen,List<JointType> badJoint)
{
Joint joint0 = joints[jointType0];
Joint joint1 = joints[jointType1];
// If we can't find either of these joints, exit
if (joint0.TrackingState == TrackingState.NotTracked ||
joint1.TrackingState == TrackingState.NotTracked)
{
return;
}
// We assume all drawn bones are inferred unless BOTH joints are tracked
Pen drawPen = this.inferredBonePen;
if ((joint0.TrackingState == TrackingState.Tracked) && (joint1.TrackingState == TrackingState.Tracked))
{
drawPen = drawingPen;
}
//If a bone makes parts of an one bad angle respect reference angle
if (badJoint.Contains(jointType0) && badJoint.Contains(jointType0))
drawPen = new Pen(Brushes.Red, 6);
drawingContext.DrawLine(drawPen, jointPoints[jointType0], jointPoints[jointType1]);
You cannot (just) use the DrawEllipse method, because that will always draw horizontal or vertical elipses.
Use this code to implement the rotation: https://stackoverflow.com/a/5298921/1974021 and write a method that takes the following input parameters:
Focalpoint1
FocalPoint2
Radius
As an ellipse can be described by both focal points and a (combined) radius. If you use the focal points, the ellipsis will overlap at the joints to create a circle-like pattern at each joint. Is that about what you want? (It is even easier if you only want them to touch at the joint)
Okay, it's actually not the focal point but the center of the osculating circle. Try this method:
private static void DrawEllipse(Pen pen, Graphics g, PointF pointA, PointF pointB, float radius)
{
var center = new PointF((pointA.X + pointB.X) / 2, (pointA.Y + pointB.Y) / 2);
var distance = GetDistance(pointA, pointB);
// The axis are calculated so that the center of the osculating circles are conincident with the points and has the given radius.
var a = radius + distance / 2; // Semi-major axis
var b = (float)Math.Sqrt(radius * a); // Semi-minor axis
// Angle in degrees
float angle = (float)(Math.Atan2(pointA.Y - pointB.Y, pointA.X - pointB.X) * 180 / Math.PI);
using (Matrix rotate = new Matrix())
{
GraphicsContainer container = g.BeginContainer();
rotate.RotateAt(angle, center);
g.Transform = rotate;
g.DrawEllipse(pen, center.X-a, center.Y-b, 2 * a, 2 * b);
g.EndContainer(container);
}
}
private static float GetDistance(PointF a, PointF b)
{
var dx = a.X - b.X;
var dy = a.Y - b.Y;
return (float)Math.Sqrt(dx * dx + dy * dy);
}

Rotating graphics?

I have this code, that draws an image.
private void timer1_Tick(object sender, EventArgs e)
{
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
var tempRocket = new Bitmap(Properties.Resources.rocket);
using (var g = Graphics.FromImage(tempRocket))
{
e.Graphics.DrawImage(tempRocket, 150, 150);
}
}
Yet what do I do to rotate it?
public static Bitmap RotateImage(Bitmap b, float angle)
{
//create a new empty bitmap to hold rotated image
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//make a graphics object from the empty bitmap
using(Graphics g = Graphics.FromImage(returnBitmap))
{
//move rotation point to center of image
g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2);
//rotate
g.RotateTransform(angle);
//move image back
g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2);
//draw passed in image onto graphics object
g.DrawImage(b, new Point(0, 0));
}
return returnBitmap;
}
There are overloads of Graphics.DrawImage that take an array of three points used to define a parallelogram for the destination, such as:
Graphics.DrawImage Method (Image, Point[])
Remarks
The destPoints parameter specifies
three points of a parallelogram. The
three Point structures represent the
upper-left, upper-right, and
lower-left corners of the
parallelogram. The fourth point is
extrapolated from the first three to
form a parallelogram.
The image represented by the image
parameter is scaled and sheared to fit
the shape of the parallelogram
specified by the destPoints
parameters.
There is also an article on MSDN describing the use of this method: How to: Rotate, Reflect, and Skew Images, with the following code example. Unfortunately, the example complicates the issue by also skewing the image.
Point[] destinationPoints = {
new Point(200, 20), // destination for upper-left point of original
new Point(110, 100), // destination for upper-right point of original
new Point(250, 30)}; // destination for lower-left point of original
Image image = new Bitmap("Stripes.bmp");
// Draw the image unaltered with its upper-left corner at (0, 0).
e.Graphics.DrawImage(image, 0, 0);
// Draw the image mapped to the parallelogram.
e.Graphics.DrawImage(image, destinationPoints);
The main differences compared to using the Graphics.Transform property are:
This method does not allow you to specify the rotation angle in degrees -- you have to use some simple trigonometry to derive the points.
This transformation applies only to the specific image.
Good if you only need to draw one rotated image and everything else is non-rotated since you don't have to reset Graphics.Transform afterward.
Bad if you want to rotate several things together (i.e., rotate the "camera").
Use Graphics.RotateTransform to rotate the image.
protected override void OnPaint(PaintEventArgs e)
{
var tempRocket = new Bitmap(Properties.Resources.rocket);
e.Graphics.RotateTransform(30.0F);
e.Graphics.DrawImage(tempRocket, 150, 150);
}
Version without clipping:
private Bitmap RotateBitmap(Bitmap bitmap, float angle)
{
int w, h, x, y;
var dW = (double)bitmap.Width;
var dH = (double)bitmap.Height;
double degrees = Math.Abs(angle);
if (degrees <= 90)
{
double radians = 0.0174532925 * degrees;
double dSin = Math.Sin(radians);
double dCos = Math.Cos(radians);
w = (int)(dH * dSin + dW * dCos);
h = (int)(dW * dSin + dH * dCos);
x = (w - bitmap.Width) / 2;
y = (h - bitmap.Height) / 2;
}
else
{
degrees -= 90;
double radians = 0.0174532925 * degrees;
double dSin = Math.Sin(radians);
double dCos = Math.Cos(radians);
w = (int)(dW * dSin + dH * dCos);
h = (int)(dH * dSin + dW * dCos);
x = (w - bitmap.Width) / 2;
y = (h - bitmap.Height) / 2;
}
var rotateAtX = bitmap.Width / 2f;
var rotateAtY = bitmap.Height / 2f;
var bmpRet = new Bitmap(w, h);
bmpRet.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution);
using (var graphics = Graphics.FromImage(bmpRet))
{
graphics.Clear(Color.White);
graphics.TranslateTransform(rotateAtX + x, rotateAtY + y);
graphics.RotateTransform(angle);
graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y);
graphics.DrawImage(bitmap, new PointF(0 + x, 0 + y));
}
return bmpRet;
}
Primary source
You need to apply transformation matrix.
Here you can find good example about transformations in GDI+

Categories