Need help getting a child object to orbit a parent object ...

Recommended Posts

RoyP    202

I'm trying to figure out how to make a child object orbit around a parent object.  In my situation, I'm trying to create a parent ship that rotates waypoints with it when it rotates.  A smaller child ship will park itself in a waypoint to maintain it's position within the fleet.

Here are a couple of images showing what I'm going for:

The child ship must keep it's position relative to the parent ship so it maintains it's position within the fleet.

i've tried learning enough about matrices to do it, but I'm screwing something up.  I've got my child ship orbiting the origin point of the screen instead of the parent ship.

Here's the code I'm using when I press a key:

parentShipRotationRadians += MathHelper.ToRadians(15);

childShipPositionPoint = Vector2.Transform(childShipPositionPoint, childShipRotationMatrix);

How do I rotate the child ship's center point around the parent ship's center point with matrices?

Please break it down for me and help me understand what you're doing.  I've tried researching it and I just can't find the info.

Roy

Share on other sites

This looks like a conceptual glitch.

The worldview for your parentship should not be the same as for your child ship, for what you're trying to achieve.

Remember that your childship has a worldview dependency on the way parentship gets projected.

In short, the worldview matrix of childship keeps changing according to parentship view matrix.

Share on other sites
RoyP    202

I'm not doing anything with a matrix for the parent ship.  I'm just assigning it's rotation a value in the Update method and using that value to change the angle the texture is rendered at in the Draw method.  The parent ship's texture is just rotating at the center point of the screen.

Roy

Share on other sites

[quote name='RoyP' timestamp='1357140875' post='5016709']
I'm not doing anything with a matrix for the parent ship.
[/quote]

That's why I am saying that you need to do something about it, to achieve what you're looking for. In mathematical terms, what you need to implement is something like Lorentz Transformation.

Share on other sites
RoyP    202

So how would I go about doing that?  This is my first adventure with matrices, so I need some help understanding what I'm supposed to do and why.

Roy

Share on other sites

Well, your parent ship's view matrix should become the world matrix of the child ship, where origin for child ship's world view will be the centre of parent ship.

Share on other sites
RoyP    202

Ok, I understand what you're saying conceptually.  How do I actually implement that in XNA?  Can you break it down step-by-step for me?  It would really help me learn it since this is my first time doing anything like this.

Roy

Share on other sites

Ok, please share the code you have so far.

Share on other sites
RoyP    202

Here's the class code from my Game1.cs file.  The only thing I left out was the using statements and the namespace.

public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

float inputDelay;
float maxInputDelay = 0.2f;

Texture2D shipTexture;
Vector2 shipTextureOriginPoint;

Texture2D dotTexture;
Vector2 dotTextureOriginPoint;

Vector2 dotPositionPoint;

Vector2 parentShipPositionPoint;

Vector2 childShipPositionPoint;
Matrix childShipMatrix;
Matrix childShipRotationMatrix;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
IsMouseVisible = true;

base.Initialize();
}

{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

shipTextureOriginPoint = new Vector2(shipTexture.Width / 2, shipTexture.Height / 2);
dotTextureOriginPoint = new Vector2(dotTexture.Width / 2, dotTexture.Height / 2);

dotPositionPoint = new Vector2(GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2);

parentShipPositionPoint = new Vector2(GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2);

childShipPositionPoint = new Vector2(parentShipPositionPoint.X - 47,
parentShipPositionPoint.Y - 47);

childShipMatrix = new Matrix();
childShipMatrix.Translation = new Vector3(childShipPositionPoint.X,
childShipPositionPoint.Y,
0);

childShipRotationMatrix = new Matrix();
}

{
// TODO: Unload any non ContentManager content here
}

protected override void Update(GameTime gameTime)
{
// Allows the game to exit
this.Exit();

if (inputDelay > 0)
inputDelay -= (float)gameTime.ElapsedGameTime.TotalSeconds;

if (inputDelay < 0)
inputDelay = 0;

if (inputDelay == 0)
{
if (Keyboard.GetState().IsKeyDown(Keys.Right))
{

childShipPositionPoint = Vector2.Transform(childShipPositionPoint,
childShipRotationMatrix);

inputDelay = maxInputDelay;
}
}

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);

spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

spriteBatch.Draw(dotTexture,
dotPositionPoint,
null,
Color.Yellow,
0,
dotTextureOriginPoint,
0.6f,
SpriteEffects.None,
0.001f);

spriteBatch.Draw(shipTexture,
parentShipPositionPoint,
null,
Color.BlueViolet,
shipTextureOriginPoint,
2.0f,
SpriteEffects.None,
0.301f);

