Draw a star with a given number of points in C#


The DrawStar method shown in the following code draws the required star.
// Draw the indicated star in the rectangle. private void DrawStar(Graphics gr, Pen the_pen, Brush the_brush, int num_points, int skip, Rectangle rect) { // Get the star's points. PointF[] star_points = MakeStarPoints(-Math.PI / 2, num_points, skip, rect); // Draw the star. gr.FillPolygon(the_brush, star_points); gr.DrawPolygon(the_pen, star_points); }The DrawStar method calls MakeStarPoints, passing it the angle at which the first point should be drawn, the number of points the star should have, the skip number, and the rectangle where the star should be drawn. It then fills and outlines the star. (The angle -Math.PI / 2 gives the point above the center of the star so the star is "rightside up." You can change the start angle to rotate the star.) The MakeStarPoints method shown in the following code does most of the interesting work.
// Generate the points for a star. private PointF[] MakeStarPoints(double start_theta, int num_points, int skip, Rectangle rect) { double theta, dtheta; PointF[] result; float cx = rect.Width / 2f; float cy = rect.Height / 2f; // If this is a polygon, don't bother with concave points. if (skip == 1) { result = new PointF[num_points]; theta = start_theta; dtheta = 2 * Math.PI / num_points; for (int i = 0; i < num_points; i++) { result[i] = new PointF( (float)(cx + cx * Math.Cos(theta)), (float)(cy + cy * Math.Sin(theta))); theta += dtheta; } return result; } // Find the radius for the concave vertices. double concave_radius = CalculateConcaveRadius(num_points, skip); // Make the points. result = new PointF[2 * num_points]; theta = start_theta; dtheta = Math.PI / num_points; for (int i = 0; i < num_points; i++) { result[2 * i] = new PointF( (float)(cx + cx * Math.Cos(theta)), (float)(cy + cy * Math.Sin(theta))); theta += dtheta; result[2 * i + 1] = new PointF( (float)(cx + cx * Math.Cos(theta) * concave_radius), (float)(cy + cy * Math.Sin(theta) * concave_radius)); theta += dtheta; } return result; }If the skip number is 1, then the result is a regular polygon instead of a star so the method doesn't need to allocate points for the stars concave points. In that case the method loops over the angles needed for each of the polygon's corners, creates a corresponding point, and returns the points. If the skip number is greater than 1, the method calls the CalculateConcaveRadius method described next to see how far the star's concave points should be from the center. If then loops over the angles needed to create the star's convex and concave points, creates the points, and returns them. This loop is a bit more complicated than the previous one because if must generate convex points on the outside of the star and concave points on the inside of the star, but it's still reasonably easy to understand. The following CalculateConcaveRadius method, which calculates the distance from the center of the star to the concave points, is a little more confusing.
// Calculate the inner star radius. private double CalculateConcaveRadius(int num_points, int skip) { // For really small numbers of points. if (num_points < 5) return 0.33f; // Calculate angles to key points. double dtheta = 2 * Math.PI / num_points; double theta00 = -Math.PI / 2; double theta01 = theta00 + dtheta * skip; double theta10 = theta00 + dtheta; double theta11 = theta10 - dtheta * skip; // Find the key points. PointF pt00 = new PointF( (float)Math.Cos(theta00), (float)Math.Sin(theta00)); PointF pt01 = new PointF( (float)Math.Cos(theta01), (float)Math.Sin(theta01)); PointF pt10 = new PointF( (float)Math.Cos(theta10), (float)Math.Sin(theta10)); PointF pt11 = new PointF( (float)Math.Cos(theta11), (float)Math.Sin(theta11)); // See where the segments connecting the points intersect. bool lines_intersect, segments_intersect; PointF intersection, close_p1, close_p2; FindIntersection(pt00, pt01, pt10, pt11, out lines_intersect, out segments_intersect, out intersection, out close_p1, out close_p2); // Calculate the distance between the // point of intersection and the center. return Math.Sqrt( intersection.X * intersection.X + intersection.Y * intersection.Y); }



Comments