I've been tried to draw triangles on each edge of regular polygons.
So far I got to make polygons like this:
What I'm trying to make is that small triangle on the each edge of the polygon:
How do I do this?
Code how to draw polygons is below:
int sides = 5;
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;
}
Try this out...instead of calculating absolute points for the triangle, I've instead computed points for a "unit triangle" at the origin (using your function!). Then I simply rotate and move the Graphics surface and draw the unit triangle where I want it:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private PointF[] nPoints;
private PointF[] triangle;
private int sides = 5;
private int angle = 0;
private int radius = 100;
private int triangleLength = 10;
private void Form1_Load(object sender, EventArgs e)
{
triangle = this.CalculateVertices(3, triangleLength, 0, new Point(0, 0)); // this "unit triangle" will get reused!
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Point center = new Point(ClientSize.Width / 2, ClientSize.Height / 2);
nPoints = CalculateVertices(sides, radius, angle, center);
// draw the polygon
g.FillPolygon(Brushes.Blue, nPoints);
g.DrawPolygon(Pens.Black, nPoints);
for (int i = 0; i < sides; i++)
{
g.DrawLine(Pens.Black, center.X, center.Y, nPoints[i].X, nPoints[i].Y);
}
// draw small triangles on each edge:
float step = 360.0f / sides;
float curAngle = angle + step / 2; // start in-between the original angles
for (double i = curAngle; i < angle + (step / 2) + 360.0; i += step) //go in a circle
{
// move to the center and rotate:
g.ResetTransform();
g.TranslateTransform(center.X, center.Y);
g.RotateTransform((float)i);
// move out to where the triangle will be drawn and render it
g.TranslateTransform(radius, 0);
g.FillPolygon(Brushes.LightGreen, triangle);
g.DrawPolygon(Pens.Black, triangle);
}
}
// this is your code unchanged
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();
}
// this is your code unchanged
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;
}
}
Related
I am trying to spread panels (9 in my example) on a circle that I have drawn.
I am using c# winforms.
I have tried many variations of my code but I'm not getting what I want and started to get confused.
Eventually I want something like that:
I am not really sure how to put the center of my panels on the corresponding points on the circle using the angles.
Here's my code:
public partial class Form1 : Form
{
List<Panel> plist = new List<Panel>();
Rectangle circ_rect = new Rectangle();
const int Num_Screens = 9;
const int margin = 15;
public Form1()
{
InitializeComponent();
WindowState = FormWindowState.Maximized;
}
private void Generate_Panels()
{
for (int i = 0; i < 9; i++)
{
Panel p = new Panel();
p.BackColor = Color.LightSkyBlue;
p.Size = new Size(250, 150);
p.BorderStyle = BorderStyle.FixedSingle;
p.Name = "panel_" + ((i + 1).ToString());
plist.Add(p);
}
}
private void Generate_Circle()
{
//Create panels
Generate_Panels();
//Set circle coord
Point circ_center = new Point(Width / 2, Height / 2);
Size circ_Size = new Size(Height - margin, Height - margin);
circ_center = new Point((circ_center.X - (circ_Size.Width / 2)),
(circ_center.Y - (circ_Size.Height / 2)));
circ_rect = new Rectangle(circ_center, circ_Size);
float radius = circ_Size.Width / 2;
float angle = 0.0f;
Point loc = Point.Empty;
Point rect_center = Point.Empty;
for (int i = 0; i < plist.Count; i++)
{
rect_center = new Point((plist[i].Width / 2), (plist[i].Height / 2));
angle = 360 * ((i + 1f) / 9);
loc.X = (int)(radius * Math.Cos(angle * Math.PI / 180)) + circ_center.X;
loc.Y = (int)(radius * Math.Sin(angle * Math.PI / 180)) + circ_center.Y;
plist[i].Location = new Point(loc.X - (plist[i].Width / 2) + circ_rect.X,
loc.Y - (plist[i].Height / 2) + circ_rect.Y);
this.Controls.Add(plist[i]);
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(Pens.Red, circ_rect);
}
private void Form1_Load(object sender, EventArgs e)
{
Generate_Circle();
}
}
Having r as radius of a circle with center of (0,0) in a Cartesian coordinate system, we can calculate coordinate of a on the circle based on the angle:
x = r * cos(degree) and y = r * sin(degree)
In C# Sin and Cos methods, accept radians, so we should convert degree to radians using the following formula.
radians = Math.PI * degree / 180.0
The next step is converting the Cartesian coordinate system values to the form coordinate values:
panel.X = x + center.X - panel.Width/2
panel.Y = center.Y - y - panel.Height/2
The next step is calculating the angles. You can set angles manually or you can calculate them by setting an angle as start angle (like 90) and adding a value (like 40, 360/count) as step to the angles.
Example
public partial class Form1 : Form {
Rectangle circle;
List<Panel> panels;
List<int> angles;
public Form1() {
InitializeComponent();
ResizeRedraw = true;
angles = Enumerable.Range(0, 9).Select(x => 90 + x * 40).ToList();
panels = Enumerable.Range(0, 9).Select(x => new Panel() {
Size = new Size(100, 40),
BackColor = Color.LightSkyBlue
}).ToList();
this.Controls.AddRange(panels.ToArray());
}
protected override void OnLayout(LayoutEventArgs levent) {
base.OnLayout(levent);
int padding = 50;
int radius = Math.Min(ClientSize.Width, ClientSize.Height) / 2 - padding;
Point center = new Point(ClientSize.Width / 2, ClientSize.Height / 2);
circle = new Rectangle(center.X - radius, center.Y - radius,
2 * radius, 2 * radius);
for (int i = 0; i < 9; i++) {
var x = (int)(radius * Math.Cos(Math.PI * angles[i] / 180.0)) + center.X;
var y = center.Y - (int)(radius * Math.Sin(Math.PI * angles[i] / 180.0));
panels[i].Left = x - (panels[i].Width / 2);
panels[i].Top = y - (panels[i].Height / 2);
}
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(Pens.Red, circle);
}
}
I'm trying to rotate polygon randomly using timer. I got to draw regular polygons and rotate it to one direction. But I'm not sure about how to rotate polygon to random direction using angle or timer interval.
My Code is below:
int sides = 5;
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;
}
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;
}
private void timer2_Tick(object sender, EventArgs e){
angle += 1;
angle_tri -= 1;
Invalidate();
}
Here is an example of drawing a list of points rotated with varying speeds, both angular and and timing..:
First a few variables:
Random rnd = new Random();
float angle = 0f;
List<Point> points = new List<Point>();
Then a Tick with varying speed and a varying angle:
private void timer1_Tick(object sender, EventArgs e)
{
angle += rnd.Next(0, 33)/ 10f;
timer1.Interval = rnd.Next(100) + 15;
pictureBox5.Invalidate();
}
Here is the Paint event of a PictureBox, which is DoubleBuffered, so it won't flicker..:
private void pictureBox5_Paint(object sender, PaintEventArgs e)
{
if (points.Count > 1)
{
Point center = new Point(
(points.Select(x => x.X).Max() + points.Select(x => x.X).Min()) / 2,
(points.Select(x => x.Y).Max() + points.Select(x => x.Y).Min()) / 2);
e.Graphics.TranslateTransform(center.X, center.Y);
e.Graphics.RotateTransform(angle);
e.Graphics.TranslateTransform(-center.X, -center.Y);
e.Graphics.DrawPolygon(Pens.DarkGreen, points.ToArray());
}
}
Note that due to the weird speed changes this is anything but smooth; you would have to find better algorithms for them than mere randomness..
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!
I'd like to update a list of points (PointFs) by performing a rotation (around a new origin) and translating each point by an amount that is proportional to its current distance from the origin (so not an absolute translation).
I currently do this for each point in turn but performance is poor when moving more than a handful of points.
I'd like to make the transformation more efficient so wanted to use a matrix. The rotation is no problem, but I don't know how to do the proportional translation.
Can I do this with an affine matrix? Is there some other way to do the transformation more efficiently?
UPDATED
Here's my current code. I've changed it a little so at least it does use a matrix for the rotation. Note the translation is based on a ratio, so points closer to the centre won't move as far as points further away:
private void DragPointsAroundCentre(PointF centre, PointF priorLocation, PointF newLocation, PointF[] otherPoints)
{
// calculate the angle and length of the transformation from the original location
var priorLength = Maths.Distance(centre, priorLocation);
var newLength = Maths.Distance(centre, newLocation);
var lengthRatio = newLength / priorLength;
var rotationAngle = (float)Maths.Angle(centre, priorLocation, newLocation);
// apply the rotation to the other points
Rotate(otherPoints, rotationAngle, centre);
// apply an equivalent translation to the other points
for (int i = 0; i < otherPoints.Length ; i++)
{
var translation = GetPointOnLine(centre, otherPoints[i], (float) lengthRatio);
otherPoints[i].X = translation.X;
otherPoints[i].Y = translation.Y;
}
}
private static void Rotate(PointF[] points, float angle, PointF center)
{
using (Matrix m = new Matrix())
{
m.RotateAt(angle, center);
m.TransformPoints(points);
}
}
// gets a point from a relative position on a line using the specified ratio
private static PointF GetPointOnLine(PointF origin, PointF point, float ratio)
{
return new PointF(
origin.X + (point.X - origin.X) * ratio,
origin.Y + (point.Y - origin.Y) * ratio);
}
This is the code I use for transformations. I hope this helps you:
class Program
{
static void Main(string[] args)
{
PointF[] points = new PointF[]
{
new PointF(1, 0),
new PointF(0, 1)
};
float angle = 90; // in degrees
PointF center = new PointF(1, 1);
Rotate(points, angle, center);
float offset = 10;
PointF vector = new PointF(1, 1);
Translate(points, offset, vector);
}
static void Rotate(PointF[] points, float angle, PointF center)
{
using (Matrix m = new Matrix())
{
m.RotateAt(angle, center);
m.TransformPoints(points);
}
}
// Translates point along the specified vector.
static void Translate(PointF[] points, float offset, PointF vector)
{
float magnitude = (float)Math.Sqrt((vector.X * vector.X) + (vector.Y * vector.Y)); // = length
vector.X /= magnitude;
vector.Y /= magnitude;
PointF translation = new PointF()
{
X = offset * vector.X,
Y = offset * vector.Y
};
using (Matrix m = new Matrix())
{
m.Translate(translation.X, translation.Y);
m.TransformPoints(points);
}
}
}
If you need the transformation to be very efficient you can combine both transformation matrices into one and transform all points only once.
EDIT:
You can use for example a simple parallel loop to make it a little bit faster. But even for 30.000.000 points the difference is not too big in this case (my case 4 cpu cores). But it depends of course how often do you process them.
class Program
{
static void Main(string[] args)
{
int pointCount = 30000000;
PointF[] otherPoints = new PointF[pointCount];
Random rnd = new Random();
for (int i = 0; i < pointCount; i++)
{
otherPoints[i] = new Point(rnd.Next(), rnd.Next());
}
PointF centre = new PointF(3, 3);
float lengthRatio = 7.3f;
// apply an equivalent translation to the other points
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < otherPoints.Length; i++)
{
var translation = GetPointOnLine(centre, otherPoints[i], (float)lengthRatio);
otherPoints[i].X = translation.X;
otherPoints[i].Y = translation.Y;
}
sw.Stop();
Console.WriteLine("Single thread: {0} sec.", sw.Elapsed.TotalSeconds);
sw.Reset();
sw.Start();
Parallel.For(0, pointCount, i =>
{
var translation = GetPointOnLine(centre, otherPoints[i], (float)lengthRatio);
otherPoints[i].X = translation.X;
otherPoints[i].Y = translation.Y;
});
sw.Stop();
Console.WriteLine("Multi thread: {0} sec.", sw.Elapsed.TotalSeconds);
Console.ReadKey();
}
// gets a point from a relative position on a line using the specified ratio
private static PointF GetPointOnLine(PointF origin, PointF point, float ratio)
{
return new PointF(
origin.X + (point.X - origin.X) * ratio,
origin.Y + (point.Y - origin.Y) * ratio);
}
}
EDIT-2:
I found a transformation that is exacly the same as yours and transforms the points in only one loop using a single matrix. Here's the code for both the old and the new transformation:
class Program
{
static void Main(string[] args)
{
PointF[] points1 = new PointF[]
{
new PointF(1f, 0f),
new PointF(0f, 1f),
new PointF(1f, 1f),
new PointF(2f, 2f),
};
PointF[] points2 = new PointF[]
{
new PointF(1f, 0f),
new PointF(0f, 1f),
new PointF(1f, 1f),
new PointF(2f, 2f),
};
PointF center = new PointF(2f, 2f);
float priorLength = 4f;
float newLength = 5f;
float lengthRatio = newLength / priorLength;
float rotationAngle = 45f;
Transformation_old(points1, rotationAngle, center, lengthRatio);
Transformation_new(points2, rotationAngle, center, lengthRatio);
Console.ReadKey();
}
static void Transformation_old(PointF[] points, float rotationAngle, PointF center, float lengthRatio)
{
Rotate(points, rotationAngle, center);
for (int i = 0; i < points.Length; i++)
{
var translation = GetPointOnLine(center, points[i], lengthRatio);
points[i].X = translation.X;
points[i].Y = translation.Y;
}
}
static void Rotate(PointF[] points, float angle, PointF center)
{
using (Matrix m = new Matrix())
{
m.RotateAt(angle, center);
m.TransformPoints(points);
}
}
private static PointF GetPointOnLine(PointF origin, PointF point, float ratio)
{
return new PointF(
origin.X + (point.X - origin.X) * ratio,
origin.Y + (point.Y - origin.Y) * ratio);
}
// Uses only a single matrix and a single transformation:
static void Transformation_new(PointF[] points, float rotationAngle, PointF center, float lengthRatio)
{
using (Matrix m = new Matrix())
{
m.RotateAt(rotationAngle, center, MatrixOrder.Prepend);
// Replaces GetPointOnLine
m.Translate(center.X, center.Y, MatrixOrder.Prepend);
m.Scale(lengthRatio, lengthRatio, MatrixOrder.Prepend);
m.Translate(-center.X, -center.Y, MatrixOrder.Prepend);
m.TransformPoints(points);
}
}
}
i am currently try to inscribe diagonals of a decagon inside a circle
like this
in c# my approach would be creating a circle
e.Graphics.DrawEllipse(myPen, 0, 0, 100, 100);
and draw lines inside using
e.Graphics.DrawLine(myPen, 20, 5, 50, 50);
after that i would draw a decagon polygon.
currently im stuck at how to divide the circle into 10 parts/ finding the correct coordiantes of the points on the circumference of the circles because im not good in math,
i want to know how would i know the next point in a circumference of the circle the size of my circle is indicated above.
and also i want also to ask a better approach for my problem.
Thank you :)
Just for grits and shins, here's a generic implementation that will inscribe an X-sided polygon into the Rectangle you pass it. Note that in this approach I'm not actually calculating any absolute points. Instead, I am translating the origin, rotating the surface, and drawing the lines only with respect to the origin using a fixed length and an angle. This is repeated in a loop to achieve the end result below, and is very similar to commanding the Turtle in Logo:
public partial class Form1 : Form
{
PictureBox pb = new PictureBox();
NumericUpDown nud = new NumericUpDown();
public Form1()
{
InitializeComponent();
this.Text = "Inscribed Polygon Demo";
TableLayoutPanel tlp = new TableLayoutPanel();
tlp.RowCount = 2;
tlp.RowStyles.Clear();
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
tlp.ColumnCount = 2;
tlp.ColumnStyles.Clear();
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tlp.Dock = DockStyle.Fill;
this.Controls.Add(tlp);
Label lbl = new Label();
lbl.Text = "Number of Sides:";
lbl.TextAlign = ContentAlignment.MiddleRight;
tlp.Controls.Add(lbl, 0, 0);
nud.Minimum = 3;
nud.Maximum = 20;
nud.AutoSize = true;
nud.ValueChanged += new EventHandler(nud_ValueChanged);
tlp.Controls.Add(nud, 1, 0);
pb.Dock = DockStyle.Fill;
pb.Paint += new PaintEventHandler(pb_Paint);
pb.SizeChanged += new EventHandler(pb_SizeChanged);
tlp.SetColumnSpan(pb, 2);
tlp.Controls.Add(pb, 0, 1);
}
void nud_ValueChanged(object sender, EventArgs e)
{
pb.Refresh();
}
void pb_SizeChanged(object sender, EventArgs e)
{
pb.Refresh();
}
void pb_Paint(object sender, PaintEventArgs e)
{
// make circle centered and 90% of PictureBox size:
int Radius = (int)((double)Math.Min(pb.ClientRectangle.Width, pb.ClientRectangle.Height) / (double)2.0 * (double).9);
Point Center = new Point((int)((double)pb.ClientRectangle.Width / (double)2.0), (int)((double)pb.ClientRectangle.Height / (double)2.0));
Rectangle rc = new Rectangle(Center, new Size(1, 1));
rc.Inflate(Radius, Radius);
InscribePolygon(e.Graphics, rc, (int)nud.Value);
}
private void InscribePolygon(Graphics G, Rectangle rc, int numSides)
{
if (numSides < 3)
throw new Exception("Number of sides must be greater than or equal to 3!");
float Radius = (float)((double)Math.Min(rc.Width, rc.Height) / 2.0);
PointF Center = new PointF((float)(rc.Location.X + rc.Width / 2.0), (float)(rc.Location.Y + rc.Height / 2.0));
RectangleF rcF = new RectangleF(Center, new SizeF(1, 1));
rcF.Inflate(Radius, Radius);
G.DrawEllipse(Pens.Black, rcF);
float Sides = (float)numSides;
float ExteriorAngle = (float)360 / Sides;
float InteriorAngle = (Sides - (float)2) / Sides * (float)180;
float SideLength = (float)2 * Radius * (float)Math.Sin(Math.PI / (double)Sides);
for (int i = 1; i <= Sides; i++)
{
G.ResetTransform();
G.TranslateTransform(Center.X, Center.Y);
G.RotateTransform((i - 1) * ExteriorAngle);
G.DrawLine(Pens.Black, new PointF(0, 0), new PointF(0, -Radius));
G.TranslateTransform(0, -Radius);
G.RotateTransform(180 - InteriorAngle / 2);
G.DrawLine(Pens.Black, new PointF(0, 0), new PointF(0, -SideLength));
}
}
}
I got the formula for the length of the side here at Regular Polygon Calculator.
One way of dealing with this is using trigonometric functions sin and cos. Pass them the desired angle, in radians, in a loop (you need a multiple of 2*π/10, i.e. a = i*π/5 for i between 0 and 9, inclusive). R*sin(a) will give you the vertical offset from the origin; R*cos(a) will give you the horizontal offset.
Note that sin and cos are in the range from -1 to 1, so you will see both positive and negative results. You will need to add an offset for the center of your circle to make the points appear at the right spots.
Once you've generated a list of points, connect point i to point i+1. When you reach the ninth point, connect it to the initial point to complete the polygon.
I don't test it, but i think it is ok.
#define DegreeToRadian(d) d * (Pi / 180)
float r = 1; // radius
float cX = 0; // centerX
float cY = 0; // centerY
int numSegment = 10;
float angleOffset = 360.0 / numSegment;
float currentAngle = 0;
for (int i = 0; i < numSegment; i++)
{
float startAngle = DegreeToRadian(currentAngle);
float endAngle = DegreeToRadian(fmod(currentAngle + angleOffset, 360));
float x1 = r * cos(startAngle) + cX;
float y1 = r * sin(startAngle) + cY;
float x2 = r * cos(endAngle) + cX;
float y2 = r * sin(endAngle) + cY;
currentAngle += angleOffset;
// [cX, cY][x1, y1][x2, y2]
}
(fmod is c++ function equals to floatNumber % floatNumber)