Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1003143
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T07:56:04+00:00 2026-05-16T07:56:04+00:00

Edit: Just wanted to make the question I have more clear. I pretty much

  • 0

Edit: Just wanted to make the question I have more clear. I pretty much am having trouble seeing how something like Matrix.CreateTransformationZ works in the context of not only matrix multiplication but more importantly what this does to the screen space/world space so I can get a clearer picture. So maybe someone could alter the code or give me a short snippet to test out where I can use this to either rotate around an axis and/or orbit around the axis. I have also changed the example.

So I’m still kind of having trouble visualizing how matrices work with the xna screen space.

I’ll give you an example:

public class Game1 : Microsoft.Xna.Framework.Game
{
    Texture2D shipTexture, rockTexture;


    Vector2 shipPosition = new Vector2(100.0f, 100.0f);
    Vector2 rockPosition = new Vector2(100.0f, 29.0f);

    int count;

    float shipRotation, rockRotation;
    float rockSpeed, rockRotationSpeed;
    bool move = true;

    const int rock = 0;
    const int ship = 1;

    Color[] rockColor;
    Color[] shipColor;

    float testRot = 0.0f;
    Vector2 shipCenter; int shipWidth, shipHeight;
    Vector2 rockCenter; int rockWidth, rockHeight;

    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

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

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        rockSpeed = 0.16f;
        rockRotationSpeed = 0.3f;
        base.Initialize();
    }



    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        shipTexture = Content.Load<Texture2D>("Images\\ship");
        rockTexture = Content.Load<Texture2D>("Images\\asteroid");

        rockWidth = rockTexture.Width; rockHeight = rockTexture.Height;
        shipWidth = shipTexture.Width; shipHeight = shipTexture.Height;

        rockCenter = new Vector2(rockWidth / 2, rockHeight / 2);
        shipCenter = new Vector2(shipWidth / 2, shipHeight / 2);



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

        // TODO: use this.Content to load your game content here
        rockColor = new Color[rockTexture.Width * rockTexture.Height];
        rockTexture.GetData(rockColor);
        shipColor = new Color[shipTexture.Width * shipTexture.Height];
        shipTexture.GetData(shipColor);
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

            /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

        spriteBatch.Draw(rockTexture, rockPosition,
            null, Color.White, testRot, rockCenter, 1.0f,
            SpriteEffects.None, 0.0f);

        spriteBatch.Draw(shipTexture, shipPosition,
            null, Color.White, shipRotation, shipCenter,
            1.0f, SpriteEffects.None, 0.0f);

        spriteBatch.End();
        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }
    #endregion

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        testRot += 0.034906585f;
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        UpdateAsteroid(gameTime);
        RotateShip(gameTime);
        MoveShip(gameTime);
        // TODO: Add your update logic here
        CheckCollisions();
        base.Update(gameTime);
    }

    #region Collisions

    public Color PixelColor(int objectNum, int pixelNum)
    {
        switch (objectNum)
        {
            case rock:
                return rockColor[pixelNum];
            case ship:
                return shipColor[pixelNum];
        }

        return Color.White;
    }

    public bool PixelCollision(Matrix transformA, int pixelWidthA, int pixelHeightA, int A,
        Matrix transformB, int pixelWidthB, int pixelHeightB, int B)
    {
        Matrix temp = Matrix.Invert(transformB);
        Matrix AtoB = transformA * Matrix.Invert(transformB);

        Vector2 columnStep, rowStep, rowStartPosition;

        columnStep = Vector2.TransformNormal(Vector2.UnitX, AtoB);
        rowStep = Vector2.TransformNormal(Vector2.UnitY, AtoB);

        rowStartPosition = Vector2.Transform(Vector2.Zero, AtoB);

        for (int rowA = 0; rowA < pixelHeightA; rowA++)
        {
            // begin at the left
            Vector2 pixelPositionA = rowStartPosition;

            // for each column in the row (move left to right)
            for (int colA = 0; colA < pixelWidthA; colA++)
            {
                // get the pixel position
                int X = (int)Math.Round(pixelPositionA.X);
                int Y = (int)Math.Round(pixelPositionA.Y);

                // if the pixel is within the bounds of B
                if (X >= 0 && X < pixelWidthB && Y >= 0 && Y < pixelHeightB)
                {

                    // get colors of overlapping pixels
                    Color colorA = PixelColor(A, colA + rowA * pixelWidthA);
                    Color colorB = PixelColor(B, X + Y * pixelWidthB);

                    // if both pixels are not completely transparent,
                    if (colorA.A != 0 && colorB.A != 0)
                        return true; // collision
                }
                // move to the next pixel in the row of A
                pixelPositionA += columnStep;
            }

            // move to the next row of A
            rowStartPosition += rowStep;
        }

        return false; // no collision
    }
    public Matrix Transform(Vector2 center, float rotation, Vector2 position)
    {

        return Matrix.CreateTranslation(new Vector3(-center, 0.0f)) *
            Matrix.CreateRotationZ(rotation) *
            Matrix.CreateTranslation(new Vector3(position, 0.0f));
    }

    public static Rectangle TransformRectangle(Matrix transform, int width, int height)
    {
        Vector2 leftTop = new Vector2(0.0f, 0.0f);
        Vector2 rightTop = new Vector2(width, 0.0f);
        Vector2 leftBottom = new Vector2(0.0f, height);
        Vector2 rightBottom = new Vector2(width, height);

        Vector2.Transform(ref leftTop, ref transform, out leftTop);
        Vector2.Transform(ref rightTop, ref transform, out rightTop);
        Vector2.Transform(ref leftBottom, ref transform, out leftBottom);
        Vector2.Transform(ref rightBottom, ref transform, out rightBottom);

        Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop), Vector2.Min(leftBottom, rightBottom));
        Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop), Vector2.Max(leftBottom, rightBottom));

        return new Rectangle((int)min.X, (int)min.Y,
            (int)(max.X - min.X), (int)(max.Y - min.Y));
    }

    private void CheckCollisions()
    {
        Matrix shipTransform, rockTransform;

        Rectangle shipRectangle, rockRectangle;

        rockTransform = Transform(rockCenter, rockRotation, rockPosition);
        rockRectangle = TransformRectangle(rockTransform, rockWidth, rockHeight);
        shipTransform = Transform(shipCenter, shipRotation, shipPosition);
        shipRectangle = TransformRectangle(shipTransform, shipWidth, shipHeight);

        if (rockRectangle.Intersects(shipRectangle)) // rough collision check
            if (PixelCollision( // exact collision check
            rockTransform, rockWidth, rockHeight, rock,
            shipTransform, shipWidth, shipHeight, ship))
                move = false;
    }
    #endregion

    #region Moves_and_Rotations

    private void UpdateAsteroid(GameTime gameTime)
    {
        float timeLapse = (float)gameTime.ElapsedGameTime.Milliseconds;

        if (move == true)
        {
            if ((rockWidth + rockPosition.X >= Window.ClientBounds.Width))
            {
                rockSpeed *= -1.0f;
                rockPosition.X += rockSpeed * timeLapse;
            }
            else if ((rockPosition.X <= 0))
            {
                rockSpeed *= -1.0f;
                rockPosition.X += rockSpeed * timeLapse;

            }
            else
                rockPosition.X += rockSpeed * timeLapse;

            const float SCALE = 50.0f;
            rockRotation += rockRotationSpeed * timeLapse / SCALE;

            rockRotation = rockRotation % (MathHelper.Pi * 2.0f);
        }
    }

    private float RotateShip(GameTime gameTime)
    {
        float rotation = 0.0f;
        float speed = gameTime.ElapsedGameTime.Milliseconds / 300.0f;

        if (!move)
            return rotation;

        KeyboardState keyboard = Keyboard.GetState();

        if (keyboard.IsKeyDown(Keys.Right))
            rotation = speed;
        else if (keyboard.IsKeyDown(Keys.Left))
            rotation = -speed;

        shipRotation += rotation;

        shipRotation = shipRotation % (MathHelper.Pi * 2.0f);
        return shipRotation;
    }

    private void MoveShip(GameTime gameTime)
    {
        const float SCALE = 20.0f;
        float speed = gameTime.ElapsedGameTime.Milliseconds / 100.0f;

        KeyboardState keyboard = Keyboard.GetState();

        if (keyboard.IsKeyDown(Keys.Up))
        {

            shipPosition.X += (float)Math.Sin(shipRotation) * speed * SCALE;
            shipPosition.Y -= (float)Math.Cos(shipRotation) * speed * SCALE;
        }
        else if (keyboard.IsKeyDown(Keys.Down))
        {
            shipPosition.X -= (float)Math.Sin(shipRotation) * speed * SCALE;
            shipPosition.Y += (float)Math.Cos(shipRotation) * speed * SCALE;
        }
    }
