# Measuring Coordinates and Areas C# Help

In the previous example, you encountered the base struct, Rectangle, which is used to represent the coordinates of a rectangle, GDI+ actually uses several similar structures to represent coordinates or areas.

The following table lists the structs that are defined in the System. Drawing namespace. Note that many of these objects have a number of other properties, methods, or operator overloads not listed here, This section just discusses some of the most important ones.

Point and PointF

Point is conceptually the simplest of these structs. Mathematically, it is equivalent to a 2D vector. It contains two public integer properties, which represent how far you move horizontally and vertically from a particular location (perhaps on the screen), as shown in Figure 33-3. Figure 33-3

To get from point A to point B, you move 20 units across and 10 units down, marked as x and y on the diagram because this is how they are commonly referred to. The following Point struct represents that line:

Point ab = new Point(20, 10);
Console.WriteLine(“Moved (O) across, {I} down”, ab.X, ah.Y);

x and Y are read-write properties, which means that you can also set the values in a Point, like this: Point ab = new Point();
ab.X = 20;
ab.Y = 10;
Console.WriteLine(“Moved (O) across, (l) down”, ab.X, ab.Y);

Note that although conventionally horizontal and vertical coordinates are referred to as x and y coordinates (lowercase), the corresponding Point properties are x and Y(uppercase) because the usual convention in C# is for public properties to have names that start with an uppercase letter.

PointF is essentially identical to Point, except that X and Y are of type float instead of into PointF is used when the coordinates are not necessarily integer values. A cast has been defined so that you can implicitly convert from Point to PointF, (Note that because Point and PointF are structs, this cast involves actually making a copy of the data.) There is no corresponding reverse case – to convert from PointF to Point you have to copy the values across, or use one of three conversion methods, Round ( ), Truncate (), and Ceiling (): You might be wondering what a unit is measured in. By default, GDI+ interprets units as pixels along the screen (or printer, whatever the graphics device is); that is how the Graphics object methods will view any coordinates that they are passed as parameters. For example, the point new Point (20, 10) represents 20 pixels across the screen and 10 pixels down. Usually these pixels are measured from the top-left comer of the client area of the window, as has been the case in the previous examples.

However, that will not always be the case. For example, on some occasions you might want to draw relative to the top-left comer of the whole window (including its border), or even to the top-left corner of the screen. In most cases, however, unless the documentation tells you otherwise, you can assume that you are talking about pixels relative to the top-left comer of the client area.

You will learn more on this subject later, after scrolling is examined, when we discuss the three different coordinate systems in use – world, ‘page, and device coordinates.

Size and SizeF

As with Point and PointF, sizes come in two varieties. The Size struct is for int types, SizeF is available if you need to use float types. Otherwise, Size and SizeF are identical This section focuses
on the Size struct.

In many ways, the Size struct is identical to the Point struct. It has two integer properties that represent a distance horizontally and a distance vertically. The main difference is that instead of x and Y, these properties are named width and Height. You can represent the earlier diagram using this code:

Size ab = new Size(20,10); .
Console.WriteLine(“Moved (O) across, (l) down”, ab.Width, ab.Height);

Although Size mathematically represents exactly the same thing as Point, conceptually, it is intended to be used in a slightly different way, Point is used when you are talking about where something is, and Size is used when you are talking about how big it is. However, because Size and Point are so closely related, there are even supported conversions between these two:

Point point = new Point(20. 10);
Size size = (Size) point;
Point another Point = (Point) size;

As an example, think about the rectangle you drew earlier, with top-left coordinate (0,0) and size (50,50). The size of this rectangle is (50,50) and might be represented by a Size instance, The bottom-right corer is also at (50,50), but that would be represented by a Point instance, To see the difference, suppose that you draw the rectangle in a different location, so that its top-left co-ordinate is at (10,10):

de. Draw Rectangle (bluePen. 10.10.50.50);

Now the bottom-right comer is at coordinate (60,60), but the size is unchanged at (50,50).

The addition operator has been overloaded for Point and Size structs so that it is possible to add a Size to a Point struct, resulting in another Point struct: This code, running as a simple console application called PointsAndSizes, produces the output shown
in Figure 33-4 . Figure 33-4

Note that this output also shows how the To String () method has been overridden in both Point and
Size to display the value in {X. Y} format.

It is also possible to subtract a Size from a Point struct to produce a Point struct, and you can add two Size structs together, producing another Size, It is not possible, however, to add a Point struct to another Point, Microsoft decided that adding Point structs does not conceptually make sense, and so it chose not to supply any overload to the + operator that would have allowed that.

You can also explicitly cast a Point to a Size struct and vice versa:

Point topLeft = new Point{10.10);
Size s1 = (Size)topLeft;
Point pl = (Point) s1 ;

With this cast, s1. Width is assigned the value of topLeft .X, and s1 Height is assigned the value of topLeft, Y. Hence, 51 contains (10,10). p1 will end up storing the same values as topLeft.

Rectangle and RectangleF

These structures represent a rectangular region (usually of the screen), Just as with Point and Size, only the Rectangle struct is considered here, RectangleF is basically identical except that its properties that represent dimensions all use float, whereas those of Rectangle use int.

A Rectangle struct can be thought of as composed of a point, representing the top-left corner of the rectangle, and a size struct, representing how large it is. One of its constructors actually takes a Point struct and a Size struct as its parameters. You can see this by rewriting the earlier code from the Draw Shapes sample that draws a rectangle: This code also uses an alternative override of Graphics. Draw Rectangle (), which takes a Pen and a Rectangle struct as its parameters.

You can also construct a Rectangle struct by supplying the top-left horizontal coordinate, top-left vertical coordinate, width, and height separately, and in that order, as individual numbers:

Rectangle rectangleArea = new Rectangle(O, 0, 50, 50)

Rectangle makes quite a few read-write properties available to set or extract its dimensions in different
combinations, See the following table for details. Note that these properties are not all independent. For example, setting Width also affects the value of Right.

Region

Region represents an area of the screen that has some complex shape. For example, the shaded area in Figure 33-5 could be represented by Region. Figure 33-5

As you can imagine, the process of initializing a Region instance is itself quite complex, Broadly speaking, you can do it by indicating either what component simple shapes make up the region or what path you take as you trace around the edge of the region. If you do need to start working with areas like this, it is worth looking up the Region class in the SDK documentation.

Posted on November 2, 2015 in Graphics with GDI+