I am making a program to calculate speed and direction of an object in 3D space to reach an astro orbit.
I've made lots of things related to this.
You can try this elliptical particle movement and push LMB to reach it in 2 seconds (or the time you choose). The calculations are done in 3D, but it is displayed in 2D.
Well now i need this equation to be solved, and it is hard to me:
Solving 't' from this equation (all other terms are known) this tip can be done giving a stablished speed for the projectile launched, and the time is calculated depending on that speed.t^2 * M^2 = ((dx + Rbx * Cos(w*t+fi) + Rsx * Sin(w*t+fi))^2 + ((dy + Rby * Cos(w*t+fi) + Rsy * Sin(w*t+fi))^2 + ((dz + Rbz * Cos(w*t+fi) + Rsz * Sin(w*t+fi))^2
Can someone help solving it? I can't, or i'd delay on it several days.
Thanks in advance.
Code: Select all
;******************************************************
;Seek & Shoot to elliptic way moving object (in 3D space):
;******************************************************
#PI=3.14159265:#DEGTORAD=0.01745329:#RADTODEG=57.2957795
#objradius=2:#refresh=60:#dly=16
#cursorradius=8:#Explosionsize=21
DefType .f
projspeed.f=5;<-rectilineus and constant speed for projectiles
MainAxisx.f=341:MainAxisy.f=0:MainAxisz.f=0
SecAxisx.f=0:SecAxisy.f=123:SecAxisz.f=0
phi.f=0; <- circular rotation angle
omega.f=0.0581333 ; <- circular rotation speed (angular speed)
time.f=2*#refresh
;
Procedure.b Collision(p1x.f,p1y.f,p1z.f,m1x.f,m1y.f,m1z.f,p2x.f,p2y.f,p2z.f,m2x.f,m2y.f,m2z.f)
w.f=#objradius
p1xp.f=p1x+w:p1xm.f=p1x-w:p1yp.f=p1y+w:p1ym.f=p1y-w:p2xp.f=p2x+w:p2xm.f=p2x-w:p2yp.f=p2y+w:p2ym.f=p2y-w
p1zp.f=p1z+w:p1zm.f=p1z-w:p2zp.f=p2z+w:p2zm.f=p2z-w
If ((p1zm<=p2zp And p1zp>=p2zm+m2z) Or (p1zp>=p2zm And p1zm<=p2zp+m2z)) Or ((p2zm<=p1zp And p2zp>=p1zm+m1z) Or (p2zp>=p1zm And p2zm<=p1zp+m1z))
If ((p1xm<=p2xp And p1xp>=p2xm+m2x) Or (p1xp>=p2xm And p1xm<=p2xp+m2x)) And ((p1ym<=p2yp And p1yp>=p2ym+m2y) Or (p1yp>=p2ym And p1ym<=p2yp+m2y))
ProcedureReturn 1
EndIf
If ((p2xm<=p1xp And p2xp>=p1xm+m1x) Or (p2xp>=p1xm And p2xm<=p1xp+m1x)) And ((p2ym<=p1yp And p2yp>=p1ym+m1y) Or (p2yp>=p1ym And p2ym<=p1yp+m1y))
ProcedureReturn 1
EndIf
EndIf
ProcedureReturn 0
EndProcedure
;-INITS:
bitplanes.b=32
SCREENWIDTH.l=GetSystemMetrics_(#SM_CXSCREEN):SCREENHEIGHT.l=GetSystemMetrics_(#SM_CYSCREEN)
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error","Can't access DirectX",0):End
EndIf
While OpenScreen(SCREENWIDTH,SCREENHEIGHT,bitplanes.b,"")=0
If bitplanes.b>16:bitplanes.b-8
ElseIf SCREENHEIGHT>600:SCREENWIDTH=800:SCREENHEIGHT=600
ElseIf SCREENHEIGHT>480:SCREENWIDTH=640:SCREENHEIGHT=480
ElseIf SCREENHEIGHT>400:SCREENWIDTH=640:SCREENHEIGHT=400
ElseIf SCREENHEIGHT>240:SCREENWIDTH=320:SCREENHEIGHT=240
ElseIf SCREENHEIGHT>200:SCREENWIDTH=320:SCREENHEIGHT=200
Else:MessageRequester("Listen:","Can't open Screen!",0):End
EndIf
Wend
;
CreateSprite(0,16,16);<-The mouse cursor
StartDrawing(SpriteOutput(0)):BackColor(0,0,0)
Line(0,0,15,10,$CABE2A)
Line(0,0,5,15,$CABE2A)
LineXY(5,15,15,10,$CABE2A)
FillArea(2,2,$CABE2A,$C0C1D0)
StopDrawing()
CreateSprite(1,#objradius*2,#objradius*2);<-the object
StartDrawing(SpriteOutput(1)):BackColor(0,0,0)
Circle(#objradius,#objradius,#objradius,$50F0CA)
StopDrawing()
;
ox.f=SCREENWIDTH.l/2:oy.f=SCREENHEIGHT.l/2:oz.f=0; <- geometrical center of ellipse
MainAxisMod.f=Sqr(MainAxisx.f*MainAxisx.f+MainAxisy.f*MainAxisy.f+MainAxisz.f*MainAxisz.f); <- radius 0 (a.k.a. semiaxis) and its length (modulo)
SecAxisMod.f=Sqr(SecAxisx.f*SecAxisx.f+SecAxisy.f*SecAxisy.f+SecAxisz.f*SecAxisz.f); <- radius 1 (a.k.a. semiaxis) and its length (modulo)
;Positionate both Focuses of the ellipse:
If SecAxisMod.f>MainAxisMod.f; <- it this is true, it means MAIN AXIS (where the Focuses are posistionated) SECONDARY AXIS must be swapped
xch.f=SecAxisMod.f:SecAxisMod.f=MainAxisMod.f:MainAxisMod.f=xch.f; <- Swap it
xch.f=SecAxisx.f:SecAxisx.f=MainAxisx.f:MainAxisx.f=xch.f; <- Swap it
xch.f=SecAxisy.f:SecAxisy.f=MainAxisy.f:MainAxisy.f=xch.f; <- Swap it
xch.f=SecAxisz.f:SecAxisz.f=MainAxisz.f:MainAxisz.f=xch.f; <- Swap it
EndIf
;
MouseLocate(ox.f,oy.f); <- lets locate mouse cursor just in the geometrical center of the ellipse
;-MAIN:
Repeat
ExamineKeyboard():ExamineMouse()
x.f=MouseX():y.f=MouseY():z.f=0
targetoldx.f=targetx.f:targetoldy.f=targety.f:targetoldz.f=targetz.f
vx.f=MainAxisx.f*Cos(phi)+SecAxisx.f*Sin(phi):vy.f=MainAxisy.f*Cos(phi)+SecAxisy.f*Sin(phi):vz.f=0
targetx.f=ox.f+vx.f:targety.f=oy.f+vy.f:targetz.f=oz.f-vz.f
targetmx.f=targetx.f-targetoldx.f:targetmy.f=targety.f-targetoldy.f:targetmz.f=targetz.f-targetoldz.f
ClearScreen(0,0,0)
If MouseButton(1) And shot.b=0
shot.b=1
shotx.f=x.f:shoty.f=y.f:shotz.f=z.f
wx.f=MouseDeltaX():wy.f=MouseDeltaY():wz.f=0; <- speed vector of the base before launch projectile
Gosub shot;<-shot to it
EndIf
;
If shot.b:Gosub moveshot:EndIf
If collide.b:Gosub boom:EndIf
;
DisplayTransparentSprite(1,targetx.f-#objradius,targety.f-#objradius)
DisplayTransparentSprite(0,x.f,y.f);draw mouse pointer sprite
phi.f+omega.f:If phi>=#PI:phi-2*#PI:EndIf
FlipBuffers():Delay(#dly);<--swap buffers
Until KeyboardPushed(#PB_Key_Escape)
ReleaseMouse(1):CloseScreen():End
;-Subroutines:
shot:; FIXED TIME ALGORITHM:
dx.f=ox-x:dy.f=oy-y:dz.f=oz-z
shotmx.f=(dx+MainAxisx.f*Cos(omega.f*time+phi)+SecAxisx.f*Sin(omega.f*time+phi))/time
shotmy.f=(dy+MainAxisy.f*Cos(omega.f*time+phi)+SecAxisy.f*Sin(omega.f*time+phi))/time
shotmz.f=(dz+MainAxisz.f*Cos(omega.f*time+phi)+SecAxisz.f*Sin(omega.f*time+phi))/time
initcount.l=ElapsedMilliseconds()
Return
moveshot:
If shotx.f>SCREENWIDTH.l Or shotx.f<0 Or shoty.f>SCREENHEIGHT.l Or shoty.f<0:shot.b=0:Return:EndIf
DisplayTransparentSprite(1,shotx.f-#objradius,shoty.f-#objradius);draw our projectile sprite
timecount.f=(ElapsedMilliseconds()-initcount.l)/1000
If Collision(targetx.f,targety.f,targetz.f,targetmx.f,targetmy.f,targetmz.f,shotx.f,shoty.f,shotz.f,shotmx.f,shotmy.f,shotmz.f)
shot.b=0:shotmx.f=0:shotmy.f=0:shotmz.f=0
collide.b=#objradius
collx.f=targetx.f:colly.f=targety.f:collmx.f=targetmx.f/3:collmy.f=targetmy.f/3
Else
shotx.f+shotmx.f
shoty.f+shotmy.f
shotz.f+shotmz.f
EndIf
Return
boom:
If collide.b<=#Explosionsize
StartDrawing(ScreenOutput())
Circle(collx.f,colly.f,collide.b,$FFFFFF)
StopDrawing()
collx.f+collmx.f:colly.f+collmy.f
collide.b+1
Else
StartDrawing(ScreenOutput())
Circle(collx.f,colly.f,#Explosionsize*2-collide.b,$0F0FFF)
StopDrawing()
collx.f+collmx.f/2:colly.f+collmy.f/2
collide.b+1:If collide.b>=#Explosionsize*2:collide.b=0:EndIf
EndIf
Return