#endregion
}

I took this from XNA Game Creators, it’s simply a method of doing Pixel Detection.

  1. In the Transform method above, matrix multiplication occurs against I guess a rectangle. What exactly is happening in terms of the screen space/world space?

  2. Why is author multiplying the matrix by the inverse of another matrix? (He mentions that somehow this makes it relative to the other asset)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T07:56:05+00:00Added an answer on May 16, 2026 at 7:56 am

    Screen space is presumably the same thing as Client Space. Client space goes from (0,0) in the top left corner to (width, height) in the bottom right. “Up” is Y-.

    Projection space goes from (-1,-1) in the bottom-left corner to (1,1) in the top-right. This is what the GPU uses for its final rendering. SpriteBatch handles this for you (by contrast: BasicEffect requires you to provide a projection matrix).

    World space is whatever you want it to be. This is the coordinate system that your gameplay takes place in. In your example it seems that this is the same as Client space.

    Traditionally, when doing this sort of thing, you have an object defined in its own space. In your example the rock and ship rectangles are hard coded into the function TransformRectangle as the initial values of the variables topLeft through bottomRight.

    You then have a World matrix for each object. This moves that object from its own space into its position in World space. In your example this is shipTransform and rockTransform. A World transform is also done inside SpriteBatch.Draw, based on the arguments you pass in (using the texture itself as the initial object).

    Then you have a View matrix – which you can think of as your camera. You example doesn’t have one of these. But if you wanted, for example, to pan the view around to follow the player, you would use a translation matrix here, created from the player’s position (and pass it to SpriteBatch.Begin).

    And finally you have a Projection matrix that converts your World space into Projection space so that the GPU can render your scene.

    Now a possible problem here is that SpriteBatch internally defines a projection matrix that converts a Client space to Projection space (so it basically “assumes” World space is Client space). Not a problem in your example because the two spaces are the same.

    If your World space is not the same thing as Client space, and you want to use SpriteBatch, you must create an additional matrix to convert from World space to Client space and insert it between the View and Project matrices (ie: multiply it with View and pass it into SpriteBatch.Begin).

    If your World space defines which way is “up” (or “right”, for that matter) differently to SpriteBatch, then you must keep in mind that the original object used by SpriteBatch.Draw defines “up” to be Y-.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have to edit my question just to make it clear. What I need
EDIT: Just to make things clear, this problem was caused by a typo in
Edit2: I just want to make sure my question is clear: Why, on each
Edit: just to be clearer on what I am looking to do. I have
Edit For simplicity: I just want to make the most basic possible cursor that
I have just successfully installed CakePHP and I see that I can edit the
EDIT: This question was misexpressed. What I've really wanted to ask was: Is there
I wonder if I can just check something that I have not tried before,
I just wanted to run this by other heads to make sure I wasn't
EDIT I've just started skimming Codd's famous 1970 paper that started it all, that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.