ImageDrawLine shortened significantly using maths
Substituted X and Y, then wrote one abstract loop instead of 4 specific loops. Lots of comments to explain what I'm doing for future maintainers.
This commit is contained in:
parent
6a01c3f31a
commit
83d0974525
151
src/textures.c
151
src/textures.c
|
|
@ -2426,129 +2426,92 @@ void ImageDrawLine (Image *dst, int startPosX, int startPosY, int endPosX, int e
|
||||||
int changeInY = (endPosY - startPosY);
|
int changeInY = (endPosY - startPosY);
|
||||||
int abs_changeInY = changeInY < 0 ? -changeInY : changeInY;
|
int abs_changeInY = changeInY < 0 ? -changeInY : changeInY;
|
||||||
|
|
||||||
if (abs_changeInY < abs_changeInX)
|
int startU, startV, endU, V_step; // Substitutions, either U = X, V = Y or vice versa. See loop at end of function
|
||||||
|
//int endV; // We never need this, i didn't just forget about it! :D
|
||||||
|
// For understanding I left it in below, too.
|
||||||
|
|
||||||
|
int A, B, P; // See linked paper above. Explained down in the main loop.
|
||||||
|
|
||||||
|
int is_x_y_reversed = (abs_changeInY < abs_changeInX);
|
||||||
|
|
||||||
|
if (is_x_y_reversed)
|
||||||
{
|
{
|
||||||
|
A = 2* abs_changeInY;
|
||||||
|
B = A - 2* abs_changeInX;
|
||||||
|
P = A - abs_changeInX;
|
||||||
|
|
||||||
if (changeInX > 0)
|
if (changeInX > 0)
|
||||||
{
|
{
|
||||||
// we need to go up or down depending (-1 or 1);
|
startU = startPosX;
|
||||||
int y_directional_unit = changeInY < 0 ? -1 : 1;
|
startV = startPosY;
|
||||||
|
endU = endPosX;
|
||||||
int A = 2* abs_changeInY;
|
//endV = endPosY;
|
||||||
int B = A - 2* abs_changeInX;
|
|
||||||
int P = A - abs_changeInX;
|
|
||||||
|
|
||||||
ImageDrawPixel(dst, startPosX, startPosY, color);
|
|
||||||
|
|
||||||
for (int x = startPosX+1, y = startPosY; x <= endPosX; x += 1)
|
|
||||||
{
|
|
||||||
if (P >= 0)
|
|
||||||
{
|
|
||||||
y += y_directional_unit;
|
|
||||||
P += B;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P += A;
|
startU = endPosX;
|
||||||
}
|
startV = endPosY;
|
||||||
ImageDrawPixel(dst, x, y, color);
|
endU = startPosX;
|
||||||
}
|
//endV = startPosY;
|
||||||
}
|
|
||||||
else
|
// since start and end are reversed:
|
||||||
{
|
|
||||||
// doing the equivalent of "calling" the branch above with inverted parameters:
|
|
||||||
changeInX = -changeInX;
|
changeInX = -changeInX;
|
||||||
changeInY = -changeInY;
|
changeInY = -changeInY;
|
||||||
int help;
|
}
|
||||||
help = startPosX;
|
|
||||||
startPosX = endPosX;
|
|
||||||
endPosX = help;
|
|
||||||
help = startPosY;
|
|
||||||
startPosY = endPosY;
|
|
||||||
endPosY = help;
|
|
||||||
|
|
||||||
int y_directional_unit = changeInY < 0 ? -1 : 1;
|
V_step = changeInY < 0 ? -1 : 1;
|
||||||
|
|
||||||
int A = 2* abs_changeInY;
|
ImageDrawPixel(dst, startU, startV, color); // At this point they are correctly ordered...
|
||||||
int B = A - 2* abs_changeInX;
|
}
|
||||||
int P = A - abs_changeInX;
|
else // all X and Y are reversed in here:
|
||||||
|
{
|
||||||
|
A = 2* abs_changeInX;
|
||||||
|
B = A - 2* abs_changeInY;
|
||||||
|
P = A - abs_changeInY;
|
||||||
|
|
||||||
ImageDrawPixel(dst, startPosX, startPosY, color);
|
|
||||||
|
|
||||||
for (int x = startPosX+1, y = startPosY; x <= endPosX; x += 1)
|
|
||||||
{
|
|
||||||
if (P >= 0)
|
|
||||||
{
|
|
||||||
y += y_directional_unit;
|
|
||||||
P += B;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
P += A;
|
|
||||||
}
|
|
||||||
ImageDrawPixel(dst, x, y, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (changeInY > 0)
|
if (changeInY > 0)
|
||||||
{
|
{
|
||||||
int x_directional_unit = changeInX < 0 ? -1 : 1;
|
startU = startPosY;
|
||||||
|
startV = startPosX;
|
||||||
int A = 2* abs_changeInX;
|
endU = endPosY;
|
||||||
int B = A - 2* abs_changeInY;
|
//endV = endPosX;
|
||||||
int P = A - abs_changeInY;
|
|
||||||
|
|
||||||
ImageDrawPixel(dst, startPosX, startPosY, color);
|
|
||||||
|
|
||||||
for (int y = startPosY+1, x = startPosX; y <= endPosY; y += 1)
|
|
||||||
{
|
|
||||||
if (P >= 0)
|
|
||||||
{
|
|
||||||
x += x_directional_unit;
|
|
||||||
P += B;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P += A;
|
startU = endPosY;
|
||||||
}
|
startV = endPosX;
|
||||||
ImageDrawPixel(dst, x, y, color);
|
endU = startPosY;
|
||||||
}
|
//endV = startPosX;
|
||||||
}
|
|
||||||
else
|
// since start and end are reversed:
|
||||||
{
|
|
||||||
// doing the equivalent of "calling" the branch above with inverted parameters:
|
|
||||||
changeInX = -changeInX;
|
changeInX = -changeInX;
|
||||||
changeInY = -changeInY;
|
changeInY = -changeInY;
|
||||||
int help;
|
}
|
||||||
help = startPosX;
|
|
||||||
startPosX = endPosX;
|
|
||||||
endPosX = help;
|
|
||||||
help = startPosY;
|
|
||||||
startPosY = endPosY;
|
|
||||||
endPosY = help;
|
|
||||||
|
|
||||||
int x_directional_unit = changeInX < 0 ? -1 : 1;
|
V_step = changeInX < 0 ? -1 : 1;
|
||||||
|
|
||||||
int A = 2* abs_changeInX;
|
ImageDrawPixel(dst, startV, startU, color); // ... but need to be reversed here. Repeated in the main loop below.
|
||||||
int B = A - 2* abs_changeInY;
|
}
|
||||||
int P = A - abs_changeInY;
|
|
||||||
|
|
||||||
ImageDrawPixel(dst, startPosX, startPosY, color);
|
// We already drew the start point. If we started at startU+0, the line would be crooked and too short.
|
||||||
|
for (int U = startU+1, V = startV; U <= endU; U += 1)
|
||||||
for (int y = startPosY+1, x = startPosX; y <= endPosY; y += 1)
|
|
||||||
{
|
{
|
||||||
if (P >= 0)
|
if (P >= 0)
|
||||||
{
|
{
|
||||||
x += x_directional_unit;
|
V += V_step; // Adjusts whenever we stray too far from the direct line. Details in the linked paper above.
|
||||||
P += B;
|
P += B; // Remembers that we corrected our path.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P += A;
|
P += A; // Remembers how far we are from the direct line.
|
||||||
}
|
}
|
||||||
ImageDrawPixel(dst, x, y, color);
|
if (is_x_y_reversed) // Substitutions may be in wrong order for drawing:
|
||||||
|
{
|
||||||
|
ImageDrawPixel(dst, U, V, color);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImageDrawPixel(dst, V, U, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user