Helper Method : CreatePathFromVertices

Topics: Developer Forum, User Forum
Dec 29, 2007 at 4:06 PM
Edited Dec 29, 2007 at 4:07 PM
I wrote this helper method for anyone having trouble getting their Polygon Geometry correct like I was. This method will create a Silverlight Path object that you can add to your Canvas to see the outline of your Vertices. Couldn't find anything to do the same from within the engine but that makes sense because the engine is unaware of the rendering engine being used (XNA, Silverlight). Hope this helps someone, it has helped me, I just can't visualize all those points in my head. :)

public static Path CreatePathFromVertices(Vertices vertices, double width, double height)
{
Path path = new Path();
path.Stroke = new SolidColorBrush(Colors.Magenta);
path.StrokeThickness = 1;
path.Fill = new SolidColorBrush(Colors.Transparent);
PathGeometry pathGeom = new PathGeometry();
PathFigureCollection figures = new PathFigureCollection();
pathGeom.Figures = figures;
PathFigure figure = new PathFigure();
figure.StartPoint = new Point((double)vertices0.X, (double)vertices0.Y);
figure.Segments = new PathSegmentCollection();
pathGeom.Figures.Add(figure);

foreach (var vector in vertices)
{
LineSegment line = new LineSegment() { Point = new Point((double)vector.X, (double)vector.Y) };
figure.Segments.Add(line);
}

TranslateTransform trans = new TranslateTransform();
trans.X = width / 2;
trans.Y = height / 2;
path.RenderTransform = trans;

path.Data = pathGeom;
return path;
}

I put this method in a Utils class and call it from within my UserControl cs file constructor. This sample puts a border around an island in my Pirate game. I used photoshop to create the island image and created a transparent layer and placed magenta dots all around the island. I then wrote a C# winforms app to read the pixel data and create the Vertices code below. I had to reorder the individual vector additions manually but I just referenced the photoshop x,y values to do so, hence the commented values next to each Add line.

public SpringIsland(PhysicsSimulator physicsSimulator)
: base (physicsSimulator)
{
System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("Pirates.SpringIsland.xaml");
this.Initialize(new System.IO.StreamReader(s).ReadToEnd());

this.Body = BodyFactory.Instance.CreateRectangleBody(this.PhysicsSimulator, (float)this.Root.Width, (float)this.Root.Height, 1000);
this.Body.IsStatic = true;

#region Vertices
Vertices vertices = new Vertices();
vertices.Add(new Vector2(-208f, -173f)); // 48, 83
vertices.Add(new Vector2(-126f, -240f)); // 130, 16
vertices.Add(new Vector2(-61f, -200f)); // 195, 56
vertices.Add(new Vector2(9f, -201f)); // 265, 55
vertices.Add(new Vector2(43f, -241f)); // 299, 15
vertices.Add(new Vector2(152f, -256f)); // 408, 0
vertices.Add(new Vector2(235f, -209f)); // 491, 47
vertices.Add(new Vector2(218f, -155f)); // 474, 101
vertices.Add(new Vector2(118f, -145f)); // 374, 111
vertices.Add(new Vector2(23f, -50f)); // 279, 206
vertices.Add(new Vector2(114f, 55f)); // 370, 311
vertices.Add(new Vector2(90f, 92f)); // 346, 348
vertices.Add(new Vector2(152f, 97f)); // 408, 353
vertices.Add(new Vector2(235f, 148f)); // 491, 404
vertices.Add(new Vector2(216f, 219f)); // 472, 475
vertices.Add(new Vector2(147f, 252f)); // 403, 508
vertices.Add(new Vector2(26f, 241f)); // 282, 497
vertices.Add(new Vector2(-62f, 234f)); // 194, 490
vertices.Add(new Vector2(-118f, 203f)); // 138, 459
vertices.Add(new Vector2(-126f, 167f)); // 130, 423
vertices.Add(new Vector2(-156f, 143f)); // 100, 399
vertices.Add(new Vector2(-218f, 129f)); // 38, 385
vertices.Add(new Vector2(-233f, 103f)); // 23, 359
vertices.Add(new Vector2(-232f, 35f)); // 24, 291
vertices.Add(new Vector2(-200f, 16f)); // 56, 272
vertices.Add(new Vector2(-195f, -32f)); // 61, 224
vertices.Add(new Vector2(-230f, -95f)); // 26, 161
vertices.Add(new Vector2(-199f, -141f)); // 57, 115
vertices.Add(new Vector2(-208f, -173f)); // 48, 83
#endregion

this.Root.Children.Add(Utils.CreatePathFromVertices(vertices, this.Root.Width, this.Root.Height));

Geom g = GeomFactory.Instance.CreatePolygonGeom(this.PhysicsSimulator, this.Body, vertices, 1);
g.CollisionHandler += new FarseerGames.FarseerPhysics.Collisions.Geom.CollisionHandlerDelegate(this.HandleCollision);
}
Feb 2, 2009 at 4:58 PM
Thanks for sharing! seems very useful since the debug capabilities of FarSeer only work in XNA.
Feb 3, 2009 at 1:36 PM
You may also want to check out http://www.codeplex.com/PhysicsHelper for some very useful tools related to Silverlight and Farseer.