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

0 Members and 1 Guest are viewing this topic.

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 + ...
    • View Profile
Re: Xiaolin Wu's antialiased line algorithm
« Reply #1 on: March 08, 2020, 12:27:36 pm »
  • Best Answer
  • 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 »
  • Best Answer
  • Can you spot the differences between our approaches?

    Offline bplus

    • Global Moderator
    • Forum Resident
    • Posts: 8053
    • b = b + ...
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #3 on: March 08, 2020, 12:36:47 pm »
  • 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 »
  • Best Answer
  • No :-)

    Offline bplus

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

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #6 on: March 08, 2020, 12:38:45 pm »
  • Best Answer
  • 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 »
  • Best Answer
  • I'm after an antialiased circle algorithm as well, will that do it?

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #8 on: March 08, 2020, 12:46:42 pm »
  • Best Answer
  • 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 »
  • Best Answer
  • I only mentioned circles *after* you made that edit.

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #10 on: March 08, 2020, 12:48:53 pm »
  • Best Answer
  • 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 + ...
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #11 on: March 08, 2020, 12:50:51 pm »
  • Best Answer
  • 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 + ...
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #12 on: March 08, 2020, 12:53:30 pm »
  • Best Answer
  • 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 »
  • Best Answer
  • We are always at Discord. *wink wink*

    Offline STxAxTIC

    • Library Staff
    • Forum Resident
    • Posts: 1091
    • he lives
      • View Profile
    Re: Xiaolin Wu's antialiased line algorithm
    « Reply #14 on: March 08, 2020, 01:05:36 pm »
  • Best Answer
  • 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.