SIGN UP MEMBER LOGIN:    
ARTICLE

Creating Irregularly Shaped Forms in GDI+

Posted by Mickey Marshall Articles | GDI+ & Graphics October 18, 2010
A Windows game that looks very similar to a painter's palette is used to show the creation of Irregularly Shaped Forms in GDI+.
Reader Level:
Download Files:
 

Long ago in a lifetime far away, I came across a Windows game that showed up on the screen looking very similar to a painter's palette. That is to say, the main form for the game had a shape reminiscent of a painter's palette.

That idea intrigued me so I started a little digging. The answer was so simple that I had a hard time getting behind it.

In a nutshell:

1: Visualize the shape or even draw it on paper.

2: Create a set of points (x & y Cartesian coordinates) that minimally define the outline of the intended shape.
(At this point in the process there are two ways of handling the last step)

For .net enthusiasts

3a: Declare an instance of System.Drawing.Drawing2D.GraphicsPath.

3b: Use an appropriate GraphicsPath function to add the points to the path.

3c: Set the form's Region to a new instance of Region while passing the GaphicsPath to the constructor of Region.

For old school die hards (like me)

        SetWindowRgn (ByVal hWnd As Integer, ByVal hRgn As Integer, ByVal bRedraw As Boolean) As Integer
CreatePolygonRgn (ByRef lpPoint As Point, ByVal nCount As Integer, ByVal nPolyFillMode As Integer) As Integer
        SetWindowRgn(Handle.ToInt32, CreatePolygonRgn(points(0), 5, 1), True)

4a: Call windows the API SetWindowRgn.

4b: For the hRgn parameter, call CreatePolygonRgn using the points defined earlier as the lpPoint parameter.

5: Sit back and let windows do the heavy lifting.

In this particular example we are going to create a Stopwatch application that actually looks like a stopwatch. First I found a simple picture of a stopwatch on the internet. Then, with a photo editor, I simply erased the face of the watch.

Stopwatch1.jpg

The essence of a stopwatch for me is the round body, a stem winder and a click button. For the sake of simplicity, I will 'move' the click button up onto the winder stem.

That leaves three reasonably simple geometric shapes to outline our stopwatch:

  1. A small square defining the winder.
  2. A small rectangle defining the click button / stem.
  3. A large circle defining the body of the watch.

Stopwatch2.jpg


Now we need to come up with a set of points that minimally describes the outline of these three shapes combined. We can do this geometrically in four areas:

1: The curve swept out from 0 degress to 85 degress (marked green below from 3 o'clock to 12 o'clock). I had to play with the focal point and radius of the circle to closely match the size of the wath face. This uses 85 points to more closely approximate a smooth curve. Windows draws straight lines between points.

For i=0 to 85
{
Point(i).X = FocalpointX + Cos(i * (pi / 180)) * Radius
Point(i).Y = FocalpointY - Sin(i * (pi / 180)) * Radius
}


Stopwatch3.jpg

2: The next point (86) is up (down in windows coordinats) 25 units (in screen y coordinat units). The right side of the stem.

points(86).X = points(85).X
points(86).Y = points(85).Y - 25

3: The next point (87) is right 15 points. This brings us to the bottom right corner of the winder.

points(87).X = points(86).X + 15
points(87).Y = points(86).Y

4: The next point is up another 25 units. This brings us to the top right corner of the winder.

Now the Math gets easy but visualizing it is tricky

points(88).X = points(87).X
points(88).Y = points(87).Y - 25

5: I have set aside 360 points for this shape (360 degrees in a circle). So now I jump to points 96-360. Point 360 will close the circle and the shape. The arc swept out by the green radius from the bottom left of the stem to 3 o'clock on the face of the watch.

For i=96 to 360
{
Point(i).X = FocalpointX + Cos(i * (pi / 180)) * Radius
Point(i).Y = FocalpointY - Sin(i * (pi / 180)) * Radius
}

Now we work backwards from point 95 to point 89.
6: Point 95 is up (down in windows coordinates) 25 units. This brings us to the top left of the stem.

points(95).X = points(96).X
points(95).Y = points(96).Y - 25

7: Point 94 is left 15 point. This marks the bottom left of the winder.

points(94).X = points(95).X - 15
points(94).Y = points(95).Y

8: Point 93 is up 15 points. To the top left of the winder.

points(93).X = points(94).X
points(93).Y = points(94).Y - 25

Theoretically we have minimally defined the shape except that point 89 through 92 are still unset. So we just set all of them to either point 93 or point 82 (I use point 82).

For i = 89 To 92
{
points(i).X = points(88).X
points(i).Y = points(88).Y
}

Now just add these points to a graphics path and set the forms region to that path, add some timer functionality and:

Stopwatch3.jpg

C Sharp Code

            Point[] points = new Point[361];
            int Radius = 0;
            int X = 0;
            int Y = 0;
            short i = 0;
            X = 160;
            Y = 245;
            Radius = 125;

            // remeber that the X, Y coordinates of a circle can be found using the sine and cosine functions from high
school trigonometry
            // Start the circle at the zero angle
            // and place the stem at the top say 85 degrees
            // so draw that arc
            for (i = 0; i <= 85; i++)
            {
                points[i].X = (int)(X + System.Math.Cos(i * (pi / 180)) * Radius);
                // pi/180 converts degrees to radians
                points[i].Y = (int)(Y - System.Math.Sin(i * (pi / 180)) * Radius);
            }
 
            // define the corners of the rectangles that define the stem
            points[86].X = points[85].X;
            points[86].Y = points[85].Y - 35;
 
            points[87].X = points[86].X + 5;
            points[87].Y = points[86].Y;
 
            points[88].X = points[87].X;
            points[88].Y = points[87].Y - 35;
 
            // finish the circle
            for (i = 96; i <= 360; i++)
            {
                points[i].X = (int)(X + System.Math.Cos(i * (pi / 180)) * Radius);
                // pi/180 converts degrees to radians
                points[i].Y = (int)(Y - System.Math.Sin(i * (pi / 180)) * Radius);
            }

            // finish the stem
            points[95].X = points[96].X;
            points[95].Y = points[96].Y - 35;

            points[94].X = points[95].X - 5;
            points[94].Y = points[95].Y;

            points[93].X = points[94].X;
            points[93].Y = points[94].Y - 35;

            for (i = 89; i <= 92; i++)
            {
                points[i].X = points[88].X;
                points[i].Y = points[88].Y;
            }

            // Old school - Windows API
            //SetWindowRgn(Handle.ToInt32, CreatePolygonRgn(points(0), 360, 1), True)

            //New school - .NET
            GraphicsPath gPath = new GraphicsPath();
            gPath.AddCurve(points);
            this.Region = new Region(gPath); 

Final Output:

Clip1.jpg

Login to add your contents and source code to this article
share this article :
post comment
 

Thanks for sharing.

Posted by Mahesh Chand Oct 19, 2010
Nevron Gauge for SharePoint
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Team Foundation Server Hosting
Become a Sponsor