@@ -3403,98 +3403,112 @@ void ImageDrawPixelV(Image *dst, Vector2 position, Color color)
3403
3403
// Draw line within an image
3404
3404
void ImageDrawLine (Image * dst , int startPosX , int startPosY , int endPosX , int endPosY , Color color )
3405
3405
{
3406
- // Using Bresenham's algorithm as described in
3407
- // Drawing Lines with Pixels - Joshua Scott - March 2012
3408
- // https://classic.csunplugged.org/wp-content/uploads/2014/12/Lines.pdf
3406
+ // Calculate differences in coordinates
3407
+ int shortLen = endPosY - startPosY ;
3408
+ int longLen = endPosX - startPosX ;
3409
+ bool yLonger = false;
3409
3410
3410
- int changeInX = (endPosX - startPosX );
3411
- int absChangeInX = (changeInX < 0 )? - changeInX : changeInX ;
3412
- int changeInY = (endPosY - startPosY );
3413
- int absChangeInY = (changeInY < 0 )? - changeInY : changeInY ;
3411
+ // Determine if the line is more vertical than horizontal
3412
+ if (abs (shortLen ) > abs (longLen ))
3413
+ {
3414
+ // Swap the lengths if the line is more vertical
3415
+ int temp = shortLen ;
3416
+ shortLen = longLen ;
3417
+ longLen = temp ;
3418
+ yLonger = true;
3419
+ }
3414
3420
3415
- int startU , startV , endU , stepV ; // Substitutions, either U = X, V = Y or vice versa. See loop at end of function
3416
- //int endV; // Not needed but left for better understanding, check code below
3417
- int A , B , P ; // See linked paper above, explained down in the main loop
3418
- int reversedXY = (absChangeInY < absChangeInX );
3421
+ // Initialize variables for drawing loop
3422
+ int endVal = longLen ;
3423
+ int sgnInc = 1 ;
3419
3424
3420
- if (reversedXY )
3425
+ // Adjust direction increment based on longLen sign
3426
+ if (longLen < 0 )
3421
3427
{
3422
- A = 2 * absChangeInY ;
3423
- B = A - 2 * absChangeInX ;
3424
- P = A - absChangeInX ;
3428
+ longLen = - longLen ;
3429
+ sgnInc = -1 ;
3430
+ }
3425
3431
3426
- if ( changeInX > 0 )
3427
- {
3428
- startU = startPosX ;
3429
- startV = startPosY ;
3430
- endU = endPosX ;
3431
- //endV = endPosY;
3432
- }
3433
- else
3432
+ // Calculate fixed-point increment for shorter length
3433
+ int decInc = ( longLen == 0 )? 0 : ( shortLen << 16 ) / longLen ;
3434
+
3435
+ // Draw the line pixel by pixel
3436
+ if ( yLonger )
3437
+ {
3438
+ // If line is more vertical, iterate over y-axis
3439
+ for ( int i = 0 , j = 0 ; i != endVal ; i += sgnInc , j += decInc )
3434
3440
{
3435
- startU = endPosX ;
3436
- startV = endPosY ;
3437
- endU = startPosX ;
3438
- //endV = startPosY;
3439
-
3440
- // Since start and end are reversed
3441
- changeInX = - changeInX ;
3442
- changeInY = - changeInY ;
3441
+ // Calculate pixel position and draw it
3442
+ ImageDrawPixel (dst , startPosX + (j >>16 ), startPosY + i , color );
3443
3443
}
3444
-
3445
- stepV = (changeInY < 0 )? -1 : 1 ;
3446
-
3447
- ImageDrawPixel (dst , startU , startV , color ); // At this point they are correctly ordered...
3448
3444
}
3449
3445
else
3450
3446
{
3451
- A = 2 * absChangeInX ;
3452
- B = A - 2 * absChangeInY ;
3453
- P = A - absChangeInY ;
3454
-
3455
- if (changeInY > 0 )
3456
- {
3457
- startU = startPosY ;
3458
- startV = startPosX ;
3459
- endU = endPosY ;
3460
- //endV = endPosX;
3461
- }
3462
- else
3447
+ // If line is more horizontal, iterate over x-axis
3448
+ for (int i = 0 , j = 0 ; i != endVal ; i += sgnInc , j += decInc )
3463
3449
{
3464
- startU = endPosY ;
3465
- startV = endPosX ;
3466
- endU = startPosY ;
3467
- //endV = startPosX;
3468
-
3469
- // Since start and end are reversed
3470
- changeInX = - changeInX ;
3471
- changeInY = - changeInY ;
3450
+ // Calculate pixel position and draw it
3451
+ ImageDrawPixel (dst , startPosX + i , startPosY + (j >>16 ), color );
3472
3452
}
3453
+ }
3454
+ }
3455
+
3456
+ // Draw line within an image (Vector version)
3457
+ void ImageDrawLineV (Image * dst , Vector2 start , Vector2 end , Color color )
3458
+ {
3459
+ // Round start and end positions to nearest integer coordinates
3460
+ int x1 = (int )(start .x + 0.5f );
3461
+ int y1 = (int )(start .y + 0.5f );
3462
+ int x2 = (int )(end .x + 0.5f );
3463
+ int y2 = (int )(end .y + 0.5f );
3464
+
3465
+ // Draw a vertical line using ImageDrawLine function
3466
+ ImageDrawLine (dst , x1 , y1 , x2 , y2 , color );
3467
+ }
3473
3468
3474
- stepV = (changeInX < 0 )? -1 : 1 ;
3469
+ // Draw a line defining thickness within an image
3470
+ void ImageDrawLineEx (Image * dst , Vector2 start , Vector2 end , int thick , Color color )
3471
+ {
3472
+ // Round start and end positions to nearest integer coordinates
3473
+ int x1 = (int )(start .x + 0.5f );
3474
+ int y1 = (int )(start .y + 0.5f );
3475
+ int x2 = (int )(end .x + 0.5f );
3476
+ int y2 = (int )(end .y + 0.5f );
3475
3477
3476
- ImageDrawPixel (dst , startV , startU , color ); // ... but need to be reversed here. Repeated in the main loop below
3477
- }
3478
+ // Calculate differences in x and y coordinates
3479
+ int dx = x2 - x1 ;
3480
+ int dy = y2 - y1 ;
3481
+
3482
+ // Draw the main line between (x1, y1) and (x2, y2)
3483
+ ImageDrawLine (dst , x1 , y1 , x2 , y2 , color );
3478
3484
3479
- // We already drew the start point. If we started at startU + 0, the line would be crooked and too short
3480
- for ( int u = startU + 1 , v = startV ; u <= endU ; u ++ )
3485
+ // Determine if the line is more horizontal or vertical
3486
+ if ( dx != 0 && abs ( dy / dx ) < 1 )
3481
3487
{
3482
- if (P >= 0 )
3488
+ // Line is more horizontal
3489
+ // Calculate half the width of the line
3490
+ int wy = (thick - 1 )* sqrtf (dx * dx + dy * dy )/(2 * abs (dx ));
3491
+
3492
+ // Draw additional lines above and below the main line
3493
+ for (int i = 1 ; i <= wy ; i ++ )
3483
3494
{
3484
- v += stepV ; // Adjusts whenever we stray too far from the direct line. Details in the linked paper above
3485
- P += B ; // Remembers that we corrected our path
3495
+ ImageDrawLine ( dst , x1 , y1 - i , x2 , y2 - i , color ); // Draw above the main line
3496
+ ImageDrawLine ( dst , x1 , y1 + i , x2 , y2 + i , color ); // Draw below the main line
3486
3497
}
3487
- else P += A ; // Remembers how far we are from the direct line
3488
-
3489
- if (reversedXY ) ImageDrawPixel (dst , u , v , color );
3490
- else ImageDrawPixel (dst , v , u , color );
3491
3498
}
3492
- }
3499
+ else if (dy != 0 )
3500
+ {
3501
+ // Line is more vertical or perfectly horizontal
3502
+ // Calculate half the width of the line
3503
+ int wx = (thick - 1 )* sqrtf (dx * dx + dy * dy )/(2 * abs (dy ));
3493
3504
3494
- // Draw line within an image (Vector version)
3495
- void ImageDrawLineV (Image * dst , Vector2 start , Vector2 end , Color color )
3496
- {
3497
- ImageDrawLine (dst , (int )start .x , (int )start .y , (int )end .x , (int )end .y , color );
3505
+ // Draw additional lines to the left and right of the main line
3506
+ for (int i = 1 ; i <= wx ; i ++ )
3507
+ {
3508
+ ImageDrawLine (dst , x1 - i , y1 , x2 - i , y2 , color ); // Draw left of the main line
3509
+ ImageDrawLine (dst , x1 + i , y1 , x2 + i , y2 , color ); // Draw right of the main line
3510
+ }
3511
+ }
3498
3512
}
3499
3513
3500
3514
// Draw circle within an image
0 commit comments