diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-08-03 21:49:31 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-08-03 21:49:31 +0000 |
commit | 2dbf43396ef13cf1f6870631edbe399b12d5d07a (patch) | |
tree | 5adc239ba2ea9d6b8cbaa46aedc732c3e95a51a0 /nuttx/graphics/nxglib | |
parent | 4a934b34d9f91e136d417551111a2c06b1f5c327 (diff) | |
download | px4-nuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.tar.gz px4-nuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.tar.bz2 px4-nuttx-2dbf43396ef13cf1f6870631edbe399b12d5d07a.zip |
Fix numerous errors in trapezoid rendering and wide line drawing algorithms
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3841 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/graphics/nxglib')
-rw-r--r-- | nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c | 24 | ||||
-rw-r--r-- | nuttx/graphics/nxglib/nxglib_splitline.c | 42 |
2 files changed, 43 insertions, 23 deletions
diff --git a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c index 970bbf829..faeebbec7 100644 --- a/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c +++ b/nuttx/graphics/nxglib/lcd/nxglib_filltrapezoid.c @@ -191,12 +191,16 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) /* Fill the run buffer for the maximum run that we will need */ - ix1 = ngl_clipl(b16toi(topx1), bounds->pt1.x); - ix2 = ngl_clipl(b16toi(topx2), bounds->pt2.x); + ix1 = b16toi(topx1); + ix1 = ngl_clipl(ix1, bounds->pt1.x); + ix2 = b16toi(topx2); + ix2 = ngl_clipr(ix2, bounds->pt2.x); ncols = ix2 - ix1 + 1; - ix1 = ngl_clipl(b16toi(botx1), bounds->pt1.x); - ix2 = ngl_clipl(b16toi(botx2), bounds->pt2.x); + ix1 = b16toi(botx1); + ix1 = ngl_clipl(ix1, bounds->pt1.x); + ix2 = b16toi(botx2); + ix2 = ngl_clipr(ix2, bounds->pt2.x); botw = ix2 - ix1 + 1; if (ncols < botw) @@ -206,7 +210,7 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) NXGL_FUNCNAME(nxgl_fillrun,NXGLIB_SUFFIX)((NXGLIB_RUNTYPE*)pinfo->buffer, color, ncols); - /* Then fill the trapezoid line-by-line */ + /* Then fill the trapezoid row-by-row */ for (row = topy; row <= boty; row++) { @@ -219,12 +223,14 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) ngl_swap(dx1dy, dx2dy, tmp); } - /* Convert the positions to integer and get the run width, - * clipping to fit within the bounding box. + /* Convert the positions to integer and get the run width, clipping to + * fit within the bounding box. */ - ix1 = ngl_clipl(b16toi(topx1), bounds->pt1.x); - ix2 = ngl_clipl(b16toi(topx2), bounds->pt2.x); + ix1 = b16toi(topx1); + ix1 = ngl_clipl(ix1, bounds->pt1.x); + ix2 = b16toi(topx2); + ix2 = ngl_clipr(ix2, bounds->pt2.x); /* Handle some corner cases where we draw nothing. Otherwise, we will * always draw at least one pixel. diff --git a/nuttx/graphics/nxglib/nxglib_splitline.c b/nuttx/graphics/nxglib/nxglib_splitline.c index eb2906e3f..31d6949ad 100644 --- a/nuttx/graphics/nxglib/nxglib_splitline.c +++ b/nuttx/graphics/nxglib/nxglib_splitline.c @@ -121,6 +121,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, b16_t xoffset; b16_t halfoffset; b16_t angle; + b16_t sinangle; b16_t b16x; /* First, check the linewidth */ @@ -193,12 +194,12 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, { /* A line of width 1 is basically a single parallelogram of width 1 */ - traps[1].top.x1 = line.pt1.x; - traps[1].top.x2 = line.pt1.x; + traps[1].top.x1 = itob16(line.pt1.x); + traps[1].top.x2 = traps[1].top.x1; traps[1].top.y = line.pt1.y; - traps[1].bot.x1 = line.pt2.x; - traps[1].bot.x2 = line.pt2.x; + traps[1].bot.x1 = itob16(line.pt2.x); + traps[1].bot.x2 = traps[1].bot.x1; traps[1].bot.y = line.pt2.y; return 1; } @@ -219,21 +220,34 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, iwidth = line.pt1.x - line.pt2.x + 1; } - /* - * Triangle height: linewidth * cosA + /* Triangle height: linewidth * cosA * Adjusted width: triheight / sinA * X offset : linewidth * linewidth / adjusted line width */ angle = b16atan2(itob16(iheight), itob16(iwidth)); triheight = b16toi(linewidth * b16cos(angle)); - adjwidth = b16divb16(itob16(linewidth), b16sin(angle)); - xoffset = itob16(linewidth * linewidth); - xoffset = b16divb16(xoffset, adjwidth); - - halfoffset = (xoffset >> 1); halfheight = (triheight >> 1); + /* If the sine of the angle is tiny (i.e., the line is nearly horizontal), + * then we cannot compute the adjusted width. In this case, just use + * the width of the line (not very good estimate -- need to revisit). + */ + + sinangle = b16sin(angle); + if (sinangle == 0) + { + adjwidth = itob16(iwidth); + xoffset = adjwidth; + } + else + { + adjwidth = b16divb16(itob16(linewidth), sinangle); + xoffset = itob16(linewidth * linewidth); + xoffset = b16divb16(xoffset, adjwidth); + } + halfoffset = (xoffset >> 1); + /* Return the top triangle (if there is one). NOTE that the horizontal * (z) positions are represented with 16 bits of fraction. The vertical * (y) positions, on the other hand, are integer. @@ -256,7 +270,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, traps[0].bot.y = iy; b16x = itob16(line.pt2.x) + halfoffset; - iy = itob16(line.pt2.y) - halfheight; + iy = line.pt2.y - halfheight; traps[2].top.x1 = b16x - adjwidth + b16ONE; traps[2].top.x2 = b16x; @@ -270,7 +284,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, /* Line is going "south west" */ b16x = itob16(line.pt1.x) + halfoffset; - iy = itob16(line.pt1.y) + halfheight; + iy = line.pt1.y + halfheight; traps[0].top.x1 = b16x - xoffset; traps[0].top.x2 = traps[0].top.x1; @@ -280,7 +294,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, traps[0].bot.y = iy; b16x = itob16(line.pt2.x) - halfoffset; - iy = itob16(line.pt2.y) - halfheight; + iy = line.pt2.y - halfheight; traps[2].top.x1 = b16x; traps[2].top.x2 = b16x + adjwidth - b16ONE; |