how to make diagram fit with in panel? - c#

hey i am trying to build a windows application in .net,i have to draw factorial image inside the panel
private void Canvas_Paint(object sender, PaintEventArgs e)
{
start_x = Canvas.Width / 2;
start_Y = Canvas.Height / 2;
for (int i = 0; i < 400; i++)
draw_T();
}
public void draw_T()
{
mypen = new Pen(Color.Green, 2F);
my_angle = my_angle + (45);
my_length = 100 + (1);
end_x = (int)(start_x + Math.Cos(my_angle * .0174539676) * my_length);
end_Y = (int)(start_Y + Math.Sin(my_angle * .0174539676) * my_length);
Point[] points =
{
new Point (start_x,start_Y),
new Point (end_x,end_Y)
};
Point[] points1 =
{
new Point ((end_x+start_x)/2,(end_Y+start_Y)/2),
new Point (end_x+50,end_Y-100)
};
start_x = end_x;
start_Y = end_Y;
Graphics g = Canvas.CreateGraphics();
g.DrawLines(mypen, points);
g.DrawLines(mypen, points1);
}
drawing T shape line,then i start to draw another T shape from last end points .But problem is diagram is going outside of the panel.How do i fix drawing inside the panel

Related

Using Matrix.Rotate more than once C# Winforms

