Author Topic: Xiaolin Wu's antialiased line algorithm  (Read 3708 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

FellippeHeitor

  • Guest
Xiaolin Wu's antialiased line algorithm
« on: March 08, 2020, 12:03:58 pm »
SUB lineSmooth (x0, y0, x1, y1, c AS _UNSIGNED LONG), with demo usage below.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3. DIM m$
  4.  
  5.     'bg
  6.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGB32(166, 83, 72), BF
  7.  
  8.     'normal line
  9.     LINE (0, 0)-(_MOUSEX, _MOUSEY), _RGB32(255)
  10.     m$ = "< QB64's regular LINE"
  11.     _PRINTSTRING (_MOUSEX / 2 + 20, _MOUSEY / 2), m$
  12.  
  13.     'line with antialiasing
  14.     lineSmooth _MOUSEX, _MOUSEY, 800, 600, _RGB32(255)
  15.     m$ = "Xiaolin Wu's antialiased line >"
  16.     _PRINTSTRING ((_MOUSEX + 800) / 2 - _PRINTWIDTH(m$) - 20, (_MOUSEY + 600) / 2), m$
  17.  
  18.     _DISPLAY
  19.     _LIMIT 60
  20.  
  21. SUB lineSmooth (x0, y0, x1, y1, c AS _UNSIGNED LONG)
  22.     'translated from
  23.     'https://en.wikipedia.org/w/index.php?title=Xiaolin_Wu%27s_line_algorithm&oldid=852445548
  24.  
  25.     DIM plX AS INTEGER, plY AS INTEGER, plI
  26.  
  27.     DIM steep AS _BYTE
  28.     steep = ABS(y1 - y0) > ABS(x1 - x0)
  29.  
  30.     IF steep THEN
  31.         SWAP x0, y0
  32.         SWAP x1, y1
  33.     END IF
  34.  
  35.     IF x0 > x1 THEN
  36.         SWAP x0, x1
  37.         SWAP y0, y1
  38.     END IF
  39.  
  40.     DIM dx, dy, gradient
  41.     dx = x1 - x0
  42.     dy = y1 - y0
  43.     gradient = dy / dx
  44.  
  45.     IF dx = 0 THEN
  46.         gradient = 1
  47.     END IF
  48.  
  49.     'handle first endpoint
  50.     DIM xend, yend, xgap, xpxl1, ypxl1
  51.     xend = _ROUND(x0)
  52.     yend = y0 + gradient * (xend - x0)
  53.     xgap = (1 - ((x0 + .5) - INT(x0 + .5)))
  54.     xpxl1 = xend 'this will be used in the main loop
  55.     ypxl1 = INT(yend)
  56.     IF steep THEN
  57.         plX = ypxl1
  58.         plY = xpxl1
  59.         plI = (1 - (yend - INT(yend))) * xgap
  60.         GOSUB plot
  61.  
  62.         plX = ypxl1 + 1
  63.         plY = xpxl1
  64.         plI = (yend - INT(yend)) * xgap
  65.         GOSUB plot
  66.     ELSE
  67.         plX = xpxl1
  68.         plY = ypxl1
  69.         plI = (1 - (yend - INT(yend))) * xgap
  70.         GOSUB plot
  71.  
  72.         plX = xpxl1
  73.         plY = ypxl1 + 1
  74.         plI = (yend - INT(yend)) * xgap
  75.         GOSUB plot
  76.     END IF
  77.  
  78.     DIM intery
  79.     intery = yend + gradient 'first y-intersection for the main loop
  80.  
  81.     'handle second endpoint
  82.     DIM xpxl2, ypxl2
  83.     xend = _ROUND(x1)
  84.     yend = y1 + gradient * (xend - x1)
  85.     xgap = ((x1 + .5) - INT(x1 + .5))
  86.     xpxl2 = xend 'this will be used in the main loop
  87.     ypxl2 = INT(yend)
  88.     IF steep THEN
  89.         plX = ypxl2
  90.         plY = xpxl2
  91.         plI = (1 - (yend - INT(yend))) * xgap
  92.         GOSUB plot
  93.  
  94.         plX = ypxl2 + 1
  95.         plY = xpxl2
  96.         plI = (yend - INT(yend)) * xgap
  97.         GOSUB plot
  98.     ELSE
  99.         plX = xpxl2
  100.         plY = ypxl2
  101.         plI = (1 - (yend - INT(yend))) * xgap
  102.         GOSUB plot
  103.  
  104.         plX = xpxl2
  105.         plY = ypxl2 + 1
  106.         plI = (yend - INT(yend)) * xgap
  107.         GOSUB plot
  108.     END IF
  109.  
  110.     'main loop
  111.     DIM x
  112.     IF steep THEN
  113.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  114.             plX = INT(intery)
  115.             plY = x
  116.             plI = (1 - (intery - INT(intery)))
  117.             GOSUB plot
  118.  
  119.             plX = INT(intery) + 1
  120.             plY = x
  121.             plI = (intery - INT(intery))
  122.             GOSUB plot
  123.  
  124.             intery = intery + gradient
  125.         NEXT
  126.     ELSE
  127.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  128.             plX = x
  129.             plY = INT(intery)
  130.             plI = (1 - (intery - INT(intery)))
  131.             GOSUB plot
  132.  
  133.             plX = x
  134.             plY = INT(intery) + 1
  135.             plI = (intery - INT(intery))
  136.             GOSUB plot
  137.  
  138.             intery = intery + gradient
  139.         NEXT
  140.     END IF
  141.  
  142.     EXIT SUB
  143.  
  144.     plot:
  145.     PSET (plX, plY), _RGB32(_RED32(c), _GREEN32(c), _BLUE32(c), plI * 255)
  146.     RETURN
  147.  
« Last Edit: March 08, 2020, 12:11:20 pm by FellippeHeitor »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Xiaolin Wu's antialiased line algorithm
« Reply #1 on: March 08, 2020, 12:27:36 pm »
Ah that reminds of this:
Code: QB64: [Select]
  1. _TITLE "WuLine test, WuLine is white, QB64 line is yellow. Wu is Smoother!" 'B+ 2019-02-25
  2. SCREEN _NEWIMAGE(700, 700, 32)
  3. _SCREENMOVE 300, 20
  4.  
  5. WHILE _KEYDOWN(27) = 0
  6.     CLS
  7.     WuLine 350, 350, 350 + 340 * COS(a), 350 + 340 * SIN(a), _RGB32(255, 255, 255)
  8.     LINE (350, 350)-(350 - 340 * COS(a), 350 - 340 * SIN(a)), _RGB32(255, 255, 0)
  9.     a = a + _PI(2 / 360)
  10.     _DISPLAY
  11.     _LIMIT 5
  12.  
  13. SUB plot (x, y, c AS _UNSIGNED LONG, opaque) 'c is RGB color a level is opaqueness 0 to 1 transparent to solid
  14.     r = _RED32(c): g = _GREEN32(c): b = _BLUE32(c): o = opaque * 255
  15.     PSET (x, y), _RGBA32(r, g, b, o)
  16.  
  17. '// integer part of x
  18. FUNCTION ipart (x)
  19.     ipart = INT(x)
  20.  
  21. FUNCTION round (x)
  22.     round = ipart(x + 0.5)
  23.  
  24. '// fractional part of x
  25. FUNCTION fpart (x)
  26.     fpart = x - INT(x)
  27.  
  28. FUNCTION rfpart (x)
  29.     rfpart = 1 - fpart(x)
  30.  
  31. SUB WuLine (xx0, yy0, xx1, yy1, c AS _UNSIGNED LONG)
  32.     'make copies since swapping values
  33.  
  34.     x0 = xx0: y0 = yy0: x1 = xx1: y1 = yy1
  35.  
  36.     DIM steep AS INTEGER
  37.     steep = ABS(y1 - y0) > ABS(x1 - x0)
  38.  
  39.     IF steep = -1 THEN
  40.         SWAP x0, y0
  41.         SWAP x1, y1
  42.     END IF
  43.     IF x0 > x1 THEN
  44.         SWAP x0, x1
  45.         SWAP y0, y1
  46.     END IF
  47.  
  48.     dx = x1 - x0
  49.     dy = y1 - y0
  50.     gradient = dy / dx
  51.     IF dx = 0.0 THEN
  52.         gradient = 1.0
  53.     END IF
  54.  
  55.     '// handle first endpoint
  56.     xend = round(x0)
  57.     yend = y0 + gradient * (xend - x0)
  58.     xgap = rfpart(x0 + 0.5)
  59.     xpxl1 = xend '// this will be used in the main loop
  60.     ypxl1 = ipart(yend)
  61.     IF steep THEN
  62.         plot ypxl1, xpxl1, c, rfpart(yend) * xgap
  63.         plot ypxl1 + 1, xpxl1, c, fpart(yend) * xgap
  64.     ELSE
  65.         plot xpxl1, ypxl1, c, rfpart(yend) * xgap
  66.         plot xpxl1, ypxl1 + 1, c, fpart(yend) * xgap
  67.     END IF
  68.     intery = yend + gradient '// first y-intersection for the main loop
  69.  
  70.     '// handle second endpoint
  71.     xend = round(x1)
  72.     yend = y1 + gradient * (xend - x1)
  73.     xgap = fpart(x1 + 0.5)
  74.     xpxl2 = xend '//this will be used in the main loop
  75.     ypxl2 = ipart(yend)
  76.     IF steep THEN
  77.         plot ypxl2, xpxl2, c, rfpart(yend) * xgap
  78.         plot ypxl2 + 1, xpxl2, c, fpart(yend) * xgap
  79.     ELSE
  80.         plot xpxl2, ypxl2, c, rfpart(yend) * xgap
  81.         plot xpxl2, ypxl2 + 1, c, fpart(yend) * xgap
  82.     END IF
  83.  
  84.     '// main loop
  85.     IF steep = -1 THEN
  86.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  87.             plot ipart(intery), x, c, rfpart(intery)
  88.             plot ipart(intery) + 1, x, c, fpart(intery)
  89.             intery = intery + gradient
  90.         NEXT
  91.     ELSE
  92.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  93.             plot x, ipart(intery), c, rfpart(intery)
  94.             plot x, ipart(intery) + 1, c, fpart(intery)
  95.             intery = intery + gradient
  96.         NEXT
  97.     END IF
  98.  
  99.  

