Code: Select all
const as double pi = 3.14159265359
const as double piDiv2 = pi/2
'dim as double posx,posy,posz
const scr_x = 1920 'screenres
const scr_y = 1080
const scr_z = 1000
const scr_xh = scr_x\2
const scr_yh = scr_y\2
const scr_zh = scr_z\2
const star_count = 999
const star_size_max = 3
const star_gravity_max = 50
const star_gravity_max_range_strengt = (star_size_max^2 + star_size_max^2) / (star_gravity_max^2)
const star_grid_x = scr_xh \ star_gravity_max + 3
const star_grid_y = scr_yh \ star_gravity_max + 3
const star_grid_z = scr_z \ star_gravity_max + 3
const star_grid_size = 50 ' 0 to xx = max planet in 1 grid space
type v3d
as double x, y, z
end type
declare sub grid_add_bol(posx as double, posy as double, size as single, strength as double, c as ubyte)
declare function to_perspective(byval p as v3d) as v3d
declare function vLength(v as v3d) as single
declare function vNormalised(v as v3d) as v3d
type v3d_short
as short x, y, z
end type
type grid_type
as double value
as boolean calculated = false
end type
type grid
redim as grid_type grid(star_grid_size)
as short grid_size_current = star_grid_size
as short grid_size_max = star_grid_size
declare constructor()
end type
constructor grid()
redim preserve as grid_type grid(grid_size_max)
end constructor
type stars_type
const count = star_count
as grid gridXYZ(-star_grid_x to star_grid_x, -star_grid_y to star_grid_y, -2 to star_grid_z)
as v3d p(star_count)
'as v3d_short grid_p(star_count)
as v3d v(star_count)
as double size(star_count)
as ubyte clr(star_count)
as boolean active(star_count)
declare function IndexByXYZgrid() as byte
declare function UpdateInGravityRange() as byte
declare constructor()
declare sub reset_pos(n as integer)
end type
constructor stars_type()
for i as long = 0 to star_count
active(i) = true
p(i).x = rnd * scr_x - scr_xh
p(i).y = rnd * scr_y - scr_yh
p(i).z = rnd * scr_z
size(i) = star_size_max ' * rnd
'v(i).x = (-rnd+.5) / 1
'v(i).y = (-rnd+.5) / 1
v(i).z = 2
clr(i) = &B111 'fix(rnd * 7) + 1
next
end constructor
sub stars_type.reset_pos(n as integer)
p(n).x = rnd * scr_x - scr_xh
p(n).y = rnd * scr_y - scr_yh
p(n).z = rnd * scr_z
v(n).x = (-rnd+.5) / 1
v(n).y = (-rnd+.5) / 1
'v(n).z = (-rnd+.5) / 1
v(n).z = 5
end sub
function stars_type.IndexByXYZgrid() as byte
' clear last time
dim as long x, y, z, i1
for x = -star_grid_x to star_grid_x
for y = -star_grid_y to star_grid_y
for z = -1 to star_grid_z
gridXYZ(x, y, z ).grid_size_current = 0
next
next
next
'end clear
'start count nummer of stars in a grid
dim as v3d_short grid_pos
'dim as grid_pos_x, grid_pos_y, grid_pos_z
for i1 = 0 to count
if active(i1) = true then
grid_pos.x = int((p(i1).x / star_gravity_max)+.5)
grid_pos.y = int((p(i1).y / star_gravity_max)+.5)
grid_pos.z = int((p(i1).z / star_gravity_max)+.5)
'grid_p(i) = grid_pos ' update to new no checks for now
with gridXYZ(grid_pos.x, grid_pos.y, grid_pos.z)
.grid( .grid_size_current).value = i1
.grid( .grid_size_current).calculated = false
.grid_size_current += 1
if .grid_size_current > .grid_size_max then
.grid_size_max += star_grid_size
.constructor() 'redim the arry preserve
end if
end with
end if
next
return 0
end function
function stars_type.UpdateInGravityRange() as byte
dim as long x, y, z, i
dim as long xx, yy, zz, ii
dim as v3d p1, p2, pp1,pp2
dim as double dist, bright, tmp
dim as short minx, maxx, miny, maxy, minz, maxz
dim as v3d po, ppo 'posities
dim as v3d pv 'vectors
for x = -star_grid_x to star_grid_x
for y = -star_grid_y to star_grid_y
for z = -1 to star_grid_z
if gridXYZ(x, y, z ).grid_size_current > 0 then
for i = 0 to gridXYZ(x, y, z ).grid_size_current - 1
if gridXYZ(x, y, z ).grid(i).calculated = false andalso active(i) = true then 'look for all neibors now
gridXYZ(x, y, z ).grid(i).calculated = true
pp1 = p(gridXYZ(x, y, z ).grid(i).value)
minx = x-1: maxx = x+1
miny = y-1: maxy = y+1
minz = z-1: maxz = z+1
for xx = minx to maxx
for yy = miny to maxy
for zz = minz to maxz
if gridXYZ(xx, yy, zz).grid_size_current > 0 then
for ii = 0 to gridXYZ(xx, yy, zz ).grid_size_current - 1
if gridXYZ(x, y, z).grid(i).value <> gridXYZ(xx, yy, zz).grid(ii).value andalso active(ii) = true then 'the same points are never connected
'gridXYZ(xx, yy, zz ).grid(ii).calculated = true
pp2 = p(gridXYZ(xx, yy, zz).grid(ii).value)
' calculate distens
dist = sqr((pp1.x - pp2.x)^2 + (pp1.y - pp2.y)^2 + (pp1.z - pp2.z)^2)
if dist < star_gravity_max then 'andalso clr(gridXYZ(xx, yy, zz).grid(ii).value) = clr(gridXYZ(x, y, z ).grid(i).value)
p1 = to_perspective(pp1)
p2 = to_perspective(pp2)
tmp = (p1.z + p2.z) /3
if tmp > 1 then tmp = 1
bright = (tmp*255) * (1-(dist / star_gravity_max))
'bright = (1-(dist / star_gravity_max))*255
line (p1.x + scr_xh, p1.y + scr_yh)-(p2.x + scr_xh, p2.y + scr_yh), rgba(bright, bright, bright, 127), ,&b1010101010101010
'*-------update star vectors
po.x = pp2.x - pp1.x
po.y = pp2.y - pp1.y
po.z = pp2.z - pp1.z
'pv = 'vReal(po, star_gravity_max)
pv = vNormalised(po)
po = pp1
po.x -= pv.x * (dist /5)
po.y -= pv.y * (dist /5)
po.z -= pv.z * (dist /5)
ppo = to_perspective(po)
line (ppo.x + scr_xh, ppo.y + scr_yh)-(p1.x + scr_xh, p1.y + scr_yh), rgba(0, bright, 0, 127) ', ,&b1010101010101010
v(gridXYZ(x, y, z ).grid(i).value).x += pv.x * (30 / (dist^2))
v(gridXYZ(x, y, z ).grid(i).value).y += pv.y * (30 / (dist^2))
v(gridXYZ(x, y, z ).grid(i).value).z += pv.z * (30 / (dist^2))
end if
end if
next ii
end if
next zz
next yy
next xx
end if
next i
end if
next z
next y
next x
return 0
end function
dim shared as stars_type star
dim as double cc
dim as long i
dim as double x, y, z, size
dim as v3d p1
screenres scr_x,scr_y,32, 2,0
screenset 1, 0
do
for i = 0 to star.count
if star.active(i) = true then
star.p(i).x += star.v(i).x
star.p(i).y += star.v(i).y
star.p(i).z += star.v(i).z
p1 = to_perspective(star.p(i))
size = p1.z / 2
if abs(p1.x)-size > scr_xh or abs(p1.y)-size > scr_yh then star.reset_pos(i): i -= 1:if i < 0 then i = 0
if star.p(i).x > scr_xh or star.p(i).x < -scr_xh or star.p(i).y > scr_yh or star.p(i).y < -scr_yh then star.reset_pos(i): i -= 1:if i < 0 then i = 0
if star.p(i).z >= scr_z or star.p(i).z <= 0 then star.reset_pos(i): i -= 1:if i < 0 then i = 0
end if
next i
'cls
star.IndexByXYZgrid()
star.UpdateInGravityRange()
for i = 0 to star.count
if star.active(i) = true then
size = star.p(i).z
p1 = to_perspective(star.p(i))
z = (p1.z - 1) /2
if z >= 1 then z = 1
grid_add_bol(p1.x + scr_xh, p1.y + scr_yh, (p1.z*star.size(i))+2, z/1.4+.1, star.clr(i))
end if
next
'locate 1,1
'print star_grid_x * 2, star_grid_y * 2, star_grid_z
'print star.gridXYZ(0, 0, star_grid_z/2 ).grid_size_current
flip
cls
screensync
loop while inkey <> chr(27)
sleep
sub grid_add_bol(posx as double, posy as double, size as single, strength as double, c as ubyte)
if size <= 1 then return
dim as integer posx_fix = int(posx)
dim as integer posy_fix = int(posy)
dim as single posx_frac = frac(posx)
dim as single posy_frac = frac(posy)
dim as double i
dim as short x,y
dim as single pre_x, pre_y, m = fix(size)
dim as single sqr_size = size * size
dim as ulong pointget
dim as byte stepsize_x = 1, stepsize_y = 1
if size > 25 then stepsize_y = (size \ 25) + 1: stepsize_x = (stepsize_y \2) +1
for y = -m to m + 1 step stepsize_y
for x = -m to m + 1 step stepsize_x
pre_x =(x-posx_frac)
pre_y =(y-posy_frac)
i = pre_x * pre_x + pre_y * pre_y
if i < sqr_size then
i = sqr(i) / size
i = sqr(1 - i*i)
i = ((i * 192)+63) * strength ' to color byte
pointget = point (x + posx_fix, y + posy_fix)
pset (x + posx_fix, y + posy_fix), pointget or rgb(i*(c and 4)\4, i*(c and 2)\2, i*(c and 1))
'pset (x + posx_fix, y + posy_fix), rgb(i*(c and 4)\4, i*(c and 2)\2, i*(c and 1))
'else
'pset (x+posx_fix,y+posy_fix), pointget or rgba(0,255,0,255)
end if
next
next
end sub
function to_perspective(byval p as v3d) as v3d
dim as v3d pr = any
pr.z = scr_z / (scr_z - p.z) 'output 1 or more
pr.x = (p.x * pr.z)
pr.y = (p.y * pr.z)
return pr
end function
'*----------------------------------- Vector code functions-------------
function vLength(v as v3d) as single
return sqr(v.x*v.x + v.y*v.y + v.z*v.z)
end function
function vNormalised(v as v3d) as v3d
dim as v3d temp
dim as single length3D = vLength(v)
temp.x = v.x / length3D
temp.y = v.y / length3D
temp.z = v.z / length3D
return temp
end function