News : The level of daily SPAM has reached insane proportions, all registrations are now manual. I ask you to send me an e-mail (john (at) murga (dot) org), to confirm that you want me to create an account for you.


Post Reply  Post Thread 
Pages (2): « First [1] 2 Next > Last »
someone with mad math skills, help please
Author Message
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #1
Question  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 non-negative number

Is there anyone who might be able to help?
Thanks.

This is the last thing I do before releasing the widgets-demo beta1

01-23-2008 09:39 AM
Find all posts by this user Quote this message in a reply
Juergen
Member
***


Posts: 81
Group: Registered
Joined: May 2007
Status: Offline
Reputation: 0
Post: #2
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

01-23-2008 10:17 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #3
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: 01-23-2008 11:28 AM by mikshaw.

01-23-2008 11:25 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #4
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:

Code:
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_x-ball[i]:x())
    local ydistance=math.abs(my_y-ball[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: 01-23-2008 12:27 PM by mikshaw.

01-23-2008 12:18 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #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.

01-23-2008 12:41 PM
Find all posts by this user Quote this message in a reply
Juergen
Member
***


Posts: 81
Group: Registered
Joined: May 2007
Status: Offline
Reputation: 0
Post: #6
RE: someone with mad math skills, help please

mikshaw Wrote:
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 N-body 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

01-24-2008 08:01 AM
Find all posts by this user Quote this message in a reply
Juergen
Member
***


Posts: 81
Group: Registered
Joined: May 2007
Status: Offline
Reputation: 0
Post: #7
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:

Code:
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()

01-24-2008 08:31 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #8
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:

Code:
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_x-ball[i]:x())
    local ydistance=math.abs(my_y-ball[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()

01-24-2008 09:25 AM
Find all posts by this user Quote this message in a reply
iGame3D
Moderator
***


Posts: 231
Group: Moderators
Joined: Apr 2007
Status: Offline
Reputation: 0
Post: #9
RE: someone with mad math skills, help please

ooh ahh thats so cool!
Comment that script, what a neat intro to murgaLua that makes!

01-24-2008 12:03 PM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #10
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.

Code:
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_x-ball[i]:x()) -- horz distance from cursor
    local ydistance=math.abs(my_y-ball[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 x-y 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: 01-25-2008 02:43 AM by mikshaw.

01-25-2008 02:36 AM
Find all posts by this user Quote this message in a reply
Pages (2): « First [1] 2 Next > Last »
Post Reply  Post Thread 

View a Printable Version
Send this Thread to a Friend
Subscribe to this Thread | Add Thread to Favorites

Forum Jump: