Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Litle bit physics in 2D.
#1
You can play with the consts have fun.

Joshy
EDIT: short bug removed!
Code:
option explicit

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 * -9.81  
    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 ' -scr_w_half - points( i ).position.x
      points(i).velocity.x*= - 0.5
      points(i).velocity.y*=  0.5
    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.95
    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.5
    elseif (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.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
sorry about my english
Reply
#2
by setting the max points at 520, after one bounce your program drew this funny man:
[Image: 3509-r.jpg]

:lol:
Smile
[Image: freebasic.png]
Reply
#3
!!!!!!!!!!!!!!! 1787 FPS !!!!!!!!!!!!!!!!

To hell with your computer :rotfl:
Or the framecounter are wrong :lol:

What is your CPU ?

Joshy
sorry about my english
Reply
#4
I just get 1000 FPS @ 2.0 GHz if I set the points to 520.


Btw, can you make it move around objects too? Then it might be a nice airflow-over-an-object program ^_^
Looks nice.
Reply
#5
Hi Neo off topic but your homepage link are down or wrong.

Joshy
sorry about my english
Reply
#6
Quote:!!!!!!!!!!!!!!! 1787 FPS !!!!!!!!!!!!!!!!

To hell with your computer :rotfl:
Or the framecounter are wrong :lol:

What is your CPU ?

Joshy
its a p4 32-bit 2.8 GHz
freebasic really likes it Smile.
[Image: freebasic.png]
Reply
#7
Nice, it looks like a very realistic line loop. 8)
I got around 1400-1500 fps.
It's the difference between asking someone how much flour goes into pancakes, and handing them a sorry mix of oozing green goo and asking them to fix it." - Deleter

-Founder & President of the No More Religion Threads movement-
Reply
#8
all i got was 2212:

[Image: 3651-r.bmp]
quote="whitetiger0990"]whitetiger is.. WHITE POWER!!! [/quote]
Here
Reply
#9
Here is an "how to" make soft bodys.
http://panoramix.ift.uni.wroc.pl/~maq/so...ftbody.pdf

Joshy
sorry about my english
Reply
#10
with the default code I get 4800 fps
[Image: freebasic.png]
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)