This chapter 
is taken from book "Programming Windows Phone 7" by Charles Petzold published by 
Microsoft press.
http://www.charlespetzold.com/phone/index.html
Game Components 
		
		To give your fingers a target to touch and drag, the programs display 
		translucent disks at the Texture2D corners. It would be nice to code these draggable 
		translucent disks so they're usable by multiple programs. In a 
		traditional graphics programming environment, we might think of 
		something like this as a control but in XNA it's called a game component.
		
		Components help modularize your XNA programs. Components can derive 
		from the
		GameComponent class but often they derive from
		DrawableGameComponent so they can display 
		something on the screen in addition to (and on top of) what goes out in 
		the Draw method of your Game class. 
		To add a new component class to your project, right-click the project 
		name, select Add and then New Item, and then pick Game Component from 
		the list. You'll need to change the base class to DrawableGameComponent and override the Draw method if you want the component to participate in 
		drawing. 
		A game generally instantiates the components that it needs either in 
		the game's constructor or during the Initialize method. The components officially become part of the game 
		when they are added to the Components collection defined by the Game class. 
		As with Game, 
		a 
		DrawableGameComponent derivative generally 
		overrides the 
		Initialize, LoadContent,
		Update, 
		and Draw methods. When the Initialize override of the Game derivative calls the Initialize method in the base class, the Initialize methods in all the components are called. Likewise, when 
		the LoadComponent,
		Update, 
		and Draw overrides in the Game derivative call the method in the base class, the LoadComponent,
		Update, 
		and Draw methods in all the components are called. 
		As you know, the Update override normally handles touch 
		input. In my experience that attempting to access touch input in a game 
		component is somewhat problematic. It seems as if the game itself and 
		the components end up competing for input. 
		To fix this, I decided that my Game derivative would be solely responsible for calling TouchPanel.GetState, 
		but the game would then give the components the opportunity to 
	
process this touch input. To accommodate this concept, I created this 
interface for GameComponent
and DrawableGameComponent derivatives: 
	
	using Microsoft.Xna.Framework.Input.Touch; 
	namespace Petzold.Phone.Xna
	{
	    public 
	interface IProcessTouch
	    {
	        bool ProcessTouch(TouchLocation 
	touch);
	    }
	}
When a game component implements this interface, the game calls the game 
component's ProcessTouch method for every TouchLocation object. If the game 
component needs to use that TouchLocation, it returns true from ProcessTouch, 
and the game then probably ignores that TouchLocation. 
The first component I'll show you is called Dragger, and it is part of the 
Petzold.Phone.Xna library. Dragger derives from DrawableGameComponent and 
implements the IProcessTouch interface: 
		
public class
Dragger : 
DrawableGameComponent, IProcessTouch
    {
        SpriteBatch spriteBatch;
        int? touchId; 
        public event
EventHandler PositionChanged; 
        public Dragger(Game 
game)
            : base(game)
        {
        }
        public 
Texture2D Texture { set;
get; }
        public 
Vector2 Origin { set;
get; }
        public 
Vector2 Position { set;
get; }
        ....
    }
A program making use of Dragger could define a custom Texture2D for the 
component and set it through this public Texture property, at which time it 
would probably also set the Origin property. However, Dragger defines a default 
Texture property for itself during its LoadContent method: 
protected 
override void  LoadContent()
        {
            spriteBatch = new
SpriteBatch(this.GraphicsDevice); 
            // Create default texture
            int radius = 48;
            Texture2D texture =
new Texture2D(this.GraphicsDevice, 
2 * radius, 2 * radius);
            uint[] pixels =
new uint[texture.Width 
* texture.Height]; 
            for (int 
y = 0; y < texture.Height; y++)
                for (int 
x = 0; x < texture.Width; x++)
                {
                    Color clr =
Color.Transparent; 
                    if ((x - radius) * (x - 
radius) +
                        (y - radius) * (y - radius) <
                        radius * radius)
                    {
                        clr = new
Color(0, 128, 128, 128);
                    }
                    pixels[y * texture.Width + x] = clr.PackedValue;
                }
            texture.SetData<uint>(pixels); 
            Texture = texture;
            Origin = new
Vector2(radius, radius); 
               base.LoadContent();
        }
