Improve gdispDrawThickLine() when the line length is short.
This commit is contained in:
parent
f624df29e8
commit
87a7658b57
1 changed files with 23 additions and 2 deletions
|
@ -2587,18 +2587,39 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
|
||||||
|
|
||||||
/* Normalize the normal vector to length width.
|
/* Normalize the normal vector to length width.
|
||||||
* This uses Newton-Raphson to avoid the need for floating point sqrt.
|
* This uses Newton-Raphson to avoid the need for floating point sqrt.
|
||||||
* We try to solve f(div) = div^2 - len/width^2.
|
* We try to solve f(div) = div^2 - len/width^2 = 0.
|
||||||
|
* The closed-form solution is div = sqrt(len) / width.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int32_t div, len, tmp;
|
int32_t div, len, tmp;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
len = nx*nx + ny*ny;
|
len = (int32_t)nx*nx + (int32_t)ny*ny;
|
||||||
div = 100; /* Initial guess for divider; not critical */
|
div = 100; /* Initial guess for divider; not critical */
|
||||||
|
|
||||||
|
/* If the line length is quite short, premultiply the vector
|
||||||
|
* in order to get better accuracy in width. */
|
||||||
|
if (len < 1024)
|
||||||
|
{
|
||||||
|
nx <<= 8;
|
||||||
|
ny <<= 8;
|
||||||
|
len <<= 16;
|
||||||
|
}
|
||||||
|
else if (len < 65536)
|
||||||
|
{
|
||||||
|
nx <<= 4;
|
||||||
|
ny <<= 4;
|
||||||
|
len <<= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prev = div;
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
tmp = width * width * div;
|
tmp = width * width * div;
|
||||||
div -= (tmp * div - len) / (2 * tmp);
|
div -= (tmp * div - len) / (2 * tmp);
|
||||||
|
|
||||||
|
if (div == prev)
|
||||||
|
break; // No change, iteration complete
|
||||||
|
prev = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx = rounding_div(nx, div);
|
nx = rounding_div(nx, div);
|
||||||
|
|
Loading…
Add table
Reference in a new issue