This code snippet creates a Voronoi diagram of points and line segments in real-time. Click and drag the points or endpoints of lines to edit the Voronoi diagram.
sync on
sync rate 0
cls
set display mode 1024,768,32
type point_type
color
pt
endtype
dim points(200) as point_type
autocam off
type line_type
color
endpt1
endpt2
main
endtype
dim lines(200) as line_type
randomize timer()
point_amount=5
line_amount=5
for i=0 to point_amount-1
points(i).color=random_color()
points(i).pt = free_object()
` make object cone points(i).pt,3000
make_object_cone(points(i).pt,3000,30)
color object points(i).pt,points(i).color
position object points(i).pt,rnd(screen width()),-1500,-rnd(screen height())
set object ambience points(i).pt,points(i).color
set object diffuse points(i).pt,points(i).color
set object specular points(i).pt,points(i).color
set object emissive points(i).pt,points(i).color
set object specular power points(i).pt,100
`set object light points(i).pt,0
set object ambient points(i).pt,0
next i
for i=0 to line_amount-1
lines(i).color=random_color()
lines(i).endpt1 = free_object()
make_object_cone(lines(i).endpt1,3000,30)
color object lines(i).endpt1,lines(i).color
lines(i).endpt2 = free_object()
make_object_cone(lines(i).endpt2,3000,30)
color object lines(i).endpt2,lines(i).color
position object lines(i).endpt1,rnd(screen width()),-1500,-rnd(screen height())
position object lines(i).endpt2,rnd(screen width()),-1500,-rnd(screen height())
dx#=object position x(lines(i).endpt2)-object position x(lines(i).endpt1)
dz#=object position z(lines(i).endpt2)-object position z(lines(i).endpt1)
d#=sqrt(dx#^2+dz#^2)
lines(i).main = free_object()
s#=3000*sqrt(2)
make_object_wedge(lines(i).main,object position x(lines(i).endpt1),object position z(lines(i).endpt1),object position x(lines(i).endpt2),object position z(lines(i).endpt2),3000)
color object lines(i).main,lines(i).color
position object lines(i).main,0,-1500,0
next i
fov#=0.1
`set camera aspect screen width()/screen height()
y#=screen height()/tan(fov#)
position camera screen width()/2,y#,-screen height()/2
set camera range y#,y#+3000
rotate camera 90,0,0
set camera fov fov#
`set ambient light 50
set ambient light 0
`set point light 0,0,2000,0
`set light range 0,1000000
drag_type=-1
drag_index=-1
dragging=0
do
set cursor 0,0
if (mouseclick() and dragging=0)
first=1
mindist#=3000
mini=-1
for i=0 to point_amount-1
dist#=sqrt((mousex()-object position x(points(i).pt))^2+(mousey()+object position z(points(i).pt))^2)
if (dist#<mindist# or first=1)
first=0
mindist#=dist#
mini=i
endif
next i
if mindist#<80
dragging=1
drag_type=0
drag_index=mini
drag_dist#=mindist#
endif
first=1
mindist#=3000
mini=-1
for i=0 to line_amount-1
dist#=sqrt((mousex()-object position x(lines(i).endpt1))^2+(mousey()+object position z(lines(i).endpt1))^2)
if (dist#<mindist# or first=1)
first=0
mindist#=dist#
mini=i
endif
next i
if mindist#<80 and (dragging=0 or mindist#<drag_dist#)
dragging=1
drag_type=1
drag_index=mini
drag_dist#=mindist#
endif
first=1
mindist#=3000
mini=-1
for i=0 to line_amount-1
dist#=sqrt((mousex()-object position x(lines(i).endpt2))^2+(mousey()+object position z(lines(i).endpt2))^2)
if (dist#<mindist# or first=1)
first=0
mindist#=dist#
mini=i
endif
next i
if mindist#<80 and (dragging=0 or mindist#<drag_dist#)
dragging=1
drag_type=2
drag_index=mini
drag_dist#=mindist#
endif
endif
if dragging=1
if drag_type=0
position object points(drag_index).pt,mousex(),-1500,-mousey()
endif
if drag_type=1
position object lines(drag_index).endpt1,mousex(),-1500,-mousey()
delete object lines(drag_index).main
make_object_wedge(lines(drag_index).main,object position x(lines(drag_index).endpt1),object position z(lines(drag_index).endpt1),object position x(lines(drag_index).endpt2),object position z(lines(drag_index).endpt2),3000)
color object lines(drag_index).main,lines(drag_index).color
position object lines(drag_index).main,0,-1500,0
endif
if drag_type=2
position object lines(drag_index).endpt2,mousex(),-1500,-mousey()
delete object lines(drag_index).main
make_object_wedge(lines(drag_index).main,object position x(lines(drag_index).endpt1),object position z(lines(drag_index).endpt1),object position x(lines(drag_index).endpt2),object position z(lines(drag_index).endpt2),3000)
color object lines(drag_index).main,lines(drag_index).color
position object lines(drag_index).main,0,-1500,0
endif
endif
if mouseclick()=0 then dragging=0
ink rgb(0,0,0),0
for i=0 to point_amount-1
box object position x(points(i).pt)-2,-object position z(points(i).pt)-2,object position x(points(i).pt)+2,-object position z(points(i).pt)+2
next i
for i=0 to line_amount-1
box object position x(lines(i).endpt1)-2,-object position z(lines(i).endpt1)-2,object position x(lines(i).endpt1)+2,-object position z(lines(i).endpt1)+2
box object position x(lines(i).endpt2)-2,-object position z(lines(i).endpt2)-2,object position x(lines(i).endpt2)+2,-object position z(lines(i).endpt2)+2
line object position x(lines(i).endpt1),-object position z(lines(i).endpt1),object position x(lines(i).endpt2),-object position z(lines(i).endpt2)
next i
sync
loop
function free_object()
e=1
while object exist(e)
inc e
endwhile
endfunction e
function make_object_cone(num,size#,slices)
memb=1
meshn=2
FVF_Format = 274
FVF_Size = 32
vertex_amount = slices*3
make memblock memb,12+FVF_SIZE*vertex_amount
write memblock dword memb,0,FVF_Format
write memblock dword memb,4,FVF_Size
write memblock dword memb,8,vertex_amount
triangle_amount = slices
for t=0 to triangle_amount-1
write memblock float memb,12+(t*3+0)*FVF_SIZE+0,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+0)*FVF_SIZE+8,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+0)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+0,size#*sin(t*360.0/slices)
write memblock float memb,12+(t*3+1)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+1)*FVF_SIZE+8,size#*cos(t*360.0/slices)
write memblock float memb,12+(t*3+1)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+1)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+0,size#*sin((t+1)*360.0/slices)
write memblock float memb,12+(t*3+2)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+2)*FVF_SIZE+8,size#*cos((t+1)*360.0/slices)
write memblock float memb,12+(t*3+2)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+2)*FVF_SIZE+20,0
next i
make mesh from memblock meshn,memb
get image 1,0,0,1,1
make object num,meshn,1
delete image 1
delete memblock memb
delete mesh meshn
endfunction
function make_object_wedge(num,x1#,z1#,x2#,z2#,size#)
`ax#=(x1#+x2#)/2
`az#=(z1#+z2#)/2
`x1#=x1#-ax#
`x2#=x2#-ax#
`z1#=z1#-az#
`z2#=z2#-az#
memb=1
meshn=2
FVF_Format = 274
FVF_Size = 32
vertex_amount = 12
make memblock memb,12+FVF_SIZE*vertex_amount
write memblock dword memb,0,FVF_Format
write memblock dword memb,4,FVF_Size
write memblock dword memb,8,vertex_amount
dx#=x2#-x1#
dz#=z2#-z1#
d#=sqrt(dx#^2+dz#^2)
dx#=dx#/d#
dz#=dz#/d#
nx#=-dz#
nz#=dx#
t=0
write memblock float memb,12+(t*3+0)*FVF_SIZE+0,x1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+0)*FVF_SIZE+8,z1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+0)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+0,x2#+nx#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+1)*FVF_SIZE+8,z2#+nz#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+1)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+0,x2#
write memblock float memb,12+(t*3+2)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+2)*FVF_SIZE+8,z2#
write memblock float memb,12+(t*3+2)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+2)*FVF_SIZE+20,0
t=1
write memblock float memb,12+(t*3+0)*FVF_SIZE+0,x1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+0)*FVF_SIZE+8,z1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+0)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+0,x1#+nx#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+1)*FVF_SIZE+8,z1#+nz#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+1)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+0,x2#+nx#*size#
write memblock float memb,12+(t*3+2)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+2)*FVF_SIZE+8,z2#+nz#*size#
write memblock float memb,12+(t*3+2)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+2)*FVF_SIZE+20,0
t=2
write memblock float memb,12+(t*3+0)*FVF_SIZE+0,x2#
write memblock float memb,12+(t*3+0)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+0)*FVF_SIZE+8,z2#
write memblock float memb,12+(t*3+0)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+0)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+0,x2#-nx#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+1)*FVF_SIZE+8,z2#-nz#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+1)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+0,x1#
write memblock float memb,12+(t*3+2)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+2)*FVF_SIZE+8,z1#
write memblock float memb,12+(t*3+2)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+2)*FVF_SIZE+20,0
t=3
write memblock float memb,12+(t*3+0)*FVF_SIZE+0,x1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+4,size#/2
write memblock float memb,12+(t*3+0)*FVF_SIZE+8,z1#
write memblock float memb,12+(t*3+0)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+0)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+0)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+0,x2#-nx#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+1)*FVF_SIZE+8,z2#-nz#*size#
write memblock float memb,12+(t*3+1)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+1)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+1)*FVF_SIZE+20,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+0,x1#-nx#*size#
write memblock float memb,12+(t*3+2)*FVF_SIZE+4,-size#/2
write memblock float memb,12+(t*3+2)*FVF_SIZE+8,z1#-nz#*size#
write memblock float memb,12+(t*3+2)*FVF_SIZE+12,0
write memblock float memb,12+(t*3+2)*FVF_SIZE+16,1
write memblock float memb,12+(t*3+2)*FVF_SIZE+20,0
make mesh from memblock meshn,memb
get image 1,0,0,1,1
make object num,meshn,1
delete memblock memb
delete mesh meshn
delete image 1
endfunction
function random_color()
red=rnd(255)
green=rnd(255)
blue=rnd(255)
if (red>=green and red>=blue)
red=255
else
if green>=red and green>=blue
green=255
else
if blue>=green and blue>=red
blue=255
endif
endif
endif
if (red<=green and red<=blue)
red=0
else
if green<=red and green<=blue
green=0
else
if blue<=green and blue<=red
blue=0
endif
endif
endif
color=rgb(red,green,blue)
endfunction color