someone with mad math skills, help please

Author 
Message 
mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

someone with mad math skills, help please
Actually, it's probably not mad skills needed, but I have next to none =o)
I've been messing around with a "gravity" test today, and although I came up with something cool to look at, it's not what I was trying for.
I can get the x,y position of the mouse, the x,y position of the object I want to move, and from there get the distance between the two points:
xdistance=math.abs(Fl:event_x()object:x())
ydistance=math.abs(Fl:event_y()object:y())
distance=math.sqrt(xdistance*xdistance+ydistance*ydistance)
What I would really like to do now is use that distance as a way to increase the motion of the object toward the mouse as the distance gets shorter. Essentially I'm looking for a single (floating point?) value that gradually increases as distance decreases. The problems I'm having are as follows:
1) I suck at math
2) The target speed should get larger as the distance gets smaller
3) The target speed should always be a fairly small nonnegative number
Is there anyone who might be able to help?
Thanks.
This is the last thing I do before releasing the widgetsdemo beta1


01232008 09:39 AM 


Juergen
Member
Posts: 81
Group: Registered
Joined: May 2007
Status:
Offline
Reputation: 0

RE: someone with mad math skills, help please
If you want to have a linear dependency you could use something like that:
speed=v_min+a/(distance+c) where v_min is the minimal speed and v_min+a/c is the maximal speed. You need the c because for distance=0 the equation would become v_min+1/0 which does not work. So your c is c=a/(v_max  v_min)
Juergen


01232008 10:17 AM 


mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

RE: someone with mad math skills, help please
I only just read this, so haven't tried it yet, but I've already got "if distance > 0" before doing anything. I don't know if that makes it easier.
What is a?
This post was last modified: 01232008 11:28 AM by mikshaw.


01232008 11:25 AM 


mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

RE: someone with mad math skills, help please
I tried it assuming that 'a' was maximum speed, and came up with something different, but not very different than what I already had. Actually it was farther away from my goal.
Here is the curent loop I have, with this change:
function grav_loop()
local my_x,bx=Fl:event_x(),0
local my_y,by=Fl:event_y()demo_bh,0
local c=math.random(1,255)
local b=math.random(1,balls)
ball[b]:color(c)
for i=1,balls do
local xdistance=math.abs(my_xball[i]:x())
local ydistance=math.abs(my_yball[i]:y())
local distance=math.sqrt(xdistance*xdistance+ydistance*ydistance)
local speed=1+5/distance
if distance > 0 then
if my_x > ball[i]:x() then
bx=ball[i]:x()+speed
else
bx=ball[i]:x()speed
end
if my_y > ball[i]:y() then
by=ball[i]:y()+speed
else
by=ball[i]:y()speed
end
ball[i]:position(bx,by)
end
end
demo_widget:redraw()
grav_timer:doWait(.05)
end
ball is a table of randomly placed circles
EDIT: Actually I kinda like that one too. I'm going to keep it in the mix as stage 3. Thanks.
This post was last modified: 01232008 12:27 PM by mikshaw.


01232008 12:18 PM 


mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

RE: someone with mad math skills, help please
Holy crap! No, wait, it makes a HUGE difference just by changing the minimum and maximum to various values. This could keep me busy for a while.
Thank you Juergen! I think this is exactly what I was looking for.


01232008 12:41 PM 


Juergen
Member
Posts: 81
Group: Registered
Joined: May 2007
Status:
Offline
Reputation: 0

RE: someone with mad math skills, help please
Holy crap! No, wait, it makes a HUGE difference just by changing the minimum and maximum to various values. This could keep me busy for a while.
Thank you Juergen! I think this is exactly what I was looking for.
Of course this doesn't model gravitation. Gravitational forces go with 1/r^2.
If you want to make a simulation a Nbody problem with randomly placed masses also is very problematic, because if you use fixed time steps (delta t) then the model will break because when 2 masses come very close the steps will be to big and when you select smaller dt then you won't see anything.
I can post an example in a few minutes.
Therefore it would make sense to simulate just a few bodies with a fixed setup (like a planetary system)
Juergen


01242008 08:01 AM 


Juergen
Member
Posts: 81
Group: Registered
Joined: May 2007
Status:
Offline
Reputation: 0

