Lissajous variation.bas


' Lissajous variation.bas for SmallBASIC 0.12.8 [B+=MGA] 2017-02-21

sc = min(xmax, ymax)/3
xc = xmax/2
yc = ymax/2

m = 1 : n = 1 : p = 1 : q = 1
while 1
m = (rnd * 28)\1
n = q
p = q
q = (rnd*28)\1 + 1
red = rnd : green = rnd : blue = rnd*rnd
for s = 0 to sc*1.05 step .05*sc
cls
color 11
locate 1, 1: ? " m = ";str(m); " n = ";str(n);" p = ";str(p);" q = ";str(q)
lastX = xc : lastY = sc + yc
for t = 0 to 2*pi*(1 + pi/360) step pi/720
c = rgb(127+127*sin(red*1*t), 127+127*sin(green*3*t), 127+127*sin(blue*5*t))
x = (sc-s)*sin(m*t) + 2*s*sin(p*t) + xc
y = (sc-s)*cos(n*t) + s*cos(q*t) + yc
color c
Thickline lastX, lastY, x, y, 5
lastX = x : lastY = y
next
showpage
next
delay 800
wend


sub
ThickLine(x1, y1, x2, y2, rThick)
local length, stepx, stepy, dx, dy, i

'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.

stepx = x2 - x1
stepy = y2 - y1
length = (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
next
end if
end

Thanks, here is encore:


' Electric Lissajous.bas for SmallBASIC 0.12.8 [B+=MGA] 2017-02-22

randomize timer
sc = min(xmax, ymax)/3
xc = xmax/2
yc = ymax/2

m = 1 : n = 1 : p = 1 : q = 1
while 1
m = (rnd * 28)\1
n = q
p = q
q = (rnd*28)\1 + 1
for s = 0 to sc*1.05 step .05*sc
cls
color 11
locate 1, 1: ? " m = ";str(m); " n = ";str(n);" p = ";str(p);" q = ";str(q)
lastX = xc : lastY = sc + yc
for t = 0 to 2*pi*(1 + pi/360) step pi/720
x = (sc-s)*sin(m*t) + 2*s*sin(p*t) + xc
y = (sc-s)*cos(n*t) + s*cos(q*t) + yc
Lightning lastX, lastY, x, y, 30
lastX = x : lastY = y
next
showpage
next
delay 800
wend

sub
Lightning(x1,y1,x2,y2,d)
'Lightning.bas copied from Bpf aurel
'fixed 2017-02-22
local mx, my 'local fix stopped the jagged lines
if d < 5 then
line x1,y1,x2,y2,rgb(200,200,230)
else
mx = (x2+x1)/2
my = (y2+y1)/2
'with or without??
'mx += rnd*.5*d 'fixed the line from turning back on itself
my += (rnd-.5)*d
Lightning x1,y1,mx,my,d/2
Lightning x2,y2,mx,my,d/2
fi
end

Hi MGA & all,

The 'wide-body' line gives the Lissajous a nice style ... line-styles are good thing generally. I soon saw that this code does thick line with CIRCLE, and keeps them spaced real close.

I don't know what happens when we do lines with Bresenham, in SB, but it's supposed to be the last word, when done in 'real' code. And, Bresenham can do it lots of ways other than a plain line.

It's been on my list, to track down guidance on this, and work on my own routines, for making different types of Trails, roads etc, on a map. Like for GPS.

Basic-Bresenham is very compact & simple. Making it thick takes more book-keeping, and this example I'm going to show is from the School of Robust Examples. But it's still not that bad.

http://members.chello.at/~easyfilter/bresenham.html

Several different examples on this page: We're looking at "Anti-aliased thick line".


Anti-aliased thick line

This algorithm draws an anti-aliased line of wd pixel width.

void plotLineWidth((int x0, int y0, int x1, int y1, float wd)
{
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = dx-dy, e2, x2, y2; /* error value e_xy */
float ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);

for (wd = (wd+1)/2; ; ) { /* pixel loop */
setPixelColor(x0,y0,max(0,255*(abs(err-dx+dy)/ed-wd+1)));
e2 = err; x2 = x0;
if (2*e2 >= -dx) { /* x step */
for (e2 += dy, y2 = y0; e2 < ed*wd && (y1 != y2 || dx > dy); e2 += dx)
setPixelColor(x0, y2 += sy, max(0,255*(abs(e2)/ed-wd+1)));
if (x0 == x1) break;
e2 = err; err -= dy; x0 += sx;
}
if (2*e2 <= dy) { /* y step */
for (e2 = dx-e2; e2 < ed*wd && (x1 != x2 || dx < dy); e2 += dy)
setPixelColor(x2 += sx, y0, max(0,255*(abs(e2)/ed-wd+1)));
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
}

Oops. Sorry; it seemed like a good idea, but code doesn't come through well. Code-block does not work the way I thought it would.

I saw other people putting stuff up like this, and thought they didn't know about using code-block. 'This is it', huh?

Ted

https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Hey Ted,

Your link was to something in German??? A quick glance at Wiki has me wondering if the algo only works fattening up lines in x axis direction?

Yes, my circle method is extremely slow but leaves nice round ends and SmallBASIC even as interpreted is pretty fast!

What's with all the {} brackets? Is that JS code?

Code tags on this forum use angle brackets code and /code, I think you have that. Then under Text format combo box (just below the edit window) select "SmallBASIC program syntax highlighter". Make sure all < in code are separated by spaces otherwise they get confused with tags.

Thanks MGA!

You may have broken me out of my trap. We will know soon. Yes, I put a Bresenham code-example inside code-tags, each in normal HTML angle-brackets, and a /slash in the closing-tag. (The Wiki article is a good, but a bit rarified!)

The code is in C. The curly-braces, {}, are for structure - nested loops. I can convert this to BASIC. But an interpreter can use this code as a module, enhancing LINE with a width-parameter, and other values. Same with CIRCLE, ELLIPSE, ARC, DRAW, POLY ... any line routine. And it does FILL, and PAINT ... with texture & patterns.

The other parts of the Chello (C-hello) website are German, but the Bresenham page I link to is English. http://members.chello.at/~easyfilter/bresenham.html

There are other, nicer Bresenham-pages, some in BASIC.

The Text Format drop-down, and SB-syntax selection was suppressed by my Guard-Browser. I fired up the backup, and now I see it.

Once I get Code working, I will back up and show the plain-line Bresenham; it is small & simple. I will put it an SB demo.


/* Anti-aliased thick line */

/* This algorithm draws an anti-aliased line of wd pixel width. */

void plotLineWidth((int x0, int y0, int x1, int y1, float wd)
{
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = dx-dy, e2, x2, y2; /* error value e_xy */
float ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);

for (wd = (wd+1)/2; ; ) { /* pixel loop */
setPixelColor(x0,y0,max(0,255*(abs(err-dx+dy)/ed-wd+1)));
e2 = err; x2 = x0;
if (2*e2 >= -dx) { /* x step */
for (e2 += dy, y2 = y0; e2 < ed*wd && (y1 != y2 || dx > dy); e2 += dx)
setPixelColor(x0, y2 += sy, max(0,255*(abs(e2)/ed-wd+1)));
if (x0 == x1) break;
e2 = err; err -= dy; x0 += sx;
}
if (2*e2 <= dy) { /* y step */
for (e2 = dx-e2; e2 < ed*wd && (x1 != x2 || dx < dy); e2 += dy)
setPixelColor(x2 += sx, y0, max(0,255*(abs(e2)/ed-wd+1)));
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
}


Better. I'm imposing code-formatting on content-text. And I had thought maybe I could use BLOCKQUOTE and CODE and others to separate different files for a single SmallBASIC program, in one Post. But not looking like, at this point.

But I can use different Reply-comments, for different parts. Ok.

Yeah, Bresenham is bedrock magic, for lines, like using MATRIX for 3D tranforms ... matrices also perform Convolutions, which do edge-effects along any LINE or shape. So you could have very spiffed-up lines on a chart, or Lissajous. And fast ... this is how lines are drawn, in most real-life settings.

How fast it runs, in BASIC, we have to wait to see. I will drop back & punt, with the simple, plain-line Bresenham. We will then know how fast SB does it (slower, for thick..). Then we will come back to thick-Bresenham.

Yes indeed, CIRCLE makes very nice thick-lines - caught my eye!

Ted