Try integrating accelerations (or better yet forces) to get velocities instead.

Please log in or register to post a reply.

I suppose i should show the gravity code. basic/sudo code

```
;---------------------------CREATE GRAVITY---------------------------
;gravityforce - is a constant gravity value
;gravity_x# - x axis point of source of gravity
;gravity_y# - y axis point of source of gravity
;gravity_z# - z axis point of source of gravity
;mass# - combined mass of the objects
;surface_radius# - radius of the source of gravity
;atmospheric_radius - radius of atmosphere , introducing drag
;effect_radius# - radius of the gravitational effect
;MovingBody_x# - x axis point of the effected object
;MovingBody_y# - y axis point of the effected object
;MovingBody_z# - z axis point of the effected object
;MovingVx# - x axis velocity of the effected object
;MovingVy# - y axis velocity of the effected object
;MovingVz# - z axis velocity of the effected object
;NOTE: MovingVx#, MovingVy#,MovingVz# must be global and assigned outside of the function
; -----EXAMPLE-----
;MovingVx# = players_x_velocity#
;MovingVy# = players_y_velocity#
;MovingVz# = players_z_velocity#
;gravity(gravity_x#,gravity_y#,gravity_z#,mass#,surface_radius#,effect_radius#,MovingBody_x#,MovingBody_y#,MovingBody_z#)
;players_x_velocity# = MovingVx#
;players_y_velocity# = MovingVy#
;players_z_velocity# = MovingVz#
; ---END EXAMPLE---
;Or simply use MovingVx# And MovingVy# as your main x,y velocity variables for 2d gravity. (not tested)
Function gravity(gravity_x#,gravity_y#,Gravity_z#,mass#,surface_radius#,Atmospheric_radius#,effect_radius#,MovingBody_x#,MovingBody_y#,MovingBody_z#)
sd# = Abs(Distance#(MovingBody_x#,MovingBody_y#,MovingBody_z#,gravity_x#,gravity_y#,Gravity_z#))
drag# = 1
If sd# <= Atmospheric_radius# Then drag# = .98
If sd# <= surface_radius# Then
MovingVx# =0
MovingVy# =0
MovingVz# =0
Return
EndIf
If sd# <= effect_radius# Then
XYa# = Angle#(gravity_x#,gravity_y#,MovingBody_x#,MovingBody_y#)
YZa# = Angle#(gravity_y#,Gravity_z#,MovingBody_y#,MovingBody_z#)
ZXa# = Angle#(Gravity_z#,gravity_x#,MovingBody_z#,MovingBody_x#)
MovingVx# = ((MovingVx#+(((Sin(XYa#)+Cos(ZXa#))* gravityforce*mass#))/sd#)*drag#)
MovingVy# = ((MovingVy#+(((Sin(YZa#)+Cos(XYa#))* gravityforce*mass#))/sd#)*drag#)
MovingVz# = ((MovingVz#+(((Sin(ZXa#)+Cos(YZa#))* gravityforce*mass#))/sd#)*drag#)
EndIf
End Function
```

so as the player gets closer to the source of gravity it accelerates and moves around the object (unless the player is headed basically straight at it). I thought i was using acceleration or forces but I’m probably wrong.

I guess another way of stating my issue is, I cannot coordinate independent angular accelerations/movements (player) with independent positioning accelerations/movements (gravity). I hope this helps define my problem a bit more. Thank you for helping.

nvm I think i just fixed it. I still have my original problem though.

****] tags to post code; it keeps the formatting.

I will be more descriptive. I have been working on this issue for many days now and cant get it right. So.. here it goes.

basic/sudo code:

```
;returns the angle of 2 points.
Function Angle#(x1#,y1#,x2#,y2#)
Return ((ATan2(x2# - x1#,y2# - y1#)+180) Mod 360)
End Function
```

I am using this to find the angle between the players(x,y,z) location and an invisible point in space that is always 5 steps in front of the player, no matter what angle/direction the player is facing. (if the point were visible, the player would always see it directly in front if them)

```
;Calculate gravity
MovingVx# = xv#
MovingVy# = yv#
MovingVz# = zv#
gravity(sun(x),sun(y),sun(z),sun(radius)*player(mass),sun(radius),sun(radius)+10,sun(radius)^3,player(x),player(y),player(z))
xv# = MovingVx#
yv# = MovingVy#
zv# = MovingVz#
;Set thrust, moving force.
thrust# = 0
if leftmouseclick = true then thrust# = .5
;Get angles
XYa# = Angle2#(player(x),player(y),invisiblepoint(x),invisiblepoint(y))
YZa# = Angle2#(player(y),player(z),invisiblepoint(y),invisiblepoint(z))
ZXa# = Angle2#(player(z),player(x),invisiblepoint(z),invisiblepoint(x))
;Get players velocity on above angle
player(pxv#) = ((Sin(XYa#)-Cos(ZXa#))* (thrust#))
player(pyv#) = ((Sin(YZa#)-Cos(XYa#))* (thrust#))
player(czv#) = ((Sin(ZXa#)-Cos(YZa#))* (thrust#))
;Add players velocity to gravitational velocity
xv# = xv#+player(pxv#)
yv# = yv#+player(pyv#)
zv# = zv#+player(pzv#)
;Update the players position
mx# = player(x)+xv#*timestep#
my# = player(y)+yv#*timestep#
mz# = player(z)+zv#*timestep#
Position player,mx#,my#,mz#
```