spriteBatch.Draw(shipTexture,
childShipPositionPoint,
null,
Color.Orange,
shipTextureOriginPoint,
1.0f,
SpriteEffects.None,
0.300f);

spriteBatch.End();

base.Draw(gameTime);
}
}

I basically want to rotate the parent ship by 15 degrees when I press the right key and have the child ship stay in the correct formation to it.  I also want to rotate the parent ship by -15 degrees when I press the left key and have the child ship stay in the correct formation to it.

This is just a really simple sandbox I'm using to learn how to implement this.

Roy

Share on other sites

Try changing shipTextureOriginPoint to dotTextureOriginPoint in below code and let me know what you see is as per your requirement or no. Snapshot would be nice.

spriteBatch.Draw(shipTexture,
childShipPositionPoint,
null,
Color.Orange,
shipTextureOriginPoint, // Change this one
1.0f,
SpriteEffects.None,
0.300f);

Share on other sites

Or, I think your can comment out this line of code and try once :

Share on other sites
RoyP    202

That's not going to do anything.  Those are just the center points on the actual textures themselves so I can rotate the texture around the texture's center point instead of the top left corner.  They have nothing to do with world space.  The coordinates that deal with the ship positions in world space are childShipPositionPoint and parentShipPositionPoint.

Roy

Share on other sites
RoyP    202

[quote]Or, I think your can comment out this line of code and try once :

That just rotates the texture itself, so commenting it out just keeps the child ship pointing straight up.  It doesn't affect it's position in world space, so the child ship is still rotating around the 0,0 world origin.

Roy

Share on other sites

Sorry bud, can't help out much unless I can figure out the exact outcome you desire.

You're telling me that this code will do this and that code will do that, where I am expecting that this is what you're looking for.

Well, I tried my best and gave you the exact concepts to solve the problem.

ow you might have to do some digging on your own and build up on the solution yourself.

Goodluck!

Share on other sites
RoyP    202

Let me try explaining exactly what I'm trying to do.  I might not be making it as clear as I thought.

Here's an image showing what I'm trying to do:

The purple ship is the parent ship.  The orange ship is the child ship.

1 - I'm starting with a parent ship at (640, 320) in world space (center of the view port).  I set the child ship's position with an offset of (-47, -47) from the parent ship's position.  Both ships start with a rotation of 0 degrees (I convert all the degrees to radians with the MathHelper.ToRadians method).  The only thing I do with the rotation amount is to use it for the SpriteBatch.Draw call in the game's Draw method and use it to pass the rotation value to the Matrix.CreateRotationZ method.

2 - When I hit the right arrow, I want to rotate the parent ship 15 degrees clockwise and compute the new center point for the child ship in relation to the parent ship.  The goal is to have the child ship rotate with the parent ship while maintaining it's position within the fleet.  (My eventual goal is to turn the concept into a waypoint system so I can park different child ships at the waypoints.)

3 to 7 -  I need to repeat step 2 over and over again, so that the child ship keeps orbiting the parent ship while maintaining it's fleet formation.  I want it to orbit in a complete circle.

When I press the left arrow key, I want to do the same thing, but in the counter clockwise direction.

Does that make it any clearer?

I know that I need to use matrix transformations to do it, but I need help understanding how to actually do the matrix transformations.  I've never done it before and I need someone to walk me through it step-by-step so that I can learn what I'm doing.

I have a basic understanding of matrix and vector math, but I'm having trouble applying the abstract concepts to a concrete implementation in XNA.

Roy

Edited by RoyP

Share on other sites

What you have to do is transform the difference vector between parent and child, not the child position itself.

Rotations matrices always rotate about the origin, so the easiest thing is to (temporarily) change your coordinate system so the parent ship's position is the origin:

Vector2 d = childShipPositionPoint - parentShipPositionPoint;
d = Vector2.Transform(d, Matrix.CreateRotationZ(15));
childShipPositionPoint = parentShipPositionPoint + d;

Let me know if this is what you are looking for.

Share on other sites

It might be just me, but even now, the snapshot that you have provided and your problem statement seem to be complementing each other.

In simple words, I think you're trying to achieve what you already have in this snapshot.

Perhaps, an altered snapshot with expected behaviour might help.

Share on other sites
It might be just me, but even now, the snapshot that you have provided and your problem statement seem to be complementing each other.

In simple words, I think you're trying to achieve what you already have in this snapshot.

Perhaps, an altered snapshot with expected behaviour might help.

The snapshot shows the expected behaviour. He wrote that the parent ship rotates about the origin instead.

Share on other sites
RoyP    202

@FromShadow ... you are a genius. :-)  It does exactly what I needed.  Thanks for explaining it to me and providing the code to do it.

@NewDisplayName ... thanks for trying to help.  I appreciate it.

Roy