The Dragger class implements the IProcessTouch interface so it has a 
ProcessTouch method that is called from the Game derivative for each 
TouchLocation object. The ProcessTouch method is interested in finger presses 
that occur over the component itself. If that is the case, it retains the ID and 
basically owns that finger until it lifts from the screen. For every movement of 
that finger, Dragger fires a PositionChanged event. 
public bool 
ProcessTouch(TouchLocation touch)
        {
            if (Texture ==
null)
                return 
false; 
            bool touchHandled =
false;                
            switch (touch.State)
            {
                case 
TouchLocationState.Pressed:
                    if ((touch.Position.X > 
Position.X - Origin.X) &&
                        (touch.Position.X < Position.X - Origin.X + 
Texture.Width) &&
                        (touch.Position.Y > Position.Y - Origin.Y) &&
                        (touch.Position.Y < Position.Y - Origin.Y + 
Texture.Height))
                    {
                        touchId = touch.Id;
                        touchHandled = true;
                    }
                    break; 
                case 
TouchLocationState.Moved:
                    if (touchId.HasValue && 
touchId.Value == touch.Id)
                    {
                        TouchLocation previousTouch;
                        touch.TryGetPreviousLocation(out 
previousTouch);
                        Position += touch.Position - previousTouch.Position; 
                        // Fire the event!
                        if (PositionChanged != null)
                            PositionChanged(this,
EventArgs.Empty); 
                        touchHandled = true;
                    }
                    break; 
                case 
TouchLocationState.Released:
                    if (touchId.HasValue && 
touchId.Value == touch.Id)
                    {
                        touchId = null;
                        touchHandled = true;
                    }
                    break;
            }
            return touchHandled;
        }
The Draw override just draws the Texture2D at the new position: 
public override
void Draw(GameTime 
gameTime)
        {
            if (Texture !=
null)
            {
                spriteBatch.Begin();
                spriteBatch.Draw(Texture, Position, 
null, Color.White,
                                 0, Origin, 1, 
SpriteEffects.None, 0);
                spriteBatch.End();
            }
            base.Draw(gameTime);
        }
Affine and Non-Affine Transforms
Sometimes it's convenient to derive a transform that maps a particular set 
of points to a particular destination. For example, here's a program that 
incorporates three instances of the Dragger component I just described, and lets 
you drag three corners of the Texture2D 
to arbitrary locations on the screen: 
![111.gif]()
This program uses an affine transform, which means that 
rectangles are always mapped to parallelograms. The fourth corner isn't 
draggable because it's always determined by the other three: 
![222.gif]()
You can't choose just any three points. Everything goes 
kaflooey if you attempt to make an interior angle greater than 180 degree.
A static class named 
MatrixHelper in the 
Petzold.Phone.Xna library has a method named 
ComputeAffineTransform 
that creates a Matrix
object based on these formulas: 
static
Matrix ComputeAffineTransform(Vector2 
ptUL, Vector2 ptUR,
Vector2 ptLL)
        {
            return new
Matrix()
            {
                M11 = (ptUR.X - ptUL.X),
                M12 = (ptUR.Y - ptUL.Y),
                M21 = (ptLL.X - ptUL.X),
                M22 = (ptLL.Y - ptUL.Y),
                M33 = 1,
                M41 = ptUL.X,
                M42 = ptUL.Y,
                M44 = 1
            };
        }
