Code: Select all
' D.J.Peters (Joshy)
const maxpoints as integer = 120
const lastpoint as integer = maxpoints - 1
const maxsprings as integer = maxpoints + 1
const lastspring as integer = maxsprings- 1
const pointkg as single = 1.0
const radius as single = 75.0
const stiffnes as single = 100.0
const damping as single = 10.0
const gravity as single = -9.81
const DT as single = 0.009
const FINAL_PRESSURE as single = 100.0
const scr_w as integer=640
const scr_h as integer=480
const scr_w_half as integer=(scr_w-1)/2
const scr_h_half as integer=(scr_h-1)/2
type vector3d
x as single
y as single
z as single
end type
type POINT3D
position as VECTOR3D
velocity as VECTOR3D
force as VECTOR3D
end type
type SPRING3D
p1 as integer
p2 as integer
length as single
normal as VECTOR3D
end type
dim shared as integer mb,mx,my,nearestpoint=0
dim shared as single pressure
dim shared as POINT3D points(maxpoints)
dim shared as SPRING3D springs(maxsprings)
sub createmesh()
dim as integer i,p1,p2
dim as single w
w=6.28/(maxpoints-1)
for i=0 to lastpoint
with points(i).position
.x=sin(i*w)*RADIUS
.y=cos(i*w)*RADIUS
end with
next
for i=0 to lastpoint
springs(i).p1 = i
springs(i).p2 = i+1
springs(i).length = sqr((points(springs(i).p1).position.x - points(springs(i).p2).position.x) * (points(springs(i).p1).position.x - points(springs(i).p2).position.x) + _
(points(springs(i).p1).position.y - points(springs(i).p2).position.y) * (points(springs(i).p1).position.y - points(springs(i).p2).position.y) )
next
springs(i-1).p1 = lastpoint
springs(i-1).p2 = 0
springs(i-1).length = sqr((points(springs(i-1).p1).position.x - points(springs(i-1).p2).position.x) * (points(springs(i-1).p1).position.x - points(springs(i-1).p2).position.x) + _
(points(springs(i-1).p1).position.y - points(springs(i-1).p2).position.y) * (points(springs(i-1).p1).position.y - points(springs(i-1).p2).position.y) )
end sub
sub CalcForces()
dim as integer i
dim as VECTOR3D pointdiff,velocitydiff
dim as single length,force,forcex,forcey,v,pv,direction
for i=0 to lastpoint
points(i).force.x = 0
points(i).force.y = pointkg * GRAVITY
if (Pressure - FINAL_PRESSURE) >= 0.0 then points(i).force.y*= (Pressure-final_pressure)
next
for i=0 to lastspring
pointdiff.x=points(springs(i).p1).position.x - points(springs(i).p2).position.x
pointdiff.y=points(springs(i).p1).position.y - points(springs(i).p2).position.y
length=sqr(pointdiff.x*pointdiff.x + pointdiff.y*pointdiff.y)
if length<>0.0 then
velocitydiff.x = points(springs(i).p1).velocity.x - points(springs(i).p2).velocity.x
velocitydiff.y = points(springs(i).p1).velocity.y - points(springs(i).p2).velocity.y
force= (length-springs(i).length)*stiffnes + (velocitydiff.x*pointdiff.x + velocitydiff.y * pointdiff.y) * damping/length
forcex=pointdiff.x/length*force
forcey=pointdiff.y/length*force
points(springs(i).p1).force.x-=forcex
points(springs(i).p1).force.y-=forcey
points(springs(i).p2).force.x+=forcex
points(springs(i).p2).force.y+=forcey
end if
springs(i).normal.x = pointdiff.y/length '!!!
springs(i).normal.y = -pointdiff.x/length '!!!
next
for i=0 to lastspring-1
pointdiff.x=points(springs(i).p1).position.x - points(springs(i).p2).position.x
pointdiff.y=points(springs(i).p1).position.y - points(springs(i).p2).position.y
length=sqr(pointdiff.x*pointdiff.x + pointdiff.y*pointdiff.y)
v += 0.5 * abs(pointdiff.x) * abs(springs(i).normal.x) * length
next
for i=0 to lastspring-1
pointdiff.x=points(springs(i).p1).position.x - points(springs(i).p2).position.x
pointdiff.y=points(springs(i).p1).position.y - points(springs(i).p2).position.y
length=sqr(pointdiff.x*pointdiff.x + pointdiff.y*pointdiff.y)
pv=length*pressure*(1.0/v)
points(springs(i).p1).force.x += springs(i).normal.x * pv
points(springs(i).p1).force.y += springs(i).normal.y * pv
points(springs(i).p2).force.x += springs(i).normal.x * pv
points(springs(i).p2).force.y += springs(i).normal.y * pv
next
for i = 0 to lastpoint
points(i).velocity.x+=( Points(i).force.x / pointkg )* DT
direction=points(i).velocity.x * DT
if (points(i).position.x + direction) < -scr_w_half then
direction*=-1
points(i).velocity.x*= - 0.5
points(i).velocity.y*= 0.5
elseif (points(i).position.x + direction) > scr_w_half then
direction*=-1
points(i).velocity.x*= -0.5
points(i).velocity.y*= 0.5
end if
points(i).position.x+=direction
points(i).velocity.y+=( Points(i).force.y / pointkg )* DT
direction=points(i).velocity.y * DT
if (points(i).position.y + direction) < -scr_h_half then
direction*=-1
points(i).velocity.y*= - 0.5
points(i).velocity.x*= 0.5
elseif (points(i).position.y + direction) > scr_h_half then
direction*=-1
points(i).velocity.y*= -0.5
points(i).velocity.x*= 0.5
end if
points(i).position.y+=direction
next
end sub
sub Euler()
dim as integer i
dim as single direction
for i = 0 to lastpoint
points(i).velocity.x+=( Points(i).force.x / pointkg )* DT
direction=points(i).velocity.x * DT
if (points(i).position.x + direction) < -scr_w_half then
direction*=-1 ' -scr_w_half - points( i ).position.x
points(i).velocity.x*= - 0.5
points(i).velocity.y*= 0.9
elseif (points(i).position.x + direction) > scr_w_half then
direction*=-1 ' scr_w_half - points(i).position.x
points(i).velocity.x*= - 0.5
points(i).velocity.y*= 0.9
end if
points(i).position.x+=direction
points(i).velocity.y+=( Points(i).force.y / pointkg )* DT
direction=points(i).velocity.y * DT
if (points(i).position.y + direction) < -scr_h_half then
direction*=-1 ' -scr_h_half - points( i ).position.y
'points(i).velocity.y*= - 0.5
points(i).velocity.x*= 0.9
elseif (points(i).position.y + direction) > scr_h_half then
direction*=-1 ' scr_h_half - points(i).position.y
'points(i).velocity.y*= - 1.5
points(i).velocity.x*= 0.9
end if
points(i).position.y+=direction
next
end sub
sub DrawIt1()
dim as integer i
pset (scr_w_half+points(0).position.x,scr_h_half-points(0).position.y)
for i=1 to lastpoint
line -(scr_w_half+points(i).position.x,scr_h_half-points(i).position.y)
next
line -(scr_w_half+points(0).position.x,scr_h_half-points(0).position.y)
end sub
sub DrawIt2()
dim as integer i
for i=0 to lastspring-1
line (scr_w_half+points(springs(i).p1).position.x,scr_h_half-points(springs(i).p1).position.y)-(scr_w_half+points(springs(i).p2).position.x,scr_h_half-points(springs(i).p2).position.y),i and &HFF
next
end sub
'
'main
'
dim as integer frames,wpage,vpage=1
dim as single t1,t2
createmesh
t1=timer
screenres scr_w,scr_h,8,2
while len(inkey)=0
if pressure<final_pressure then pressure+=(final_pressure/300.0)
CalcForces
screenset wpage,vpage
swap wpage,vpage
cls
drawIt1
t2=timer
frames+=1
if (t2-t1)>1 then
windowtitle "FPS="+str(frames)
t1=t2:frames=0
end if
wend
sleep