RE: someone with mad math skills, help please
It might be possible to tweak it a little, so that it works better, but the main problem will prevail. Such a simple simulation won't work very good with so many bodies and a random initial setup. At least not if you want to see anything with a decent machine.
Juergen
P.S.: For some reason I can't attach it.
So here it is:
demo_widget:color(0)
balls=34
bsize=10
function grav_loop()
local planet_new={},g,m,r,sqr_r,rx,ry,m_j
time_step=max_slider:value()
for i=1,balls do  for every planet
g={0,0}
m=planet[i][1]  with mass m
for j=1,balls do  with every other planet
if i~=j then  planets do not influence itself
rx=planet[i][2]planet[j][2]
ry=planet[i][3]planet[j][3]
sqr_r=rx*rx+ry*ry
r=math.sqrt(sqr_r)  distance
m_j=planet[j][1]  mass of the second planet
g[1]=g[1]+(r>1 and m_j/sqr_r*rx/r or m_j*rx)  gravitational field value (acceleration of the mass for time_step)
g[2]=g[2]+(r>1 and m_j/sqr_r*ry/r or m_j*rx)  of course a vector, we also don't want to use too small r values > planets normally have a radius. Also r=0 is forbidden.
end
end
g[1]=g[1]*grav_const  we take to liberty to change the gravitational constant.
g[2]=g[2]*grav_const  not possible in real life!
planet_new[i]={planet[i][1],  the mass doesn't change
planet[i][2]+planet[i][4]*time_step+g[1]*time_step*time_step*.5,  x_1=x_0+v_0*t+g/2*t^2 which is the new position of the object
planet[i][3]+planet[i][5]*time_step+g[2]*time_step*time_step*.5,  the same
planet[i][4]+g[1]*time_step,  v_1=v_0+g*t , which is the new speed of the object
planet[i][5]+g[2]*time_step}  of course the same
ball[i]:position(planet_new[i][2]/scale,planet_new[i][3]/scale)
end
planet=planet_new  everything starts from the beginning
demo_widget:redraw()
grav_timer:doWait(.05)
end
fltk.fl_define_FL_PLASTIC_UP_BOX()
math.randomseed(os.time())
scale=1000
max_x=(demo_widget:w()bsize)*scale
max_y=(demo_widget:h()bsize)*scale
max_m=20000000
min_m=1000000
max_ivx=50
max_ivy=50
grav_const=1
ball={}
planet={}
for i=1,balls do
 planets[i]={mass,pos_x,pos_y,v_x,v_y}
planet[i]={math.random(min_m,max_m),math.random(1,max_x),math.random(1,max_y),math.random(max_ivx,max_ivx),math.random(max_ivy,max_ivy)}
ball[i]=fltk:Fl_Box(planet[i][2]/scale,planet[i][3]/scale,bsize,bsize)
if fltk._FL_PLASTIC_ROUND_UP_BOX then ball[i]:box(fltk._FL_PLASTIC_ROUND_UP_BOX) else ball[i]:box(fltk.FL_PLASTIC_ROUND_UP_BOX) end
ball[i]:color(planet[i][1]/max_m*255)
end
max_slider=fltk:Fl_Hor_Value_Slider(0,demo_widget:h()20,demo_widget:w(),20)
max_slider:minimum(1)
max_slider:maximum(100)
max_slider:value(.1)
max_slider:step(.1)
grav_timer = murgaLua.createFltkTimer()
grav_timer:callback(grav_loop)
grav_timer:do_callback()


01242008 08:31 AM 


mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

RE: someone with mad math skills, help please
I haven't looked at your script yet, but I've been messing around with various equations and come up with a handful of interesting pieces. Here's one that is cosest to my current goal:
balls=1500
bsize=2
min_grav=0
max_grav=6
function grav_loop()
local my_x,bx=Fl:event_x(),0
local my_y,by=Fl:event_y(),0
local c=math.random(1,255)
for i=1,balls do
local xdistance=math.abs(my_xball[i]:x())
local ydistance=math.abs(my_yball[i]:y())
local distance=math.sqrt(xdistance*xdistance+ydistance*ydistance)
local xspeed=(min_grav+max_grav)/distance*xdistance
local yspeed=(min_grav+max_grav)/distance*ydistance
if distance <= 25 then
ball[i]:color(c)
 need a better formula here
