Values converge to zero

BlitzMax Forums/BlitzMax Programming/Values converge to zero

Heliotrope(Posted 2015) [#1]
Hi there, I am tring to make a gravity simulator, but the x and y corrds converge to zero and I have no idea why can anyone help?

The algorithm - https://msdn.microsoft.com/en-us/library/dn528554%28v=vs.85%29.aspx

Graphics (640,480)
'SeedRnd MilliSecs ()
Global objcnt% = 3
Global asizex% = 640, asizey% = 480
Global g# = 6.67 * 10^-11
Global arr1# [objcnt%,5,2]

'Fill the program with masses and their variables
For t = 0 To objcnt - 1
	arr1 [t, 0,1] = Rnd (1,10)   'mass
	arr1 [t, 1,1] = Rnd (asizex) 'x location
	arr1 [t, 2,1] = Rnd (asizey) 'y location
	arr1 [t, 3,1] = Rand (-1,1)  'x direction 
	arr1 [t, 4,1] = Rand (-1,1)  'y direction 
Next 

'Main loop
Repeat 
	
	Cls
	'Make array equal 
	For t = 0 To objcnt - 1
		For t2 = 0 To 4
			arr1 [t,t2,0] = arr1 [t,t2,1]
		Next 
	Next
	
	'Draw to the screen the masses
	For t = 0 To objcnt - 1
		mass = arr1 [t,0,0]
		x = arr1 [t,1,0]
		y = arr1 [t,2,0]
		'constraints
		If x < 0 Then x = 0 And SetColor (255,0,0)
		If x > asizex Then x = asizex And SetColor (255,0,0)
		If y < 0 Then y = 0 And SetColor (255,0,0)
		If y > asizey Then y = asizex And SetColor (255,0,0)
		DrawText (mass,x,y)
		SetColor (255,255,255)
	Next 
	
	'Calculate gravity 
	For t = 0 To objcnt - 1
		For t2 = 0 To objcnt - 1
			'seperation calculations
			xdif = arr1 [t,1,1] - arr1 [t2,1,1]
			ydif = arr1 [t,2,1] - arr1 [t2,2,1]
			totala = Sqr (xdif^2 + ydif^2)
			
			'acceleration calculations
			xacc = g * ((arr1 [t2,0,1] * xdif) / totala)
			yacc = g * ((arr1 [t2,0,1] * ydif) / totala)
			
			'position calculations
			arr1 [t,1,1] = arr1 [t,1,1] + xacc Mod asizex
			arr1 [t,2,1] = arr1 [t,2,1] + yacc Mod asizey
		Next
	Next 
	
	Flip 
	WaitKey ()
	
Until KeyHit (key_escape) Or AppTerminate ()

End 



Brucey(Posted 2015) [#2]
You haven't defined types for lots of your variables.
They will default to Int - in which case your calculations will be somewhat rounded.

I suggest sticking a SuperStrict at the top of your code and fix all the resulting errors.


Matty(Posted 2015) [#3]
Another potential is your mod statement. You may find you need brackets around the first two terms of the expression otherwise you will simply be calculating the modulus of the second which I dont think is what you are wanting to. But brucey is correct about the variable declarations....particularly with the sqrt calc....you will be losing heaps of precision by using ints for that.


Matty(Posted 2015) [#4]
Oh....something worth considering much later on is replacing the power to symbols with a simple multiplication in the case of squaring variables....but get your other logic right first.


Matty(Posted 2015) [#5]
Oh.....one more....make sure you check for potential divide by zero errors.....your variable totala has the possibility of being zero....


Matty(Posted 2015) [#6]
Edit technically it should crash the very first time due to divide by zero since you are calculating gravitation between an object and itself.....you need to skip iterations in the inner loop when the object indices are the same.


Floyd(Posted 2015) [#7]
Other issues
		If x < 0 Then x = 0 And SetColor (255,0,0)
That's not what And means.

Global g# = 6.67 * 10^-11
The value of g ( 0.0000000000667 ) is WAY too small to affect the other values, which are in the range of zero to a few hundred.


Matty(Posted 2015) [#8]
I think Floyd you just identified why his x and y values are all "converging to zero" as the OP says...those And statements are going to do that for every x and y value! (Assuming the compiler doesnt complain)



Edit - did the original authors name just change or am I seeing things???


Brucey(Posted 2015) [#9]
You're just seeing things.


Heliotrope(Posted 2015) [#10]
Hi guys It sort of works now but the objects keep throwing eachother out further than they came in. I don't think thats normal.




Matty(Posted 2015) [#11]
Your acceleration has the wrong sign.


Think of it like this:

If you want an attractive force then the acceleration should be in the opposite direction to the position vector from one object to the other.


I can also see you are going to have problems if you increase the objcnt beyond two (have a look at where you deduct acc outside the inner loop)

As a test (after changing the signs of xacc and yacc) try setting obj 0 mass really big ( &#12299;1000 ) and obj 1 really small ( &#12298; 0.0x) and position obj 0 in the centre of the screen and obj 1 somewhere further away and give obj 0 an initial velocity of 0 and obj 1 an initial velocity that is fairly large but at right angles to its position relative to obj 0.

You should (with a bit of tweaking) get an orbit.


Floyd(Posted 2015) [#12]
I won't try debug whatever you are doing, but will comment on what should happen.

You will have several point masses ( objects ). All changes will be done for one timeslice. Each object must know it's own mass, position, velocity and acceleration ( change in velocity for next step ). The latter three will be two values, for x and y.

All changes for the next step must be calculated before any of those changes are actually made. So the general plan is this:

For each object
	initialize total acceleration to zero
	For each other object
		compare with that other object
		calculate the acceleration change which that other object will produce
		add that change to the running total of the total acceleration
	Next
	Store the total acceleration ( x and y ) into the current object
Next

Now loop through all objects and apply the acceleration calculated in the previous step.



Heliotrope(Posted 2015) [#13]
Seems to work now, just had to fix the read write operations.

The final code...



If your RNG is the same as mine it should generate a 2,4,9 if you haven't seeded it. The 2 and the 4 being lighter will chaotically orbit around the 9.


Heliotrope(Posted 2015) [#14]
Update - I have tried to convert the code to monkey, but as I am new to it can't seen where I've gone wrong.