New KA fast Thick Line Method!

This is no joke! New method for thick line is a small fraction, (.04+ to .05+), times to draw than my old method. Here is test code:

' poly thick line test.bas SmallBASIC 0.12.8 [B+=MGA] 2017-04-01

const cx = xmax/2
const cy = ymax/2

'new kick butt fast ptline!!!
sub ptline(x1, y1, x2, y2, thick) 'this draws a little rectangle
local arr, r, dx, dy, perpA1, perpA2
dim arr()
r = thick/2
dx = x2 - x1
dy = y2 - y1
perpA1 = atan2(dy, dx) + pi/2
perpA2 = perpA1 - pi
arr << x1 + r * cos(perpA1) 'corner 1
arr << y1 + r * sin(perpA1)
arr << x2 + r * cos(perpA1) 'corner 2
arr << y2 + r * sin(perpA1)
arr << x2 + r * cos(perpA2) 'corner 3
arr << y2 + r * sin(perpA2)
arr << x1 + r * cos(perpA2) 'corner 4
arr << y1 + r * sin(perpA2)
arr << x1 + r * cos(perpA1) 'back to first corner
arr << y1 + r * sin(perpA1)
drawpoly arr filled

'versus MGA's old slow thickLine
sub rtLine(x1, y1, x2, y2, rThick)
'x1, y1 is one endpoint of line
'x2, y2 is the other endpoint of the line
'rThick is the radius of the tiny circles that will be drawn
' from one end point to the other to create the thick line
'Yes, the line will then extend beyond the endpoints with circular ends.

local length, stepx, stepy, dx, dy, i
rThick = int(rThick/2) : stepx = x2 - x1 : stepy = y2 - y1
length = int((stepx ^ 2 + stepy ^ 2) ^.5)
if length then
dx = stepx / length : dy = stepy / length
for i = 0 to length
circle x1 + dx * i, y1 + dy * i, rThick filled
circle x1, y1, rThick filled
end if

'Thanks Andy Amaya!
func tline(x1, y1, x2, y2, pensize)
If penSize < 2 Then Line x1, y1, x2, y2 : Return
' penSize is thickness to draw line
offst = Int(penSize/2) 'offset to center rects
' Calculate deltax and deltay for initialization
deltax = Abs(x2 - x1)
deltay = Abs(y2 - y1)
' Initialize all variables based on which is the independent variable
If deltax >= deltay Then
' x is the independent variable
numRects = deltax + 1
d = Int(deltay/2) - deltax
dinc1 = Int(deltay/2)
dinc2 = Int((deltay - deltax)/2)
xinc1 = 1
xinc2 = 1
yinc1 = 0
yinc2 = 1
' y is the independent variable
numRects = deltay + 1
d = Int(deltax/2) - deltay
dinc1 = Int(deltax/2)
dinc2 = Int((deltax - deltay)/2)
xinc1 = 0
xinc2 = 1
yinc1 = 1
yinc2 = 1
End If
' Make sure x and y move in the right directions
If x1 > x2 Then
xinc1 = -xinc1
xinc2 = -xinc2
End If
If y1 > y2 Then
yinc1 = -yinc1
yinc2 = -yinc2
End If
' Start drawing at x, y
x = x1 - offst
y = y1 - offst
' Draw the filled rects
For i = 1 To numRects
rect x,y, x+pensize, y+pensize
If d < 0 Then
d = d + dinc1
x = x + xinc1
y = y + yinc1
d = d + dinc2
x = x + xinc2
y = y + yinc2
End If

t0 = ticks
c = 1 to 15
color c
for a = 0 to 2 * pi step pi/36
rtline cx, cy, cx + 300 * cos(a), cy + 300 * sin(a), 15
rtTime = ticks - t0
? "MGA's old method for thick line took ";rtTime;" ms to draw this 15 times."
delay 3000
t0 = ticks
c = 1 to 15
color c
for a = 0 to 2 * pi step pi/36
ptline cx, cy, cx + 300 * cos(a), cy + 300 * sin(a), 15
ptTime = ticks - t0
? "MGA's new method for thick line took ";ptTime;" ms to draw this 15 times."
? "New method time / Old method time is ";ptTime / rtTime
delay 3000
t0 = ticks
c = 1 to 15
color c
for a = 0 to 2 * pi step pi/36
tline cx, cy, cx + 300 * cos(a), cy + 300 * sin(a), 15
tTime = ticks - t0
? "Andy's tline method for thick line took ";tTime;" ms to draw this 15 times."
? "Andy's tline time / MGA Old method time is ";tTime / rtTime
? "Andy's tline time / MGA New method time is ";tTime / ptTime

EDIT: I have now included Andy Amaya's Thick Line method fromSdlBasic. His, I think, follows Bresenham's, it is faster than my old method and my new method is 3.6 X's slower at SdlBasic than my old method??? Their polygon must work much differently than our Drawpoly.

That's a great solution to the frequent need for thicker lines, MGA!

Interesting, the different results on SdlBasic. - Ted

Thanks! Yes, most curious SdlBasic difference.

My next target is my hand drawn font updates that really needed a speed boost. For that I will also need a Drawpoly Method for doing arcs. But now there is no urgency because Chris has updated SB for fonts of all sizes. Still it's good practice.

I have been meaning to get back to more musical version of Recording Experiment. I was in bands since 5th grade through 2 years college, playing first flute then trombone, tried some piano too. For me it was a choice of band or art, now I am making up for what I missed in art. ;-))

BTW, may I inquire where you live? I am outside Cleveland, Ohio, USA and you can call me Mark.

Hi Mark! I'm on the Olympic Peninsula, west of Seattle. Born nearby in the town of Forks, the locale of the Twilight story. The La Push students were then bussed from the village, and I was later disturbed to discover that not all schools were composed of 1/3rd Native kids. And dad was born in Roswell, New Mexico.

It may be that SdlBasic, using proven libraries like OpenGL, has a better way to do circles and other figures.

Font-work is worthwhile. DRAW-fonts work, but yeah they get too-thin when bigger. But old DRAW has a COLOR command, which allows some nice touches on compact fonts. The monster Unicode and Font Library installations today, could renew an interest in limited font-creation. As people move back to lower-performance machines, these may be excessive.

I like Junicode. I took a little ancient-language, and explore Old(er) English and Germanic.


OH, with Drawpoly, just create an polyeditor and save letter data that can be scaled and rotated!

No worries about thick lines or arcs! Plus! can use the editor for other figures as well. :-)

(Well arcs might be a problem... hmm...)

BTW, the difference in thick line times between Andy's Method and my old method was entirely due to using filled circles as opposed to filled squares, about 4 times longer.