Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Programming challenge, gravity
Message
De
22/06/2004 12:47:39
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Titre:
Programming challenge, gravity
Divers
Thread ID:
00916106
Message ID:
00916106
Vues:
60
Hey all,

If anyone's got some spare time, and wants a challenge.

I wrote this program almost a month ago now thinking I'd have plenty of time to play with it (hahahah!) but I haven't.

So I thought I'd post it here. Its real "raw", I just slapped it together in a couple hours, about an hour of coding after about an hour of scribbling numbers and triangles on paper. Since I haven't been able to play with it, I thought maybe someone here might.

I'm wondering a couple things:

1. How can this program be written for awesome performance?
2. How can this program be written so that the physical units can be made adjustable?
3. How can this program be written to calculate the elapsed time in second given physical units like meter and kilogram?
4. Can anyone get the program to do all of the above, giving us a single program that with the appropriate parameters gives us the following three models:

a. An apple falling to the ground
b. The moon orbiting the earth
c. The first three planets (all nine would be nice of course) orbiting the sun

5. How else can this program be made "cool"? What languages do you think would be best suited for it?

In the program I'm posting I'm not even sure if I'm doing Newton's law correctly so that would have to be checked too.

Here's some data that might help:
http://hyperphysics.phy-astr.gsu.edu/hbase/solar/sun.html#c1
http://hyperphysics.phy-astr.gsu.edu/hbase/solar/soldata2.html

And here's the VFP7 code:
* Goals of this model
* 1. Allow for the creation of bodies with the following properties
*    Position (X,Y)
*    Speed (X,Y)
*    Mass
* 2. Add inertia
* 3. Add gravitational force
* 4. Place two bodies in some space and have one orbit the other

DECLARE Sleep IN Win32API INTEGER nMilliseconds

*LOCAL sun, earth
*!*	sun = CREATEOBJECT("body")
*!*	sun.mass	= 1.98892 * 10^30
*!*	sun.X		= 200000000
*!*	sun.Y		= 200000000
*!*	moon = CREATEOBJECT("body")
*!*	moon.mass = 5.9742 * 10^24 * .0123


apple = CREATEOBJECT("body")
apple.mass = 1
*apple.X = 500
apple.X = 1200000
apple.Y = 5000000
apple.SpeedY = 5000
apple.SpeedX = 10000
apple.lSkipGravity = .T.

apple2 = CREATEOBJECT("body")
apple2.mass = 1
apple2.X = 3200000
apple2.Y = 0
apple2.SpeedX = 5000
apple2.lSkipGravity = .T.


earth = CREATEOBJECT("body")
earth.mass	= 5.9742 * 10^24
*earth.X		= 500
*earth.Y		= 500
earth.X		= 3200000
earth.Y		= 3200000
earth.Speedx= 0
earth.Speedy= 0
*earth.lSkipGravity = .T.

private aBodies[1], gui

DIMENSION aBodies[3]
aBodies[1] = apple && sun
aBodies[2] = earth
aBodies[3] = apple2

gui = CREATEOBJECT("modelview")
earth.oObject = gui.AddBody()
earth.oObject.BorderColor = RGB(0, 0, 255)
earth.oObject.FillColor = RGB(0, 0, 255)
apple.oObject = gui.AddBody()
apple.oObject.BorderColor = RGB(255, 0, 0)
apple.oObject.FillColor = RGB(255, 0, 0)
apple2.oObject = gui.AddBody()
apple2.oObject.BorderColor = RGB(0, 255, 0)
apple2.oObject.FillColor = RGB(0, 255, 0)
gui.Show()
RefreshView()

DO WHILE .T.

	GravitationalAcceleration()
	Inertia()
	RefreshView()
	=sleep(1)

ENDDO 