This method isn't public because it's not very useful by 
itself. It's not very useful because the formulas are based on transforming an 
image that is one-pixel wide and one-pixel tall. Notice, however, that the code 
sets M33 and M44 
to 1. This doesn't happen automatically and 
it is essential for the matrix to work right. 
To compute a 
Matrix for an affine transform that applies to an 
object of a particular size, this public method is much more useful: 
public
static Matrix 
ComputeMatrix(Vector2 size,
Vector2 ptUL, 
Vector2 ptUR, Vector2 ptLL)
        {
            // Scale transform
            Matrix S =
Matrix.CreateScale(1 / size.X, 1 / size.Y, 
1); 
            // Affine transform
            Matrix A = 
ComputeAffineTransform(ptUL, ptUR, ptLL); 
            // Product of two transforms
            return S * A;
        }
The first transform scales the object down to a 1*1 size 
before applying the computed affine transform. The AffineTransform project is 
responsible for the two screen shots shown above. It creates three instances of 
the Dragger 
component in its Initialize 
override, sets a handler for the 
PositionChanged event, 
and adds the component to the Components
collection: 
public
class Game1 : 
Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch; 
        Texture2D texture;
        Matrix matrix =
Matrix.Identity;
        Dragger draggerUL, draggerUR, 
draggerLL; 
        ...
        protected 
override void Initialize()
        {
            draggerUL = new Dragger(this);
            draggerUL.PositionChanged += OnDraggerPositionChanged;
            this.Components.Add(draggerUL); 
            draggerUR = new Dragger(this);
            draggerUR.PositionChanged += OnDraggerPositionChanged;
            this.Components.Add(draggerUR); 
            draggerLL = new Dragger(this);
            draggerLL.PositionChanged += OnDraggerPositionChanged;
            this.Components.Add(draggerLL); 
            base.Initialize();
        } 
        ...
    }
Don't forget to add the components to the Components collection of the Game
class! 
The 
LoadContent override is responsible for loading the image that will be 
transformed and initializing the Position properties of the three Dragger 
components at the three corners of the image: 
protected
override void 
LoadContent()
        {
            // Create a new SpriteBatch, which can be 
used to draw textures.
            spriteBatch = new
SpriteBatch(GraphicsDevice); 
            Viewport viewport =
this.GraphicsDevice.Viewport;
            texture = this.Content.Load<Texture2D>("PetzoldTattoo"); 
            draggerUL.Position = new
Vector2((viewport.Width - texture.Width) / 2,
                                             (viewport.Height - texture.Height) 
/ 2); 
            draggerUR.Position = draggerUL.Position + 
new Vector2(texture.Width, 0);
            draggerLL.Position = draggerUL.Position + 
new Vector2(0, texture.Height); 
            OnDraggerPositionChanged(null,
EventArgs.Empty);
        }
Dragger only fires its PositionChanged event when the component is actually 
dragged by the user, so the LoadContent method concludes by simulating a 
PositionChanged event, which calculates an initial Matrix based on the size of 
the Texture2D and the initial positions of the Dragger components: 
void 
OnDraggerPositionChanged(object sender,
EventArgs args)
        {
            matrix = MatrixHelper.ComputeMatrix(new
Vector2(texture.Width, texture.Height),
                                                draggerUL.Position,
                                                draggerUR.Position,
                                                draggerLL.Position);
        }
The program doesn't need to handle any touch input of its own, but Dragger 
implements the IProcessTouch interface, so the program funnels touch input to 
the Dragger components. These Dragger components respond by possibly moving 
themselves and setting new Position properties, which will cause PositionChanged 
events to be fired. 
protected
override void 
Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back 
== ButtonState.Pressed)
                this.Exit(); 
            TouchCollection touches =
TouchPanel.GetState(); 
            foreach (TouchLocation 
touch in touches)
            {
                bool touchHandled =
false; 
                foreach (GameComponent 
component in this.Components)
                {
                    if (component
is IProcessTouch 
&&
                        (component as
IProcessTouch).ProcessTouch(touch))
                    {
                        touchHandled = true;
                        break;
                    }
                } 
                if (touchHandled ==
true)
                    continue;
            } 
            base.Update(gameTime);
        }