In theory the above should work(i think). But I’ve narrowed the problem down to getting my angles for the player incorrectly or used improperly for determining the velocity in the right direction. I said before that the player movement was working, it’s not. sorry about that.

I figured it out.. my problem was with my angle# function

```
;returns the angle of 2 points.
Function Angle#(x1#,y1#,x2#,y2#)
Return ((ATan2(x2# - x1#,y2# - y1#)+180) Mod 360)
End Function
```

should have been

```
;returns the angle of 2 points.
Function Angle2#(x1#,y1#,x2#,y2#)
Return ATan2(x2# - x1#,y2# - y1#)
End Function
```

Its weird though.. cause the first angle works for the gravity but not
for player movement?? I am using both versions of the angle function
now.

everything works how I envisioned it.

thank you

I’m still having problems. What i have above tends to jump around a lot and in some directions it will gravitate toward the sun but not directly to it until a certain angle is reached then it will. Basically it’s not accurately fallowing a gravitational path. I have some new code that gets better accuracy but it still just isn’t right. I am changing from the previous description of the problem to better fit the issue at hand. For this description I shall use player(x,y,z), an invisible point invP(x,y,z) that is 10 steps in front of the player(x,y,z) point ,and shot(xv,yv,zv) . I will reference the angle# function from above in the code.

In this description the player is firing a weapon. the player will always be at player(0,0,0) for this example. when the player fires the weapon the shot should appear directly in front of them (center of the screen) no matter what direction the player is facing. With the code below, pitch works fine, yaw is inverted (and i cant just swap key’s around cause i’m using a mouse for the player’s control) .

here’s what i got so far:

```
x#=Angle#(invP(y),invP(z),player(y),player(z)) //pitch
y#=Angle#(invP(x),invP(z),player(x),player(z)) //yaw
z#=Angle#(invP(x),invP(Y),player(x),player(y)) //roll
xv = 0 // x axis velocity
yv = 0 // y axis velocity
zv = 2 // z axis velocity
//roll
tx = ((Cos(z#) * xv) - (Sin(z#) * yv))
ty = ((Sin(z#) * xv) + (Cos(Z#) * yv))
//yaw
tx = ((Cos(y#) * xv) - (Sin(y#) * zv))
tz = ((Sin(y#) * xv) + (Cos(y#) * zv))
//pitch
tz = ((Cos(X#) * zv) - (Sin(x#) * yv))
ty = ((Sin(X#) * zv) + (Cos(x#) * yv))
shot(xv) = tx
shot(yv) = ty
shot(zv) = tz
```

I have looked everywhere online for tutorials and forums but none have
anything that works completely. The above works for pitch and the ones
from tutorials work for yaw, but not both. If you can please, please
help.

Thank you.

Thats what i thought as well, but if i invert the yaw then both the
pitch and yaw have a peek or dip at 90 and -90 degree’s.

if the player rotates on the yaw axis it looks like

v—-

where — is the rotation and v is the dip.

This code would be a lot easier to read and write if you incorporated vector and matrix math routines.

PLEASE ask the math question instead of pasting a bunch of code in some obscure language.

If all you want is where to put the shot then the answer is trivial. Subtract the player position from the imaginary point “10 steps in front of the player” and divide by 10 to get a normalized direction vector for the player. The location of the shot is then the distance in front of the player you want the shot to appear multiplied by the unit direction vector plus the player position – no trig functions required.

Also, you have a typo:

```
xv = 0 // x axis velocity
yv = 0 // y axis velocity <-- shouldn't that be a 1?
zv = 2 // z axis velocity
```

@paul0n0n

Thats what i thought as well, but if i invert the yaw then both the pitch and yaw have a peek or dip at 90 and -90 degree’s.

if the player rotates on the yaw axis it looks like

v—-

where — is the rotation and v is the dip.

Sounds like you’re having trouble with angles wrapping around and making the trig functions do unintended things. It’s not totally clear to me how your control scheme works, but if you’re having the player rotate the camera with the mouse, you should just let the mouse movement change the yaw and pitch variables directly, then calculate the vector you need using spherical coordinates. Look at the spherical->Cartesian conversion on that page - it’s a standard formula that’s known to work right for all values of the angles.

@Reedbeta

calculate the vector you need using spherical coordinates

omg thank you this works perfectly. Talk about over thinking the problem!

now how do i get it to work if the player moves away from 0,0,0 ? That
was easy enough.

but then the farther away i get from 0,0,0 the shot starts jumping
around.. is there a fix for this?

so far this is what I am doing. shot has x,y,z as well, shot(x,y,z)