I used it in a clock and the Search engine here is not linking me to the place I just saw it.

Ah here it is:
https://www.qb64.org/forum/index.php?topic=1083.msg102983#msg102983
« Last Edit: March 08, 2020, 12:32:26 pm by bplus »

FellippeHeitor

  • Guest
Re: Xiaolin Wu's antialiased line algorithm
« Reply #2 on: March 08, 2020, 12:33:23 pm »
Can you spot the differences between our approaches?

Marked as best answer by on May 10, 2024, 09:52:55 am

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Xiaolin Wu's antialiased line algorithm
« Reply #3 on: March 08, 2020, 12:36:47 pm »
  • Undo Best Answer
  • Can you spot the differences between our approaches?

    My translation is shorter ;-)) Can you just summarize I've been all over the place with library work and my brain is scattered to 4 winds.

    FellippeHeitor

    • Guest
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #4 on: March 08, 2020, 12:37:21 pm »
    No :-)

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #5 on: March 08, 2020, 12:37:51 pm »
    OK

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #6 on: March 08, 2020, 12:38:45 pm »
    Interesting. Seems like a lot of work though to just make a line by PSET with transparency.

    Code: QB64: [Select]
    1.   PSET (plX, plY), _RGB32(_RED32(c), _GREEN32(c), _BLUE32(c), plI * 255)

    I might try to make something shorter and name it after myself instead. Until then, let's glorify Xiaolin Wu.

    .... I'll only do it if I can generalize it to curves, how's that?
    « Last Edit: March 08, 2020, 12:45:20 pm by STxAxTIC »
    You're not done when it works, you're done when it's right.

    FellippeHeitor

    • Guest
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #7 on: March 08, 2020, 12:45:45 pm »
    I'm after an antialiased circle algorithm as well, will that do it?

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #8 on: March 08, 2020, 12:46:42 pm »
    Oops I edited as you were responding so it may pass by too fast. But for the sake of not skipping a beat:

    Quote
    .... I'll only do it if I can generalize it to curves, how's that?

    I mean *any* curve...
    You're not done when it works, you're done when it's right.

    FellippeHeitor

    • Guest
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #9 on: March 08, 2020, 12:47:43 pm »
    I only mentioned circles *after* you made that edit.

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #10 on: March 08, 2020, 12:48:53 pm »
    I guess what I'm after is an anti-aliased DRAW. Hm, now you've got me thinking. God I love the forums...
    « Last Edit: March 08, 2020, 12:50:19 pm by STxAxTIC »
    You're not done when it works, you're done when it's right.

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #11 on: March 08, 2020, 12:50:51 pm »
    OK in two minutes of compare I see Fell's WuLine all in one sub 126 lines, convenient!

    My version has 5 supplemental subs that might be used in other places, 90 lines total.


    Antialias circle great goal! I hope you have better luck than I.
    « Last Edit: March 08, 2020, 12:55:01 pm by bplus »

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #12 on: March 08, 2020, 12:53:30 pm »
    Hey is this from conversation at Discourse?

    FellippeHeitor

    • Guest
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #13 on: March 08, 2020, 12:58:56 pm »
    We are always at Discord. *wink wink*

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #14 on: March 08, 2020, 01:05:36 pm »
    Maybe bplus was wondering if somehow Discord was channeling its output here because we were exchanging so fast?

    Not the case. Just two ninjas at work.
    You're not done when it works, you're done when it's right.