Author Topic: SUB thickLine  (Read 1453 times)

0 Members and 1 Guest are viewing this topic.

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2935
  • Let it go, this too shall pass.
    • QB64.org
SUB thickLine
« on: February 25, 2018, 05:56:05 PM »
This can be used to draw a line with a specified lineWidth%:

Code: QB64: [Select]
  1. SUB thickLine (x1!, y1!, x2!, y2!, lineWidth%)
  2.     DIM angle%, distance%, halfThickness%
  3.     angle% = INT(_R2D(_ATAN2(y2! - y1!, x2! - x1!)))
  4.     distance% = _HYPOT((x2! - x1!), (y2! - y1!))
  5.     halfThickness% = lineWidth% / 2
  6.     IF halfThickness% < 1 THEN halfThickness% = 1
  7.     IF halfThickness% = 1 THEN
  8.         DRAW "bm" + STR$(x1!) + "," + STR$(y1!) + " TA" + STR$(-angle%) + " R" + STR$(distance%)
  9.     ELSE
  10.         DRAW "bm" + STR$(x1!) + "," + STR$(y1!) + " TA" + STR$(-angle%) + "U" + STR$(halfThickness%) + " R" + STR$(distance%) + "D" + STR$(halfThickness% * 2) + " L" + STR$(distance%) + "U" + STR$(halfThickness%) + " B R" + STR$(distance% / 2) + "P" + STR$(_DEFAULTCOLOR) + "," + STR$(_DEFAULTCOLOR)
  11.     END IF

Sample code using the method:
Code: QB64: [Select]
  1. CONST false = 0, true = NOT false
  2.  
  3. DIM x1, y1, x2, y2
  4. DIM mouseDown AS _BYTE
  5. DIM totalDots AS INTEGER
  6. DIM thickness AS INTEGER
  7.  
  8. thickness = 10
  9.  
  10. SCREEN _NEWIMAGE(800, 600, 32)
  11.  
  12.     WHILE _MOUSEINPUT: thickness = thickness + _MOUSEWHEEL: WEND
  13.  
  14.     IF thickness < 1 THEN thickness = 1
  15.  
  16.         IF NOT mouseDown THEN
  17.             mouseDown = true
  18.             totalDots = totalDots + 1
  19.             IF totalDots > 2 THEN totalDots = 1
  20.             SELECT CASE totalDots
  21.                 CASE 1
  22.                     x1 = _MOUSEX
  23.                     y1 = _MOUSEY
  24.                 CASE 2
  25.                     x2 = _MOUSEX
  26.                     y2 = _MOUSEY
  27.             END SELECT
  28.         END IF
  29.     ELSE
  30.         mouseDown = false
  31.     END IF
  32.  
  33.     CLS
  34.     PRINT "Click to set the initial line coordinate,"
  35.     PRINT "click again to set the final line coordinate."
  36.     PRINT "Use the mousewheel to make the line thicker/thinner."
  37.     PRINT "Current thickness:"; thickness
  38.  
  39.     IF totalDots = 1 THEN
  40.         PSET (x1, y1)
  41.     ELSE
  42.         thickLine x1, y1, x2, y2, thickness
  43.     END IF
  44.     _DISPLAY
  45.     _LIMIT 30
  46.  
  47. SUB thickLine (x1!, y1!, x2!, y2!, lineWidth%)
  48.     DIM angle%, distance%, halfThickness%
  49.     angle% = INT(_R2D(_ATAN2(y2! - y1!, x2! - x1!)))
  50.     distance% = _HYPOT((x2! - x1!), (y2! - y1!))
  51.     halfThickness% = lineWidth% / 2
  52.     IF halfThickness% < 1 THEN halfThickness% = 1
  53.     IF halfThickness% = 1 THEN
  54.         DRAW "bm" + STR$(x1!) + "," + STR$(y1!) + " TA" + STR$(-angle%) + " R" + STR$(distance%)
  55.     ELSE
  56.         DRAW "bm" + STR$(x1!) + "," + STR$(y1!) + " TA" + STR$(-angle%) + "U" + STR$(halfThickness%) + " R" + STR$(distance%) + "D" + STR$(halfThickness% * 2) + " L" + STR$(distance%) + "U" + STR$(halfThickness%) + " B R" + STR$(distance% / 2) + "P" + STR$(_DEFAULTCOLOR) + "," + STR$(_DEFAULTCOLOR)
  57.     END IF

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2935
  • Let it go, this too shall pass.
    • QB64.org
Re: SUB thickLine
« Reply #1 on: February 25, 2018, 06:12:00 PM »
Same idea, different method. This version of the SUB uses _MAPTRIANGLE to achieve similar results. You can replace this in the sample above and it'll work as expected:

Code: QB64: [Select]
  1. SUB thickLine (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE, lineWeight%)
  2.     DIM a AS SINGLE, x0 AS SINGLE, y0 AS SINGLE
  3.     DIM prevDest AS LONG, prevColor AS _UNSIGNED LONG
  4.     STATIC colorSample AS LONG
  5.  
  6.     IF colorSample = 0 THEN
  7.         colorSample = _NEWIMAGE(1, 1, 32)
  8.     END IF
  9.  
  10.     prevDest = _DEST
  11.     prevColor = _DEFAULTCOLOR
  12.     _DEST colorSample
  13.     PSET (0, 0), prevColor
  14.     _DEST prevDest
  15.  
  16.     a = _ATAN2(y2 - y1, x2 - x1)
  17.     a = a + _PI / 2
  18.     x0 = 0.5 * lineWeight% * COS(a)
  19.     y0 = 0.5 * lineWeight% * SIN(a)
  20.  
  21.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), colorSample TO(x1 - x0, y1 - y0)-(x1 + x0, y1 + y0)-(x2 + x0, y2 + y0), , _SMOOTH
  22.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), colorSample TO(x1 - x0, y1 - y0)-(x2 + x0, y2 + y0)-(x2 - x0, y2 - y0), , _SMOOTH

This is the same method Ashish and I used for p5js.bas
« Last Edit: February 25, 2018, 06:21:16 PM by FellippeHeitor »

Offline Pete

  • Forum Resident
  • Posts: 2567
  • Cuz I sez so, varmint!
Re: SUB thickLine
« Reply #2 on: February 25, 2018, 06:50:40 PM »
How about underlined letters? SmallBASIC for Android has that, oooh and italics! I can't recall if this was ever added to QB64 or not. I  recall making something close to this for a graphics GUI that had http hypertext I wanted underlined. Hmmm, maybe I need to go dig that one up.

Atari BASIC actually had a very easy way to customize the 8x8 pixel grid of each ASCII character, so you could make your own underline characters very easily, although italics would be a lot more work involved.

Pete :)

PS The mouse wheel was a nice effect!

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2935
  • Let it go, this too shall pass.
    • QB64.org
Re: SUB thickLine
« Reply #3 on: February 25, 2018, 07:05:19 PM »
PS The mouse wheel was a nice effect!

Thanks, Pete!