It is possible for the program to dispense with setting handlers for the 
PositionChanged event of the Dragger components and instead poll the Position 
properties during each Update call and recalculate a Matrix from those values. 
However, recalculating a Matrix only when one of the Position 
properties actually changes is much more 
efficient. 
The Draw 
override uses that Matrix to display the texture: 
protected
override void 
Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue); 
            spriteBatch.Begin(SpriteSortMode.Immediate,
null, null,
null, null,
null, matrix);
            spriteBatch.Draw(texture, Vector2.Zero,
Color.White);
            spriteBatch.End() 
            base.Draw(gameTime);
        }
As you experiment with AffineTransform, you'll want to avoid making the 
interior angles at any corner greater than 180 degree. (In other words, keep it 
convex.) Affine transforms can express familiar operations like translation, 
scaling, rotation, and skew, but they never transform a square into anything 
more exotic than a parallelogram. 
Non-affine transforms are much more common in 3D than 
2D. In 3D, non-affine transforms are necessary to implement perspective effects. 
A long straight desert highway in a 3D world must seem to get narrower as it 
recedes into the distance, just like in the real world. Although we know that 
the sides of the road remains parallel, visually they seem to converge at 
infinity. This tapering effect is characteristic of non-affine transforms.
Although non-affine transforms are essential for 3D 
graphics programming, I wasn't even sure if 
SpriteBatch supported 
two-dimensional non-affine transforms until I tried them, and I was pleased to 
discover that XNA says "No problem!" What this means is that you can use 
non-affine transforms in 2D programming to simulate perspective effects. 
A non-affine transform in 2D can transform a square into 
a simple convex quadrilateral-a four-sided figure where the sides meet only at 
the corners, and interior angles at any corner are less than 180 degree. Here's one 
example: 
![333.gif]()
This one makes me look really smart: 
![444.gif]()
This program is called NonAffineTransform and it's just like AffineTransform 
except it has a fourth Dragger component and it calls a somewhat more 
sophisticated method in the MatrixHelper 
class in Petzold.Phone.Xna. You can move the little disks 
around with a fair amount of freedom; as long as you're not trying to form a 
concave quadrilateral, you'll get an image stretched to fit. 
The math of NonAffineTransform has been incorporated 
into a second static 
MatrixHelper.ComputeMatrix method in the Petzold.Phone.Xna library: 
public
static Matrix 
ComputeMatrix(Vector2 size,
Vector2 ptUL, 
Vector2 ptUR, 
                                                        
Vector2 ptLL, Vector2 ptLR)
        {
            // Scale transform
            Matrix S =
Matrix.CreateScale(1 / size.X, 1 / size.Y, 
1); 
            // Affine transform
            Matrix A = 
ComputeAffineTransform(ptUL, ptUR, ptLL);
 
            // Non-Affine transform
            Matrix B =
new Matrix();
            float den = A.M11 * A.M22 - A.M12 * 
A.M21;
            float a = (A.M22 * ptLR.X - A.M21 * 
ptLR.Y + 
                       A.M21 * A.M42 - A.M22 * A.M41) / den; 
            float b = (A.M11 * ptLR.Y - A.M12 * 
ptLR.X + 
                       A.M12 * A.M41 - A.M11 * A.M42) / den; 
            B.M11 = a / (a + b - 1);
            B.M22 = b / (a + b - 1);
            B.M33 = 1;
            B.M14 = B.M11 - 1;
            B.M24 = B.M22 - 1;
            B.M44 = 1; 
            // Product of three transforms
            return S * B * A;
        }
I won't show you the NonAffineTransform program here because it's pretty much 
the same as the AffineTransform program but with a fourth Dragger component 
whose Position property is passed to the second ComputeMatrix 
method. 
The big difference with the new program is that 
non-affine transforms are much more fun!