Graphics: Lines and Shapes

In this section, you will learn about:

The graphics library offers a few options for drawing lines, all of which can be viewed in the grlib.h file. This file can be accessed by Ctrl + clicking on the <ti/grlib/grlib.h> part of your include statement (if you haven't already realized, Ctrl + click can help you discover lots of information about the DriverLib).

Graphics_drawLine is the general function for drawing lines. x1 and y1 are the coordinates for one endpoint of the line, and x2 and y2 serve as the coordinates for the other endpoint.

Graphics_drawLineH is used for graphing horizontal lines, where both endpoints share the same y coordinate value. Similarly, Graphics_drawLineV is used for graphing vertical lines, where both endpoints share the same x coordinate value.

The demo code below shows you how you can use lines and print them to the LCD.

https://github.com/ECE2564-VT/LCD_lineDemo

The graphics library has options for drawing hollow circles and filled circles. The parameters for both, however, are the same.

x and y are the coordinates for the center of the circle. lRadius is the radius of the circle. Note that these functions only produce circles, not ellipses. These lines of code will draw a hollow circle and a filled circle right next to each other:

Graphics_Context g_sContext;


Graphics_drawCircle(&g_sContext, 33, 64, 25);

Graphics_fillCircle(&g_sContext, 95, 64, 25);

The last shape you can draw with the graphics library is a rectangle. Like circles, rectangles can be drawn either hollow or filled. Unlike circles, rectangles use a type-defined struct, Graphics_Rectangle, to draw them.

xMin and xMax are the x-coordinates for the left and right sides of the rectangle, respectively. Similarly, yMin and yMax are the y-coordinates for the upper and lower sides. You can initialize and modify a Graphics_Rectangle variable like so:

// Initialization

Graphics_Rectangle myRect = {10, 20, 50, 70};


// Change one member at a time

myRect.xMin = 25;

myRect.yMax = 80;


// Change multiple members simultaneously

// May not work on older compilers

myRect = (Graphics_Rectangle) {30, 20, 80, 100};

Once you have your Graphics_Rectangle defined, pass its pointer to one of the drawing functions. The following code draws a filled rectangle surrounded by a hollow rectangle:

Graphics_Context g_sContext;


// Draw filled rectangle

Graphics_Rectangle myRect = {50, 25, 80, 100};

Graphics_fillRectangle(&g_sContext, &myRect);


// Draw hollow rectangle

myRect = (Graphics_Rectangle) {40, 15, 90, 110};

Graphics_drawRectangle(&g_sContext, &myRect);

You've learned so far how to draw shapes, but how do you get rid of them? There's no graphics library function to simply erase shapes aside from completely wiping your entire screen using Graphics_clearDisplay. But that function is very slow, and it should only be reserved for when you want to clear the entire screen, not just a single shape.

So what's the solution? We just need to draw more shapes, specifically ones that match the background color. Think of it this way: if the background color is blue, then shapes drawn with that same blue would effectively be invisible. It would be like using a white crayon to draw a circle on white paper -- obviously, you wouldn't be able to see the circle you drew.

The draw functions in the graphic library will always draw new shapes over any shapes that were already on the screen. Thus, we can effectively erase a shape by changing the foreground color and drawing over the old shape. For example, let's say we had a white circle drawn on a black background. If we wanted to erase that white circle, we would change the foreground color to black, then re-draw that same circle. Below is an example of how this is done in code:

Graphics_Context g_sContext;


// Initialization

Graphics_setBackgroundColor(&g_sContext, GRAPHICS_COLOR_BLACK);

Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_WHITE);


// Draw the circle

Graphics_fillCircle(&g_sContext, 63, 63, 20);


// Erase the circle

Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_BLACK);

Graphics_fillCircle(&g_sContext, 63, 63, 20); // Notice that the parameters are exactly the same

Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_WHITE); // Don't forget this step!

After you are done erasing shapes, it is generally a good idea to immediately change the foreground color back to its original state.

If you want to "move" a shape, you will have to erase that shape, then redraw it at its new position. Sometimes, this new position can partially overlap the old position. As a general tip, it's better to erase the old shape before drawing the new one, or else you will accidentally erase parts of the new shape. The following demo demonstrates what happens if you draw new shapes before erasing the old ones:

https://github.com/ECE2564-VT/LCD_eraseDemo

Circles, rectangles, and lines cover the basics of drawing shapes on the LCD, and that knowledge will be enough to complete projects in this course. For the curious and advanced, though, you can utilize clipping regions to make shapes like semicircles or quarter-circles. A clipping region is an area where graphics drawn outside of its boundaries are "clipped" and not drawn.

By default, the clipping region is the 128x128 area of the LCD screen. Naturally, drawing shapes outside of this area will cause only the parts that are within the boundaries to be drawn. For example, drawing a circle whose center is at the top-right corner of the LCD will result in a quarter-circle rather than the entire circle. This is because that quarter-circle is the only part of the full circle that falls within the clipping region (and also because there isn't any physical space on the screen to draw the rest of the circle).

The graphics library provides a function to readjust the clipping region and shrink it to a size smaller than 128x128. Adjusting the clipping region further limits how new graphics are drawn, but it has no effect on shapes that were drawn beforehand. Thus, we can make our own quarter-circles and other circle-like shapes by utilizing the clipping region.

To set the clipping region, we can use the following function from the grlib.h file:

The function takes a pointer to a Graphics_Context as well as a pointer to a Graphics_Rectangle. The context is self-explanatory, but the rectangle is used to specify the boundaries of the clipping region. The following demo shows how to make quarter-circles and semicircles using the clipping regions:

https://github.com/ECE2564-VT/LCD_clipRegionDemo