Draw a filled rectangle in a random angle.

Tips/comments? Please use : drommels at zondag dot org

 
Extension of the ADAfruit GFX-library for TFT display’s.

Keywords: Arduino, ADAfruit, GFX-library, rectangle, fillTriangle

First the theoretical part of the story.

To draw a line from x0,y0 to x1,y1 we use the function:

drawline(x0,y0,x1,y1,color);

The result is a 1 pixel wide line.

To make a line that has twice or more of this thickness it gets tricky. My first thought was to draw extra lines on a ‘smart’ way by adding 1 to the x-values and/or y-values. In practice this gives strange results and is not a satisfactory solution so I started a search for the solution.

The clue came (of course) from the adafruit forum. Someone made a note about using the filled triangle function for this purpose. As you can see in the figure below, the combination of triangle RED and triangle GREEN is indeed a rectangle in the right angle.

floating_rectangle.jpg

The coordinates x0,y0 and x1,y1 are known and thanks a mix from Pythagoras law, arctan and Fanny’s mathematical knowledge this results in the formulas:

x0,y0 = given coordinates
x1,y1 = given coordinates
D = given width of the rectangle
dx = difference between x0 and xa/xb and between x1 and xc, xd
dy = difference between x0 and ya/yb and between y1 and yc, yd

With this formula it is easy to calculate the coordinates in red (xa,ya ….. xd,yd):

xa=x0-dx, ya=y0-dy etc.

And draw a couple of filled triangle by making use of these results.

Examples

To show the rectangles (left figure below) they are not filled in this example, the colored dots represent x0,y0 and x1,x2.
The right picture shows filled triangles. To fill the gaps between the rectangles filled circles are drawn on the x0,y0 and x1,y1 with half the given size.

rectangle_constructed_with_triangel  rectangle_filled_with_circel

Used Hardware and Software

Display: 3.95” mcfriend, ili9488 based on Arduino Mega. Afafruit GFX library and a graph library (under contruction) to draw the coordinate systems.

Translated this in C++ code

 

/* plot a filled rectangle in any angle by defining origin, destination and size */

void Graph::draw_rectangle(int x0, int y0, int x1, int y1, int size, word color)

{

      // thanks to Fanny... *********************

      int dif_x = x1 - x0;                           // numerator of the formula for dy

      int dif_y = y1 - y0;                           // numerator for dx

      float sqr = sqrt(dif_x*dif_x + dif_y*dif_y);   // denominator of the formulas

      int dx = (size / 2.0) * dif_y / sqr;           // multiply the fraction with half the width of the rectangle

      int dy = (size / 2.0) * dif_x / sqr;                 // the same for

      // ****************************************

      tft.fillTriangle(x0 + dx, y0 - dy, x0 - dx, y0 + dy, x1 + dx, y1 - dy, color);

      tft.fillTriangle(x0 - dx, y0 + dy, x1 - dx, y1 + dy, x1 + dx, y1 - dy, color);

}