I probably failed the challenge. Was fun to make anyway.
Code: Select all
#define dbl double
#define RGBA_R( c ) ( CULng( c ) Shr 16 And 255 )
#define RGBA_G( c ) ( CULng( c ) Shr 8 And 255 )
#define RGBA_B( c ) ( CULng( c ) And 255 )
#define RGBA_A( c ) ( CULng( c ) Shr 24 )
#define max(a, b) (iif((a) > (b), (a), (b)))
#define min(a, b) (iif((a) < (b), (a), (b)))
const PI = atn(1) * 4
const as ulong C_BK = rgb(0,0,0)
const as ulong C_WH = rgb(255,255,255)
const as ulong C_YE = rgb(255,255,0)
const SW = 800, SH = 600
screenres SW, SH, 32
sub limit(byref v as dbl, vmin as dbl, vmax as dbl)
if v > vmax then v = vmax
if v < vmin then v = vmin
end sub
function distSq(x1 as dbl, y1 as dbl, x2 as dbl, y2 as dbl) as dbl
dim as dbl dx = x1 - x2
dim as dbl dy = y1 - y2
return dx * dx + dy * dy
end function
function interpol(c1 as ulong, c2 as ulong, f1 as dbl) as ulong
limit(f1, 0, 1)
dim as dbl f2 = 1 - f1
dim as long r = clng(RGBA_R(c1) * f1 + RGBA_R(c2) * f2)
dim as long g = clng(RGBA_G(c1) * f1 + RGBA_G(c2) * f2)
dim as long b = clng(RGBA_B(c1) * f1 + RGBA_B(c2) * f2)
return rgb(r, g, b)
end function
function merge(c1 as ulong, c2 as ulong) as ulong
dim as long r = max(RGBA_R(c1), RGBA_R(c2))
dim as long g = max(RGBA_G(c1), RGBA_G(c2))
dim as long b = max(RGBA_B(c1), RGBA_B(c2))
return rgb(r, g, b)
end function
'(x0,y0) = point, (x1,y1,x2,y2) = line
function distToLineSeg(x0 as dbl, y0 as dbl, x1 as dbl, y1 as dbl, x2 as dbl, y2 as dbl) as dbl
dim as dbl lineLengthSquared = (x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)
dim as dbl rfactor = ((x0-x1) * (x2-x1) + (y0-y1) * (y2-y1)) / lineLengthSquared
dim as dbl dist
if ((rfactor >= 0) and (rfactor <= 1)) then
dist = abs((x2-x1) * (y1-y0) - (y2-y1) * (x1-x0)) / sqr(lineLengthSquared)
else
dim as dbl d1 = sqr((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0))
dim as dbl d2 = sqr((x2-x0) * (x2-x0) + (y2-y0) * (y2-y0))
if (d1 < d2) then dist = d1 else dist = d2
end if
return dist
end function
dim as dbl px(0 to 7), py(0 to 7)
for i as integer = 0 to 7
dim as dbl r = 0.45
if i mod 2 = 1 then r = 0.3
px(i) = cos((i / 8) * (2 * PI)) * (SH * r) + (SW / 2)
py(i) = sin((i / 8) * (2 * PI)) * (SH * r) + (SH / 2)
'circle (px(i), py(i)), 3, C_WH
next
dim as integer linSeg(0 to 7, 0 to 1) 'number, endpoint
for i as integer = 0 to 7
linSeg(i, 0) = (i * 3) mod 8
linSeg(i, 1) = (i * 3 + 3) mod 8
next
dim as dbl r1 = 2, r2 = r1 + 8
'define line segment end points
dim as dbl x1 = SW * .3, y1 = SH * .3
dim as dbl x2 = SW * .8, y2 = SH * .6
dim as ulong c, cBack
dim as dbl d
for y as integer = 0 to SH - 1
for x as integer = 0 to SW - 1
for i as integer = 0 to 7
c = C_BK
x1 = px(linSeg(i, 0))
y1 = py(linSeg(i, 0))
x2 = px(linSeg(i, 1))
y2 = py(linSeg(i, 1))
d = distToLineSeg(x, y, x1, y1, x2, y2)
if d < r1 then
c = C_WH
else
if d < r2 then
c = interpol(C_BK, C_YE, (d - r1) / (r2 - r1))
end if
end if
if c <> C_BK then 'no need to plot black pixel
cBack = point(x,y)
pset(x, y), merge(c, cBack)
end if
next
next
next
getkey