* Gravitational Acceleration... the hard part
FUNCTION GravitationalAcceleration

	* Adjust the acceleration of every object has on every other object
	LOCAL lo1, lo2, lng, ;
		lx, ly, ld, ;
		lxp, lyp
	FOR EACH lo1 IN aBodies
	
		IF lo1.lSkipGravity
			LOOP 
		ENDIF 

		FOR EACH lo2 IN aBodies
		
			IF lo1 = lo2
				LOOP 
			ENDIF 
		
			* First, find out the acceleration due to gravitation
			* between these two objects
			lng = Newton(lo1, lo2)
			
			* Now apply the acceleration to the second body
			DO CASE 

			* lo2 is below lo1
			CASE lo1.X = lo2.X AND lo1.Y > lo2.Y
				lo2.SpeedY = lo2.SpeedY + lng

			* lo2 is above lo1
			CASE lo1.X = lo2.X AND lo1.Y < lo2.Y
				lo2.SpeedY = lo2.SpeedY - lng

			* lo2 is left of lo1
			CASE lo1.Y = lo2.Y AND lo1.X > lo2.X
				lo2.SpeedX = lo2.SpeedX + lng

			* lo2 is right of lo1
			CASE lo1.Y = lo2.Y AND lo1.X < lo2.X
				lo2.SpeedX = lo2.SpeedX - lng
				
			*Otherwise, we're at an angle
			OTHERWISE 
			
				* Step 1, find out the distance between o1 and o2
				lx = lo1.X - lo2.X
				ly = lo1.Y - lo2.Y
				ld = SQRT(lx^2 + ly^2)
				
				* Step 2, find the legs of the new triangle
				lxp = lx * (lng / ld)
				lyp = ly * (lng / ld)
				
				lo2.SpeedX = lo2.SpeedX + lxp
				lo2.SpeedY = lo2.SpeedY + lyp
			
			
			ENDCASE 
		ENDFOR 
	ENDFOR 
RETURN 

FUNCTION Newton
	LPARAMETERS to1, to2
	LOCAL lnResult
	* This should calculate the force of gravity based on G * (m1*m2)/r^2
	* But for the apple/earth example we know the accelation is 4.9m/s/s
	
	lx = to1.X - to2.X
	ly = to1.Y - to2.Y
	ld = SQRT(lx^2 + ly^2)
	
	lnResult= 6.67300 * 10^-11 * ((to1.Mass * to2.Mass)/ld^2)
	*WAIT WINDOW TRANSFORM(lnResult)
	
RETURN lnResult && 4.9


FUNCTION Inertia

	LOCAL loB
	FOR EACH loB IN aBodies
		IF loB.SpeedX = 0 AND loB.SpeedY = 0
			loB.lChanged = .F.
		ELSE 
			loB.X = loB.X + loB.SpeedX
			loB.Y = loB.Y + loB.SpeedY
			loB.lChanged = .T.
		ENDIF 
	ENDFOR 

RETURN 

FUNCTION RefreshView

	LOCAL loB
	gui.LockScreen = .T.
	FOR EACH loB IN aBodies
		IF loB.lChanged
			loB.oObject.Left = loB.X / 10000
			loB.oObject.Top = loB.Y / 10000
		ENDIF 
	ENDFOR 
	gui.LockScreen = .F.

*	earth.oObject.Parent.LockScreen = .T.
*	earth.oObject.Left = earth.X
*	earth.oObject.Top = earth.Y
*	earth.oObject.Parent.LockScreen = .F.
RETURN 

DEFINE CLASS body AS Custom 

	Mass = 0
	SpeedX = 0
	SpeedY = 0
	X = 0
	Y = 0
	lChanged = .T.
	lSkipGravity = .F.
	oObject = .NULL.
	
	FUNCTION Destroy
		this.oObject = .NULL.
	RETURN 

ENDDEFINE 

DEFINE CLASS modelview AS Form
	Desktop = .T.
	BackColor = 0
	Width = 700
	Height = 700
	ShowWindow = 2

	FUNCTION Init
*		this.WindowState = 2
	RETURN 

	FUNCTION AddBody
		LOCAL lcName, loO
		lcName = SYS(2015)
		this.AddObject(lcName, "BodyGui")
		loO = EVALUATE("this." + lcName)
		loO.Visible = .T.
	RETURN loO
ENDDEFINE 

DEFINE CLASS bodygui as Shape 

	fillstyle = 0
	curvature = 99
	width = 4
	height = 4
	
ENDDEFINE
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform