Calculating an angle from a Vector2

February 28, 2009 .net, vectors, xna

When you need to calculate an angle from a Vector2 structure, you can use this piece of code:

public static class Vector2Helper { public static float CalculateAngle(Vector2 v) { float angle = 0.0f; if(v != Vector2.Zero) { v.Normalize(); angle = (float)Math.Acos(v.Y); if(v.X < 0.0f) angle = -angle; } return angle; } }

I used this to calculate an angle from the Vector2 of the Left Stick.

The original credit for this source code comes from here.

The Game Show Host Problem, aka The Monty Hall Problem

February 12, 2009

NOTE: This is a repost from my old blog.

So, me and my girlfriend went to see 21 last night and in the movie they make mention of The Game Show Host problem, aka The Monty Hall Problem.

The jist of the problem is this: You are on a game show. The host presents you with 3 doors, 1 of which has a car behind it, the other 2 have goats. The game show host tells you to pick a door. You do so, at which point the game show host opens up a door to show you a goat behind the door and then asks you if you would like to switch your choice to the other closed door. The question is then, should you switch your choice?

The correct answer is yes. More on why after the jump.

I won’t go too far into detail about why you should switch your answer, I’ll leave that to Wikipedia. Some things to note that may not be obvious: 1) The game show host will always open a door that is not the correct door 2) He will never open your door. These are the keys to this problem. By switching, you will win a prize 2/3 of the time as opposed to only winning 1/3 of the time if you do not.

Many people will argue that once the game show host opens the door with the goat behind it that there is now a 50% chance of you picking the right door by either staying with your door or switching. This is simply not true. Each door still only has 33.3% chance of being the door with the car behind it. The thing is though, once you pick your door, the game show host then eliminates a door based on 2 criteria: 1) The door is not the one with the prize behind it 2) The door is not yours. Due to these criteria, the odds of the correct door do not change for the door that you have picked, but rather change for the doors that you have not picked. The 2 doors not chosen by you then in a sense combine into one option and they together have a probability of 66.7%.

The Wikipedia article explains in much more mathematical detail why it is better to switch. I suggest you look there if I have done nothing but confuse you. This is simple strategy and probability. Knowing exactly how the game works can make you alot better at it.

Drawing 2D Lines as Rotated Quads

February 07, 2009 .NET

I haven't had much time lately with work but one question I've seen asked many many times is how to draw lines of different widths. So, to cut to the chase I'll share the code I've used to do it.

public void DrawLine(Vector3 p1, Color c1, Vector3 p2, Color c2, int width) { float distance = Vector3.Distance(p1, p2); float halfDistance = distance / 2.0f; float halfWidth = width / 2.0f; Vector3 difference = p2 - p1; Vector3 destination = new Vector3(p1.X + difference.X / 2.0f, p1.Y + difference.Y / 2.0f, p1.Z + difference.Z); // Calculate angle between two points float angle = (float)Math.Atan2(difference.Y, difference.X); Vector3 v1, v2, v3, v4; v1 = new Vector3(-halfDistance, -halfWidth, 0); // Top Left v2 = new Vector3(halfDistance, -halfWidth, 0); // Top Right v3 = new Vector3(halfDistance, halfWidth, 0); // Bottom Right v4 = new Vector3(-halfDistance, halfWidth, 0); // Bottom Left Matrix m = Matrix.Identity * Matrix.CreateRotationZ(angle) * Matrix.CreateTranslation(destination); v1 = Vector3.Transform(v1, m); v2 = Vector3.Transform(v2, m); v3 = Vector3.Transform(v3, m); v4 = Vector3.Transform(v4, m); DrawQuad(v1, c1, v2, c2, v3, c2, v4, c1); }

I've left a lot of fluff code out. I usually check if the line is a width of 1 and draw a normal line. I also left out the code on how to draw a quad as that can be found many other places already.

SpriteSheet Class

January 09, 2009 .NET, SpriteSheet, XNA

I've been talking with a guy on the creator forums lately about SpriteSheets and so I decided it might be a good idea to post my SpriteSheet class.

It's very simple. Only reads sprites from left to right and assumes all Sprites are the same width and height.

#region Usingusing System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace Snow.Xna.Graphics { /// Spritesheet class. /// public class SpriteSheet { #region Fields string name; Texture2D texture; Rectangle[] rectangles; int spriteWidth, spriteHeight; #endregion #region Properties /// The name of this SpriteSheet. /// public string Name { get { return name; } } /// The texture for this SpriteSheet. /// public Texture2D Texture { get { return texture; } } /// Returns a rectangle for a sprite in the SpriteSheet. /// /// index /// public Rectangle this[int i] { get { return rectangles[i]; } } /// The number of sprites in this SpriteSheet. /// public int Count { get { return rectangles.Length; } } /// The width of the texture. /// public int Width { get { return texture.Width; } } /// The width of each sprite in the SpriteSheet. /// public int SpriteWidth { get { return spriteWidth; } } /// The height of the texture. /// public int Height { get { return texture.Height; } } /// The height of each sprite in the SpriteSheet. /// public int SpriteHeight { get { return spriteHeight; } } #endregion /// Create a new SpriteSheet and determine the number of sprites in the sheet. /// /// /// Width of each sprite. /// Height of each sprite. public SpriteSheet(string name, Texture2D texture, int spriteWidth, int spriteHeight) : this(name, texture, spriteWidth, spriteHeight, 0) { } /// Create a new SpriteSheet. /// /// /// Width of each sprite. /// Height of each sprite. /// The number of sprites in the sheet. public SpriteSheet(string name, Texture2D texture, int spriteWidth, int spriteHeight, int count) { this.name = name; this.texture = texture; this.spriteWidth = spriteWidth; this.spriteHeight = spriteHeight; if(count == 0) { int numX = texture.Width / spriteWidth; int numY = texture.Height / spriteHeight; rectangles = new Rectangle[numX * numY]; } else { rectangles = new Rectangle[count]; } int x = 0, y = 0; for(int i = 0; i < rectangles.Length; i++) { rectangles[i] = new Rectangle(x, y, spriteWidth, spriteHeight); x += spriteWidth; if(x >= texture.Width) { x = 0; y += spriteHeight; } } } public static implicit operator Texture2D(SpriteSheet spriteSheet) { return spriteSheet.Texture; } } }

You can create a new SpriteSheet and use it like this:

`

SpriteSheet spriteSheet = new SpriteSheet("tiles", Content.Load<texture2D>("tiles"), 64, 64); spriteBatch.Begin(); spriteBatch.Draw(spriteSheet, new Rectangle(0, 0, spriteSheet.SpriteWidth, spriteSheet.SpriteHeight), spriteSheet[0], Color.White); spriteBatch.End();

`

Which loads a spritesheet with sprites of size 64x64. It then draws the first Sprite in the SpriteSheet. You of course wouldn't want to load the spritesheet every frame as well.

Feel free to use this code without restriction.

Edit: I copied and pasted the second piece of code from somewhere else so I fixed two typos.

Colors and Hex

December 21, 2008 .NET, XNA

I recently needed to write out Color(s) as an xml attribute. I wrote 2 methods to read and write the Color(s) as Hex strings. Here ya go:

Read More