xspeed=xspeed*max_x/distance*math.random(2,3)
yspeed=yspeed*max_y/distance*math.random(2,3)
end
if my_x > ball[i]:x() then bx=ball[i]:x()+xspeed else bx=ball[i]:x()xspeed end
if my_y > ball[i]:y() then by=ball[i]:y()+yspeed else by=ball[i]:y()yspeed end
ball[i]:position(bx,by)
end
w:redraw()
grav_timer:doWait(.05)
end
w=fltk:Fl_Double_Window(Fl:w(),Fl:h(),"gravity test")
w:color(0)
math.randomseed(os.time())
max_x=w:w()bsize
max_y=w:h()bsize
ball={}
for i=1,balls do
ball[i]=fltk:Fl_Box(math.random(1,max_x),math.random(1,max_y),bsize,bsize)
ball[i]:box(fltk.FL_FLAT_BOX)
end
grav_timer = murgaLua.createFltkTimer()
grav_timer:callback(grav_loop)
grav_timer:do_callback()
w:fullscreen()
w:show()
Fl:run()


01242008 09:25 AM 


iGame3D
Moderator
Posts: 231
Group: Moderators
Joined: Apr 2007
Status:
Offline
Reputation: 0

RE: someone with mad math skills, help please
ooh ahh thats so cool!
Comment that script, what a neat intro to murgaLua that makes!


01242008 12:03 PM 


mikshaw
Senior Member
Posts: 522
Group: Registered
Joined: Apr 2007
Status:
Offline
Reputation: 5

RE: someone with mad math skills, help please
I like this version best so far
EDIT: I think the warp equations might be in need of even more work. It looks fine on my 1024x768 resolution, but I think higher resolutions might end up with a lot of empty space.
balls=1500  number of dots
bsize=2  dot size
max_grav=6  maximum gravity
hole=20  distance from cursor within which dots warp
function grav_loop()
local my_x,my_y=Fl:event_x(),Fl:event_y()  cursor location
local xspeed,yspeed,bx,by  initialize some local vars
local c=math.random(1,255)  random color (except black)
for i=1,balls do
 find distance of dots from the cursor
local xdistance=math.abs(my_xball[i]:x())  horz distance from cursor
local ydistance=math.abs(my_yball[i]:y())  vert distance
local distance=math.sqrt(xdistance^2+ydistance^2)  as the crow flies
if distance <= hole then
ball[i]:color(c)  set the color of the dot about to be warped
 These equations have no defined mathematical logic behind them.
 I was just playing with numbers until something cool happened.
 xspeed and yspeed are actually distance measurements (how far to move the dot in one loop)
 random offset prevents the dots from eventually converging on a single xy intersection
xspeed=distance*xdistance*2+math.random(50,50)
yspeed=distance*ydistance*2+math.random(50,50)
else
 thanks to Juergen for help with this
xspeed=max_grav/distance*xdistance
yspeed=max_grav/distance*ydistance
end
 move the dot according to its relative position to cursor
if my_x > ball[i]:x() then bx=ball[i]:x()+xspeed else bx=ball[i]:x()xspeed end
if my_y > ball[i]:y() then by=ball[i]:y()+yspeed else by=ball[i]:y()yspeed end
ball[i]:position(bx,by)
end
w:redraw()
grav_timer:doWait(.05)
end
 make the window the size of your screen
w=fltk:Fl_Double_Window(Fl:w(),Fl:h(),"gravity test")
w:color(0)
math.randomseed(os.time())  set a seed for upcoming math.random()
 set up dots in random locations
ball={}
for i=1,balls do
ball[i]=fltk:Fl_Box(math.random(1,w:w()),math.random(1,w:h()),bsize,bsize)
ball[i]:box(fltk.FL_FLAT_BOX)
end
grav_timer = murgaLua.createFltkTimer()
grav_timer:callback(grav_loop)
grav_timer:do_callback()
w:fullscreen()
w:show()
w:cursor(66)  cross
Fl:run()
This post was last modified: 01252008 02:43 AM by mikshaw.


01252008 02:36 AM 