```
//start Cartesian coordinate system always at 0,0,0
// this works since the invP(x,y,z) is always 10 steps in front of the player (x,y,z) directional facing.
shot(x) = player(x)
shot(y) = player(y)
shot(z) = player(z)
tx = player(x)-invP(x)
ty = player(y)-invP(y)
tz = player(z)-invp(z)
//set up the initial velocity on each axis for use as a radial distance
xv = 0
yv = 0
zv = 2
// Cartesian coordinates to spherical coordinates
radialDistance = (xv^2+yv^2+zv^2) //uses the velocity's
azimuth = ATan2(ty,tx) //uses the invP
zenith = ATan2(SquareRoot(tx^2+ty^2),tz) //uses the invP
//convert spherical coordinates into Cartesian coordinates
shot(xv) = radialDistance * sin(zenith) * cos(azimuth)
shot(yv) = radialDistance * sin(zenith) * sin(azimuth)
shot(zv) = radialDistance * cos(zenith)
```

That code looks like it should work. However, you don’t need to convert to spherical coordinates and back again - all you’re doing there is scaling the tx, ty, tv vector to match the desired speed for the shot. You could do that just as well in Cartesian coordinates.

I wonder if the problem you’re seeing is with how the invP point is being calculated. I don’t see the need for invP at all. You can just keep track of (and/or let the user control) the desired azimuth and zenith, then convert those to Cartesian coordinates whenever needed.

@Reedbeta

That code looks like it should work. However, you don’t need to convert to spherical coordinates and back again - all you’re doing there is scaling the tx, ty, tv vector to match the desired speed for the shot. You could do that just as well in Cartesian coordinates.

I was trying to do that I think, but it wasn’t working or I was doing it wrong. I’m still not sure how to do it, a wiki page?

To scale a vector in Cartesian coordinates, all you have to do is multiply each component by the scaling factor. So if the vector is (tx, ty, tz), then (2*tx, 2*ty, 2*tz) is a vector in the same direction but twice as long.

Now if you want a vector to have a particular length, say 5, you first have to normalize it, which means scaling it to have length 1. Then you can scale it by 5, and it will have length 5. To normalize it, you just divide each component by the vector’s length, which is sqrt(tx*tx + ty*ty + tz*tz).

@Reedbeta

I’m not sure but isn’t scaling relative to the position of the object and not to the direction of the object is facing? anyway I also figured out how to use Cartesian coordinates to rotate in the same way spherical coordinates do. it’s pretty easy actually, I was close yet so far away. it is done like so:

```
xv =0:yv=0:zv=2
sx = Sin(player(pitch))
cx = Cos(player(pitch))
sy = Sin(player(yaw))
cy = Cos(player(yaw))
sz = Sin(player(roll))
cz = Cos(player(roll))
// rotation around x
xy = cx*yv - sx*zv
xz = sx*yv + cx*zv
// rotation around y
yz = cy*xz - sy*xv
yx = sy*xz + cy*xv
// rotation around z
zx = cz*yx - sz*xy
zy = sz*yx + cz*xy
tx = zx
ty = zy
tz = yz
shot(xv) = tx
shot(yv) = ty
shot(zv) = tz
```

Your absolutely right about not needing invP. Though i still get the jumping around of the shot after player moves farther then about 1,000,000 steps in any direction. Strange there are no tutorials for this or anything in the wiki as well.

@monjardin

Thank you monjardin. That helped out immensely. Doubles isn’t an option for me so I have figured out another way to overcome the floating point errors. instead of the player going to the systems, I bring the systems to the player. so the player is always at 0,0,0.

- Upcoming Multiplatform Game Program...
- Our first game - looking for feedbacks
- Network Emulation Tool
- Trouble with accessing GLSL array
- Fiction
- Game Programming Patterns: Bytecode
- Interactive WebGL Water Demo
- Skeletal Animation Tutorial with GP...
- Unreal Engine 4
- Microsoft xbox one selling poorly

I’m new here and I hope this is something that is easy to answer.

I have a sun and planets, the planets orbit the sun with gravity. the player can orbit both the sun or planets or depending on the trajectory a combination of many. but i will just use the sun, now the sun is set in some x,y,z place.

sun(x,y,z)

player(x,y,z)

the gravity from the sun to the player works on velocities that effect the x,y,z of the player and are calculated as xv,yv,zv

player(x-xv,y-yv,z-zv) and would update player(x,y,z) with the new coordinates

this part works.

i also have the player velocities: player(pxv,pyv,pzv)

and there are player angles: Player(pitch,yaw,roll)

and the player moves by combining them. This works as well.

Now my problem, I cannot figure out how to alter the xv,yv,zv and the player(pxv,pyv,pzv):Player(pitch,yaw,roll) into a harmonious act.

example experienced: say the player is gravitating to the sun,and the player moves to the sun as well, when then i stop the velocity increase of the player the gravitating velocity does not change with the player’s velocity increase.

and it’s not just to the gravitating body, its in any direction. Any help would be great. Thank you.