Quellcode beliebig verändert werden) angezogen wird. In diesem Fall sind die Massen jedoch fest und nicht selbst
beweglich (vgl. Magnetpendel).
Code: Alles auswählen
Enumeration
#Window
#ImageGadget
#XText
#XSpin
#YText
#YSpin
#Start
#Pause
#Stop
#Erase
#ActX
#ActY
#Kraftfeld
#Hintergrund
#HintergrundThread
#Display
EndEnumeration
Structure df
fx.d
fy.d
EndStructure
Structure mass
x.d
y.d
m.d
EndStructure
Global Gravitation_Const.d=1,StdMass.d=1
Global NewList Masses.mass()
m.d=1000000
Dist.d=200
Global w.l,h.l,KoordX.l,KoordY.l
w=600
h=600
KoordX=457
KoordY=254
CreateImage(#Hintergrund,w*2,h)
CreateImage(#HintergrundThread,w*2,h)
CreateImage(#Kraftfeld,w,h)
CreateImage(#Display,w*2,h)
Raster=40
radius=2*Raster/40
First=1
If First<>0
AddElement(Masses())
Masses()\x=300+Cos(60*#PI/180)*Dist
Masses()\y=300+Sin(60*#PI/180)*Dist
Masses()\m=m
EndIf
Second=1
If Second<>0
AddElement(Masses())
Masses()\x=300+Cos(180*#PI/180)*Dist
Masses()\y=300+Sin(180*#PI/180)*Dist
Masses()\m=m
EndIf
Third=1
If Third<>0
AddElement(Masses())
Masses()\x=300+Cos(300*#PI/180)*Dist
Masses()\y=300+Sin(300*#PI/180)*Dist
Masses()\m=m
EndIf
Fourth=1
If Fourth<>0
AddElement(Masses())
Masses()\x=300
Masses()\y=300
Masses()\m=m
EndIf
Procedure.d Absolute(*Vector.df)
Distance.d=Sqr(*Vector\fx**Vector\fx+*Vector\fy**Vector\fy)
ProcedureReturn Distance
EndProcedure
Procedure.l GetColor(Absolute.d)
;ColorSeed.c=Int(Sqr(Absolute)/680*255)
ColorSeed=Int(Absolute)
Color.l=RGB(255-ColorSeed,255-ColorSeed,255)
ProcedureReturn Color
EndProcedure
Procedure.d GetAngle(Sin.d,Cos.d)
Angle.d=ATan(Sin/Cos)
If Sin<0 And Cos<0
Angle+#PI
ElseIf Cos<0 And Sin>=0
Angle+#PI
ElseIf Sin<0 And Cos>=0
Angle+2*#PI
EndIf
If Angle>2*#PI
Angle-2*#PI
EndIf
ProcedureReturn Angle
EndProcedure
Procedure GetGravitation(x.d,y.d,*Vector.df)
ResetList(Masses())
*Vector\fx=0
*Vector\fy=0
While NextElement(Masses())
deltax.d=(x-Masses()\x)
deltay.d=(y-Masses()\y)
r.d=Sqr(deltax*deltax+deltay*deltay)
F.d=-Gravitation_Const*StdMass*Masses()\m/(r*r)
*Vector\fx+F*deltax/r
*Vector\fy+F*deltay/r
Wend
EndProcedure
Procedure DrawTestMass(x,y)
If x<=w
Circle(x,y,4,RGB(200,200,200))
Circle(x,y,3,RGB(000,128,128))
EndIf
EndProcedure
Procedure Simulation()
CopyImage(#Hintergrund,#HintergrundThread)
x.d=KoordX
y.d=KoordY
TimeStep=8
Repeat
GetGravitation(x,y,Kraft.df)
ax.d=Kraft\fx/StdMass
ay.d=Kraft\fy/StdMass
vx.d=vx+ax*TimeStep/1000
vy.d=vy+ay*TimeStep/1000
x =x +vx*TimeStep/1000
y =y +vy*TimeStep/1000
StartDrawing(ImageOutput(#HintergrundThread))
;Circle(Int(x) ,Int(y),1,RGB(000,128,128))
Circle(Int(x+w),Int(y),1,RGB(000,128,128))
StopDrawing()
StartDrawing(ImageOutput(#Display))
DrawImage(ImageID(#HintergrundThread),0,0)
DrawTestMass(Int(x) ,Int(y))
;DrawTestMass(Int(x+w),Int(y))
StopDrawing()
SetGadgetState(#ImageGadget,ImageID(#Display))
SetGadgetText(#ActX,"Aktuell X: "+Str(x))
SetGadgetText(#ActY,"Aktuell Y: "+Str(y))
Delay(TimeStep/2)
Until x>w Or y>h Or x<0 Or y<0
DisableGadget(#Start,0)
DisableGadget(#Pause,1)
DisableGadget(#Stop ,1)
DisableGadget(#XSpin,0)
DisableGadget(#YSpin,0)
DisableGadget(#Erase,0)
Repeat
Delay(10)
ForEver
EndProcedure
Procedure Erase()
StartDrawing(ImageOutput(#Display))
DrawImage(ImageID(#Hintergrund),0,0)
DrawTestMass(KoordX,KoordY)
StopDrawing()
SetGadgetState(#ImageGadget,ImageID(#Display))
SetGadgetText(#ActX,"Aktuell X: "+Str(KoordX))
SetGadgetText(#ActY,"Aktuell Y: "+Str(KoordY))
EndProcedure
OpenWindow(#Window,0,0,w*2,h+40,"Gravitationsfeld, -linien und -simulation",#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
StartDrawing(ImageOutput(#Kraftfeld))
For x=0 To w
For y=0 To h
GetGravitation(x,y,Vector.df)
Abs.d=Absolute(Vector)
Plot(x,y,Int(Abs))
Next y
Next x
StopDrawing()
StartDrawing(ImageOutput(#Hintergrund))
DrawImage(ImageID(#Kraftfeld),0,0)
For x=0 To w
For y=0 To h
If x%Raster=0 And y%Raster=0 And x<w And y<h And x<>0 And y<>0
GetGravitation(x,y,Vector.df)
Angle.d=GetAngle(Vector\fy,Vector\fx)
dx.l=Int(Cos(Angle)*10*Raster/40)
dy.l=Int(Sin(Angle)*10*Raster/40)
dA.d=#PI/6+#PI
dxp1.l=Int(Cos(Angle+dA)*7*Raster/40)
dyp1.l=Int(Sin(Angle+dA)*7*Raster/40)
dxp2.l=Int(Cos(Angle-dA)*7*Raster/40)
dyp2.l=Int(Sin(Angle-dA)*7*Raster/40)
Circle(x,y,radius,16777215)
Line(x-dx,y-dy,dx*2,dy*2,16777215)
Line(x+dx,y+dy,dxp1,dyp1,16777215)
Line(x+dx,y+dy,dxp2,dyp2,16777215)
Circle(x+w,y,radius,16777215)
Line(x-dx+w,y-dy,dx*2,dy*2,16777215)
Line(x+dx+w,y+dy,dxp1,dyp1,16777215)
Line(x+dx+w,y+dy,dxp2,dyp2,16777215)
EndIf
Next y
Next x
StopDrawing()
StartDrawing(ImageOutput(#Display))
DrawImage(ImageID(#Hintergrund),0,0)
DrawTestMass(KoordX,KoordY)
StopDrawing()
CreateGadgetList(WindowID(#Window))
ImageGadget(#ImageGadget,0,0,w*2,h,ImageID(#Display))
TextGadget(#XText, 10,h+10 ,40,20,"Start-X:")
StringGadget(#XSpin, 50,h+10-3,60,20,Str(KoordX),#PB_String_Numeric|#PB_Text_Right)
TextGadget(#YText,120,h+10 ,40,20,"Start-Y:")
StringGadget(#YSpin,160,h+10-3,60,20,Str(KoordY),#PB_String_Numeric|#PB_Text_Right)
ButtonGadget(#Start,280,h+10-3,50,20,"Start")
ButtonGadget(#Pause,340,h+10-3,50,20,"Pause")
DisableGadget(#Pause,1)
ButtonGadget(#Stop, 400,h+10-3,50,20,"Stop")
DisableGadget(#Stop ,1)
ButtonGadget(#Erase,460,h+10-3,50,20,"Löschen")
DisableGadget(#Erase,1)
TextGadget(#ActX,520,h+10,70,20,"Aktuell X: "+Str(KoordX))
TextGadget(#ActY,600,h+10,70,20,"Aktuell Y: "+Str(KoordY))
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case #XSpin
KoordX=Val(GetGadgetText(#XSpin))
If KoordX>w
KoordX=w
SetGadgetText(#XSpin,Str(KoordX))
ElseIf KoordX<0
KoordX=0
SetGadgetText(#XSpin,Str(KoordX))
EndIf
StartDrawing(ImageOutput(#Display))
DrawImage(ImageID(#Hintergrund),0,0)
DrawTestMass(KoordX,KoordY)
StopDrawing()
SetGadgetState(#ImageGadget,ImageID(#Display))
Case #YSpin
KoordY=Val(GetGadgetText(#YSpin))
If KoordY>h
KoordY=h
SetGadgetText(#YSpin,Str(KoordY))
ElseIf KoordY<0
KoordY=0
SetGadgetText(#YSpin,Str(KoordY))
EndIf
StartDrawing(ImageOutput(#Display))
DrawImage(ImageID(#Hintergrund),0,0)
DrawTestMass(KoordX,KoordY)
StopDrawing()
SetGadgetState(#ImageGadget,ImageID(#Display))
Case #Start
If IsThread(Simulation)
KillThread(Simulation)
EndIf
Simulation=CreateThread(@Simulation(),0)
DisableGadget(#Start,1)
DisableGadget(#Pause,0)
DisableGadget(#Stop ,0)
DisableGadget(#XSpin,1)
DisableGadget(#YSpin,1)
DisableGadget(#Erase,1)
Case #Pause
If IsThread(Simulation)
If ThreadPaused=0
ThreadPaused=1
PauseThread(Simulation)
ElseIf ThreadPaused=1
ThreadPaused=0
ResumeThread(Simulation)
EndIf
EndIf
Case #Stop
If IsThread(Simulation)
KillThread(Simulation)
EndIf
DisableGadget(#Start,0)
DisableGadget(#Pause,1)
DisableGadget(#Stop ,1)
DisableGadget(#XSpin,0)
DisableGadget(#YSpin,0)
DisableGadget(#Erase,0)
Case #Erase
DisableGadget(#Erase,1)
Erase()
EndSelect
EndSelect
Until event=#PB_Event_CloseWindow