how i can draw small circle inside big one on c#? - 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);

Related

How do I rotate a Regular polygon in 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.

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 can I draw a circle behind another circle on the same line slope?

I have a line and a circle at the end of the line, like in this image:
I draw the first circle and center this circle is end of first line.
How can I draw another circle behind the first one and on the same slope of line? I tried this code:
float y2 = m * x - m * x1 + y1; //new
p1 = new PointF(x1, y1); //x and y for first line line
PointF p2 = new PointF();
p2 = new PointF(x2, y2); //make the new x,y as point
g.DrawLine(penTow, p1, p2); //this should draw line from center first circle to center of second circle
g.DrawEllipse(penOrginal,
(float)(p2.X - radius), (float)(p2.Y - radius),
(float)(radius * 2), (float)(radius * 2)); //draw the second circle and center is the end of second line
When I tried it the circle was too far from the first circle
var slope = Math.Atan2(p2.X - p1.X, p2.Y - p1.Y);
var nextX = p2.X + radus * 2 * Math.Sin(slope);
var nextY = p2.Y + radus * 2 * Math.Cos(slope);
e.Graphics.DrawEllipse(Pens.Black,
(float)(nextX - radus), (float)(nextY - radus),
(float)(radus * 2), (float)(radus * 2));

Crop a diagonal area from an image in WPF

I want to crop from an image using user-drawn rectangles on a canvas. The rectangles can be moved, re-sized, and rotated.
When the user selects "Get Cropped Image", the area inside the rectangle should be saved in a second image location on the page, which I can do perfectly well, so long as the rectangle is not rotated. (Straight-forward use of CroppedBitmap.) However, when the rectangle is at an angle I do not know how to perform the crop.
This is what I want to do (forgive my poor MS Paint skills):
My questions are:
1) How do I correctly track or calculate the points of the rectangle?
and,
2) Once I have the points, how do I crop the rotated rectangle?
EDIT:
Thanks to user Rotem, I believe that I have the answer to the second question. Using code modified from the following answers: Answer 1, Answer 2, I am seeing good results. Unfortunately, I am still unable to track the correct location points for the rectangle, so I cannot fully test this as of yet.
public static Bitmap CropRotatedRect(Bitmap source, System.Drawing.Rectangle rect, float angle, bool HighQuality)
{
Bitmap result = new Bitmap((int)rect.Width, (int)rect.Height);
using (Graphics g = Graphics.FromImage(result))
{
g.InterpolationMode = HighQuality ? InterpolationMode.HighQualityBicubic : InterpolationMode.Default;
using (Matrix mat = new Matrix())
{
mat.Translate(-rect.Location.X, -rect.Location.Y);
mat.RotateAt(-(angle), rect.Location);
g.Transform = mat;
g.DrawImage(source, new System.Drawing.Point(0, 0));
}
}
return result;
}
EDIT:
The answer to the first point is much easier than I had originally thought. You can always get the top-left corner of the rectangle by calling—
double top = Canvas.GetTop(rect);
double left = Canvas.GetLeft(rect);
You can then calculate the rest of the points using the width and the height—
Point topLeft = new Point(left, top);
Point topRight = new Point(left + rect.Width, top);
Point bottomLeft = new Point(left, top + rect.Height);
Point bottomRight = new Point(left + rect.Width, top + rect.Height);
Point centerPoint = new Point(left + (rect.Width / 2), top + (rect.Height / 2));
If your rectangle is rotated, then you have to translate these points to determine where they truly lie on the canvas—
public Point TranslatePoint(Point center, Point p, double angle)
{
// get the point relative to (0, 0) by subtracting the center of the rotated shape.
Point relToOrig = new Point(p.X - center.X, p.Y - center.Y);
double angleInRadians = angle * Math.PI / 180;
double sinOfA = Math.Sin(angleInRadians);
double cosOfA = Math.Cos(angleInRadians);
Point translatedPoint = new Point(relToOrig.X * cosOfA - relToOrig.Y * sinOfA,
relToOrig.X * sinOfA + relToOrig.Y * cosOfA);
return new Point(translatedPoint.X + center.X, translatedPoint.Y + center.Y);
}
Once you are able to translate the top-left corner, you can use Rotem's cropping method. You can also calculate the position of the rest of the rectangle, so you are able to determine if the rectangle is within the bounds of the image, if it is touching an edge, or any other thing that you might want to do in regards to the position.
I discovered the answer to my own question(s), and made the appropriate edits along the way. Please see above for the answer.

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);
}

Categories