I've been trying to solve a problem I'm having with rotating an oval. The code that I'm posting works, but it's mimicking the kind of code I have to work with for real. Meaning, I can't use the OnPaint override and I'm limited to what I can do in the main code. I'm adding an oval to a graphic layer, and I need to be able to rotate, move and resize the oval. Move and resizing work flawlessly, but rotating doesn't work as I need it to.
If you click in the small box at the 9 oclock position,
the oval will rotate as expected:
The required behavior is to be able to click in the small box at the 12 oclock position, and have the oval rotate again. This does not occur. In order to get the oval to rotate again you need to click in the original 9 oclock position. What I'm really, really trying to find out is how to get the coordinates of the box at the 12 oclock position (or what ever position or location that box ends up after rotating) so that I can rotate it again. Thus far, I have been unable to figure it out. Please try and understand, I'm working with old code that was poorly written and I'm not allowed to change very much of it. What I write must integrate with what's already there. Below is the code snippet that demonstrates what I'm doing. I know I'm missing something obvious, just don't know what. Thanks.
public partial class Form1 : Form
{
int theAngle = 0;
Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
Pen pen3 = new Pen(Color.Green, 4);
Pen smallPen = new Pen(Color.Black, 1);
PointF center = new PointF(0, 0);
Rectangle rectangle = new Rectangle(20, 20, 100, 30);
Rectangle myRect2 = new Rectangle();
bool mouseBtnDown = false;
Graphics gw;
public Form1()
{
InitializeComponent();
this.MouseDown += mouseDown;
gw = this.CreateGraphics();
}
private void mouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (myRect2.Contains(e.Location))
theAngle+=90;
rotate();
}
if (e.Button == MouseButtons.Right)
{
//oval = false;
//mouseBtnDown = false;
theAngle = 0;
rectangle.X = e.X - 50;
rectangle.Y = e.Y - 15;
rectangle.Width = 100;
rectangle.Height = 30;
center.X = rectangle.Left + (0.5f * rectangle.Width);
center.Y = rectangle.Top + (0.5f * rectangle.Height);
myRect2.Size = new Size(15, 15);
myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
drawstuff();
// Invalidate();
}
}
public void rotate()
{
var matrix = new Matrix();
matrix.RotateAt(theAngle, center);
gw.Transform = matrix;
drawstuff();
}
public void drawstuff()
{
gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
gw.DrawEllipse(pen2, rectangle);
gw.DrawRectangle(smallPen, myRect2);
}
}
You can use the Transform matrix to rotate points. So what I've done is get the 4 corner points of myRect2, rotate them using the same Transform matrix, then assign these to a rectangle. You can then use this new rectangle to check the location. I also changed the call to drawstuff() at the end of the right button click to call rotate(), this way the rotated rectangle can get updated when the ellipse is first placed, and the graphics transform angle gets updated to 0.
public partial class Form1 : Form
{
int theAngle = 0;
Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
Pen pen3 = new Pen(Color.Green, 4);
Pen smallPen = new Pen(Color.Black, 1);
PointF center = new PointF(0, 0);
Rectangle rectangle = new Rectangle(20, 20, 100, 30);
Rectangle myRect2 = new Rectangle();
Rectangle rotatedRect2 = new Rectangle();
bool mouseBtnDown = false;
Graphics gw;
public Form1()
{
InitializeComponent();
this.MouseDown += mouseDown;
gw = this.CreateGraphics();
}
private void mouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (rotatedRect2.Contains(e.Location))
theAngle += 90;
rotate();
}
if (e.Button == MouseButtons.Right)
{
//oval = false;
//mouseBtnDown = false;
theAngle = 0;
rectangle.X = e.X - 50;
rectangle.Y = e.Y - 15;
rectangle.Width = 100;
rectangle.Height = 30;
center.X = rectangle.Left + (0.5f * rectangle.Width);
center.Y = rectangle.Top + (0.5f * rectangle.Height);
myRect2.Size = new Size(15, 15);
myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
rotate();
//drawstuff();
// Invalidate();
}
}
public void rotate()
{
var matrix = new Matrix();
matrix.RotateAt(theAngle, center);
gw.Transform = matrix;
// Get the 4 corner points of myRect2.
Point p1 = new Point(myRect2.X, myRect2.Y),
p2 = new Point(myRect2.X + myRect2.Width, myRect2.Y),
p3 = new Point(myRect2.X, myRect2.Y + myRect2.Height),
p4 = new Point(myRect2.X + myRect2.Width, myRect2.Y + myRect2.Height);
Point[] pts = new Point[] { p1, p2, p3, p4 };
// Rotate the 4 points.
gw.Transform.TransformPoints(pts);
// Update rotatedRect2 with those rotated points.
rotatedRect2.X = pts.Min(pt => pt.X);
rotatedRect2.Y = pts.Min(pt => pt.Y);
rotatedRect2.Width = pts.Max(pt => pt.X) - pts.Min(pt => pt.X);
rotatedRect2.Height = pts.Max(pt => pt.Y) - pts.Min(pt => pt.Y);
drawstuff();
}
public void drawstuff()
{
gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
gw.DrawEllipse(pen2, rectangle);
gw.DrawRectangle(smallPen, myRect2);
}
}
Something to note. Drawing to the screen like this (using the form's created graphics and drawing using your own draw function) means the ellipses/rectangles are only drawn once. i.e. if you draw a few then minimize your form, when you bring it back up the ellipses will be gone. Not sure if this is what you're after or not. One way to fix this would be to draw the ellipses to a Bitmap and then in the form's Paint event this bitmap is draw to the form.

Position controls on a circle

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

Refresh the canvas only for certain brushes

I'm trying to graph some circles and lines etc but I only want some lines to refresh on the canvas and the others not to, is there any way around this?
For example the mypen, mypen2 and mypen3, I want them to refresh on canvas but the graphics "g" a little further down I don't want to refresh, I want all the instances to show. How do I do this? Here is my code
private void drawlines()
{
canvas.Refresh();
int j = Int32.Parse(ivalue.Text);
float position1 = canvas.Width / 2;
float position2 = canvas.Height / 2;
float XX = (float)(Math.Round(position1 + Math.Sin(DegreeToRadian(j)) * 100));
float XY = (float)(Math.Round(position2 - Math.Cos(DegreeToRadian(j)) * 100));
float X2 = (position1 + XX);
float XY2 = XY;
System.Drawing.Pen myPen;
System.Drawing.Pen myPen2;
System.Drawing.Pen myPen3;
System.Drawing.Pen myPen4;
myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
myPen2 = new System.Drawing.Pen(System.Drawing.Color.Blue);
myPen3 = new System.Drawing.Pen(System.Drawing.Color.Black);
myPen4 = new System.Drawing.Pen(System.Drawing.Color.Green);
System.Drawing.Graphics formGraphics = canvas.CreateGraphics();
formGraphics.DrawRectangle(myPen,XX, XY,3,3);
formGraphics.DrawRectangle(myPen2, canvas.Width / 2, XY, 3, 3);
formGraphics.DrawRectangle(myPen3, position1, position2, 3, 3);
formGraphics.DrawRectangle(myPen4, position1, XY2, 3, 3);
label1.Text = Convert.ToString(XY);
label1.Refresh();
listBox1.Items.Clear();
listBox1.Items.Add("XX=[" + XX + "] XY=[" + XY + "]");
}
private void Go_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 360; i = i + 1)
{
drawlines();
int linearm = (canvas.Width / 2) - i;
ivalue.Text = Convert.ToString(i);
ivalue.Refresh();
int testx = Int32.Parse(label1.Text);
Graphics g;
g = canvas.CreateGraphics();
Pen p;
Rectangle r;
p = new Pen(Brushes.Green);
r = new Rectangle(linearm,testx, 1, 1);
g.DrawRectangle(p, r);
System.Threading.Thread.Sleep(15);
}
}
I assume you are using winforms? If so you need to change your code to work like this:
To be persistant everything need to be drawin in the Paint event and using its e.Graphics object. (This is the Golden Rule! Corollary: Never use System.Drawing.Graphics formGraphics = canvas.CreateGraphics();)
Everything you want to be drawn must be stored in Lists of classes, sufficient to hold all info you need.
If you were to draw only Rectangles in only one pen a List<Rectangle> would be enough, but for other shapes and pens you will want to create a class to hold those data.
Now you can:
Draw them all in the Paint event, iterating the List<your DrawItemClass>
Remove or set inactive those items in the List you don't want to be drawn any longer..

Customize TabPage tabs like Process Flow Arrows in Microsoft Dynamics CRM 2015

I want my TabControl in a Windows Forms app to look something like this:
https://technet.microsoft.com/en-us/library/dn531164.aspx
I have an app that has process flow and each TabPage is a process phase that I want to represent with these nice looking arrows. I know about OnPaint and System.Drawing, but I cannot make those tabs look decent.
I tried to handle TabControl.DrawItem event and to draw an arrow, but I am not satisfied with the look.
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Rectangle rect = e.Bounds;
int offset = 10;
Point p1 = e.Bounds.Location;
Point p2 = new Point(e.Bounds.X + e.Bounds.Width - offset, e.Bounds.Y);
Point p3 = new Point(e.Bounds.X + e.Bounds.Width, e.Bounds.Y + (e.Bounds.Height / 2));
Point p4 = new Point(p2.X, e.Bounds.Bottom);
Point p5 = new Point(e.Bounds.X, e.Bounds.Y+e.Bounds.Height);
Point p6 = new Point(e.Bounds.X + offset, p3.Y);
GraphicsPath path = new GraphicsPath();
path.AddLine(p1, p2);
path.AddLine(p2, p3);
path.AddLine(p3, p4);
path.AddLine(p4, p5);
path.AddLine(p5, p6);
path.AddLine(p6, p1);
e.Graphics.FillPath(Brushes.Black, path);
};
Is there any other approach to make this work as described?
Sometimes I go crazy and pick up a challenge just for fun :-)
Here is the result:
I overlay the TabControl tabControl1 with a Panel tp. (Do pick better names!) Note that this must happen rather late or else the TabControl will pop to the top.
I call them to order in the Shown event:
private void Form1_Shown(object sender, EventArgs e)
{
tp.BringToFront();
tabControl1.SendToBack();
}
You probably could create the Panel in the designer to avoid these motions..
In addition to the Panel I need a List<GraphicsPath> which is used both for drawing and for precise hit testing..:
Panel tp = null;
List<GraphicsPath> tabAreas = new List<GraphicsPath>();
You can call this function to prepare both the Panel and the List:
void makeTabPanel(TabControl tab)
{
tp = new Panel();
tp.Size = new Size(tab.Width, tab.ItemSize.Height);
tp.Paint += tp_Paint;
tp.MouseClick += tp_MouseClick;
tp.Location = tab.Location;
tab.Parent.Controls.Add(tp);
int tabs = tabControl1.TabPages.Count;
float w = tabControl1.Width / tabs;
float h = tp.Size.Height;
float y0 = 0; float y1 = h / 2f; float y2 = h;
float d = 5; // <--- this is the gap
float e = 8; // <- this is the extrusion
float w1 = w - d;
tabAreas = new List<GraphicsPath>();
for (int t = 0; t < tabs; t++)
{
int t1 = t + 1;
float e1 = t == 0 ? 0 : e; // corrections for start and end..
float e2 = t == tabs - 1 ? 0 : e;
float e3 = t == tabs - 1 ? d : 0;
List<PointF> points = new List<PointF>();
points.Add(new PointF(t * w, y0));
points.Add(new PointF(t1 * w - d + e3, y0));
points.Add(new PointF(t1 * w -d + e2 + e3, y1));
points.Add(new PointF(t1 * w- d + e3, y2));
points.Add(new PointF(t * w, y2));
points.Add(new PointF(t * w + e1, y1));
GraphicsPath gp = new GraphicsPath(FillMode.Alternate);
gp.AddPolygon(points.ToArray());
tabAreas.Add(gp);
}
}
After this the actual events are rather simple:
void tp_MouseClick(object sender, MouseEventArgs e)
{
for (int t = 0; t < tabAreas.Count; t++)
{
if (tabAreas[t].IsVisible(e.Location) )
{ tabControl1.SelectedIndex = t; break;}
}
tp.Invalidate();
}
void tp_Paint(object sender, PaintEventArgs e)
{
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(Color.White); // **
float w = tp.Width / tabAreas.Count;
Size sz = new System.Drawing.Size( (int)w, e.ClipRectangle.Height);
for (int t = 0; t < tabAreas.Count; t++)
{
Rectangle rect = new Rectangle((int)(t * w ), 0, sz.Width, sz.Height);
bool selected = tabControl1.SelectedIndex == t ;
Brush brush = selected ? Brushes.DarkGoldenrod : Brushes.DarkGray; // **
e.Graphics.FillPath(brush, tabAreas[t]);
e.Graphics.DrawString(tabControl1.TabPages[t].Text,
tabControl1.Font, Brushes.White, rect, fmt);
}
}
Pick your colors here (**)
Update: Using TextRenderer as Lars suggests works just as well. (At least ;-)
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter ;
TextRenderer.DrawText(e.Graphics, tabControl1.TabPages[t].Text,
tabControl1.Font, rect, Color.White, flags);

Transcribing a polygon on a circle

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)

Categories