/// <summary>
        /// Decompose the polygon into several smaller non-concave polygons.
        /// </summary>
        /// <param name="vertices">The polygon to decompose.</param>
        /// <param name="sheer">The sheer to use if you get bad results, try using a higher value.</param>
        /// <returns>A list of triangles</returns>
        public static List<Vertices> ConvexPartition(Vertices vertices, float sheer = 0.001f)
        {
            Debug.Assert(vertices.Count > 3);

            List<Point> compatList = new List<Point>(vertices.Count);

            foreach (Vector2 vertex in vertices)
            {
                compatList.Add(new Point(vertex.X, vertex.Y));
            }

            Triangulator t = new Triangulator(compatList, sheer);

            List<Vertices> list = new List<Vertices>();

            foreach (List<Point> triangle in t.Triangles)
            {
                Vertices outTriangles = new Vertices(triangle.Count);

                foreach (Point outTriangle in triangle)
                {
                    outTriangles.Add(new Vector2(outTriangle.X, outTriangle.Y));
                }

                list.Add(outTriangles);
            }

            return list;
        }
Example #2
1
        public override void Initialize()
        {
            Vector2 trans = new Vector2();
            _polygons = new List<Vertices>();

            _polygons.Add(PolygonTools.CreateGear(5f, 10, 0f, 6f));
            _polygons.Add(PolygonTools.CreateGear(4f, 15, 100f, 3f));

            trans.X = 0f;
            trans.Y = 8f;
            _polygons[0].Translate(ref trans);
            _polygons[1].Translate(ref trans);

            _polygons.Add(PolygonTools.CreateGear(5f, 10, 50f, 5f));

            trans.X = 22f;
            trans.Y = 17f;
            _polygons[2].Translate(ref trans);

            AddRectangle(5, 10);
            AddCircle(5, 32);

            trans.X = -20f;
            trans.Y = 8f;
            _polygons[3].Translate(ref trans);
            trans.Y = 20f;
            _polygons[4].Translate(ref trans);

            _subject = _polygons[0];
            _clip = _polygons[1];

            base.Initialize();
        }
Example #3
0
        /// <summary>
        /// Decompose the polygon into several smaller non-concave polygons.
        /// </summary>
        /// <param name="vertices">The polygon to decompose.</param>
        /// <param name="sheer">The sheer to use if you get bad results, try using a higher value.</param>
        /// <returns>A list of trapezoids</returns>
        public static List<Vertices> ConvexPartitionTrapezoid(Vertices vertices, float sheer = 0.001f)
        {
            List<Point> compatList = new List<Point>(vertices.Count);

            foreach (Vector2 vertex in vertices)
            {
                compatList.Add(new Point(vertex.X, vertex.Y));
            }

            Triangulator t = new Triangulator(compatList, sheer);

            List<Vertices> list = new List<Vertices>();

            foreach (Trapezoid trapezoid in t.Trapezoids)
            {
                Vertices verts = new Vertices();

                List<Point> points = trapezoid.GetVertices();
                foreach (Point point in points)
                {
                    verts.Add(new Vector2(point.X, point.Y));
                }

                list.Add(verts);
            }

            return list;
        }
        public Entity BuildEntity(Entity e, params object[] args)
        {
            e.Tag = "Chassis";

            #region Body
            Body Chassis = e.AddComponent<Body>(new Body(_World, e));
            {
                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(-2.5f, 0.08f));
                vertices.Add(new Vector2(-2.375f, -0.46f));
                vertices.Add(new Vector2(-0.58f, -0.92f));
                vertices.Add(new Vector2(0.46f, -0.92f));
                vertices.Add(new Vector2(2.5f, -0.17f));
                vertices.Add(new Vector2(2.5f, 0.205f));
                vertices.Add(new Vector2(2.3f, 0.33f));
                vertices.Add(new Vector2(-2.25f, 0.35f));
                PolygonShape chassisShape = new PolygonShape(vertices, 2f);

                Chassis.BodyType = BodyType.Dynamic;
                Chassis.Position = new Vector2(0.0f, -1.0f);
                Chassis.CreateFixture(chassisShape);
            }
            #endregion

            #region Sprite
            e.AddComponent<Sprite>(new Sprite(args[0] as Texture2D, (Rectangle)args[1],
               Chassis, 1, Color.White, 0f));
            #endregion
            return e;
        }
Example #5
0
 public Goalie(World world, GoalieData spawn)
 {
     var body = new Body(world);
     var angle = spawn.End - spawn.Begin;
     body.Rotation = FMath.Atan2(angle.Y, angle.X);
     segment.A = spawn.Begin;
     segment.B = spawn.End;
     var normal = new Vector2(-angle.Y, angle.X);
     normal.Normalize();
     delta = normal * .5f;
     segmentOut.A = spawn.Begin + delta;
     segmentOut.B = spawn.End + delta;
     segmentIn.A = spawn.Begin - delta;
     segmentIn.B = spawn.End - delta;
     body.Position = spawn.Begin;
     var verts = new Vertices();
     verts.Add(new Vector2(left, bottom));
     verts.Add(new Vector2(right, bottom));
     verts.Add(new Vector2(right, top));
     verts.Add(new Vector2(left, top));
     var shape = new PolygonShape(verts, 1f);
     body.FixedRotation = true;
     body.BodyType = BodyType.Dynamic;
     Fixture = body.CreateFixture(shape);
 }
Example #6
0
        /// <summary>
        /// Create a new chainshape from the vertices.
        /// </summary>
        /// <param name="vertices">The vertices to use. Must contain 2 or more vertices.</param>
        /// <param name="createLoop">Set to true to create a closed loop. It connects the first vertice to the last, and automatically adjusts connectivity to create smooth collisions along the chain.</param>
        public ChainShape(Vertices vertices, bool createLoop = false)
            : base(0)
        {
            ShapeType = ShapeType.Chain;
            _radius = Settings.PolygonRadius;

            Debug.Assert(vertices != null && vertices.Count >= 3);
            Debug.Assert(vertices[0] != vertices[vertices.Count - 1]); // FPE. See http://www.box2d.org/forum/viewtopic.php?f=4&t=7973&p=35363

            for (int i = 1; i < vertices.Count; ++i)
            {
                Vector2 v1 = vertices[i - 1];
                Vector2 v2 = vertices[i];

                // If the code crashes here, it means your vertices are too close together.
                Debug.Assert(Vector2.DistanceSquared(v1, v2) > Settings.LinearSlop * Settings.LinearSlop);
            }

            Vertices = new Vertices(vertices);

            if (createLoop)
            {
                Vertices.Add(vertices[0]);
                PrevVertex = Vertices[Vertices.Count - 2]; //FPE: We use the properties instead of the private fields here.
                NextVertex = Vertices[1]; //FPE: We use the properties instead of the private fields here.
            }
        }
 /// <summary>
 /// Constructs a FPE Body from the given list of vertices and density
 /// </summary>
 /// <param name="game"></param>
 /// <param name="world"></param>
 /// <param name="vertices">The collection of vertices in display units (pixels)</param>
 /// <param name="bodyType"></param>
 /// <param name="density"></param>
 public PhysicsGameEntity(Game game, World world, Category collisionCategory, Vertices vertices, BodyType bodyType, float density)
     : this(game,world,collisionCategory)
 {
     ConstructFromVertices(world,vertices,density);
     Body.BodyType = bodyType;
     Body.CollisionCategories = collisionCategory;
 }
Example #8
0
        /// <summary>
        /// Decompose the polygon into several smaller non-concave polygon.
        /// If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices.
        /// </summary>
        public static List<Vertices> ConvexPartition(Vertices vertices)
        {
            Debug.Assert(vertices.Count > 3);
            Debug.Assert(vertices.IsCounterClockWise());

            return TriangulatePolygon(vertices);
        }
Example #9
0
        public override Body CreateBody(World world)
        {
            var unithull = new Vertices((Vector2[])this.ResourceDictionary.GetResource(_resource.CollisionHullKey));
            
            var scaledVertices = new List<Vector2>();
            foreach (var vertex in unithull)
            {
                scaledVertices.Add(new Vector2(vertex.X * _resource.Width, vertex.Y * _resource.Height));
            }

            var vertices = new Vertices(scaledVertices);

            var body = new Body(world);
            body.BodyType = BodyType.Dynamic;
            body.IgnoreGravity = true;
            body.LinearDamping = 0.0f;
            body.FixedRotation = true;
            body.Mass = 0;
            var location = ((ILocatable)_actor).Location;
            body.Position = new Vector2(location.X, location.Y);

            var shape = new PolygonShape(vertices, 1f);

            var fixture = body.CreateFixture(shape, 0f);
            fixture.CollisionGroup = _resource.CollisionGroup;
            fixture.UserData = new CollisionData { Actor = _actor };
            fixture.OnCollision += OnCollision;
            _body = body;
            return body;
        }
 public cRigidBodyGameObject(float mass, Vertices v)
 {
     _rigidBody = new PolygonRigidBody(mass, v);
     cPhysics.Instance.addObject(this);
     _canAttachPortalTo = false;
     _portaling = false;
 }
Example #11
0
 public static Body CreateLoopShape(World world, Vertices vertices, Vector2 position,
                                   DebugMaterial userData)
 {
     Body body = CreateBody(world, position);
     FixtureFactory.AttachLoopShape(vertices, body, userData);
     return body;
 }
Example #12
0
        public override Body CreateBody(World world)
        {
            var unitHull = (Vector2[])ResourceDictionary.GetResource("UnitHull");

            var scaledVertices = new List<Vector2>();
            foreach (var vertex in unitHull)
            {
                scaledVertices.Add(new Vector2(vertex.X * _resource.Width, vertex.Y * _resource.Height));
            }
            
            var vertices = new Vertices(scaledVertices);

            var body = new Body(world);
            body.BodyType = BodyType.Static;
            
            var location = ((ILocatable)_actor).Location;
            body.Position = new Vector2(location.X, location.Y);

            var shape = new PolygonShape(vertices, 1f);

            var fixture = body.CreateFixture(shape, 0f);
            fixture.UserData = new CollisionData { Actor = _actor };
            fixture.CollisionGroup = _resource.CollisionGroup;            
            fixture.OnCollision += OnCollision;
            _body = body;
            return body;
        }
        /// <summary>
        /// Cut a the contour and add a triangle into V to describe the 
        /// location of the cut
        /// </summary>
        /// <param name="contour">The list of points defining the polygon</param>
        /// <param name="u">The index of the first point</param>
        /// <param name="v">The index of the second point</param>
        /// <param name="w">The index of the third point</param>
        /// <param name="n">The number of elements in the array.</param>
        /// <param name="V">The array to populate with indicies of triangles.</param>
        /// <returns>True if a triangle was found</returns>
        private static bool Snip(Vertices contour, int u, int v, int w, int n,
                                 int[] V)
        {
            if (Settings.Epsilon > MathUtils.Area(ref _tmpA, ref _tmpB, ref _tmpC))
            {
                return false;
            }

            for (int p = 0; p < n; p++)
            {
                if ((p == u) || (p == v) || (p == w))
                {
                    continue;
                }

                Vector2 point = contour[V[p]];

                if (InsideTriangle(ref _tmpA, ref _tmpB, ref _tmpC, ref point))
                {
                    return false;
                }
            }

            return true;
        }
Example #14
0
        public SquareStack(Vector2 pos, Vector2 size, Vector2 subSize, float rot, SpriteBatch batch, Texture2D texture, World world)
            : base(pos, batch, texture, world)
        {
            this.size = size;
            this.subSize = subSize;
            this.rot = rot;
            this.texture = texture;
            this.color = Color.Green;
            this.spriteOrigin = new Vector2(texture.Width / 2, texture.Height / 2);
            this.backCol = new Color(color.R / 2, color.G / 2, color.B / 2);

            rMat = Matrix.CreateRotationZ(rot);

            if (Settings.MaxPolygonVertices < 24) Settings.MaxPolygonVertices = 24;

            Vector2 leftTop = Vector2.Transform(new Vector2(-size.X / 2, -size.Y / 2), rMat);
            Vector2 rightTop = Vector2.Transform(new Vector2(size.X / 2, -size.Y / 2), rMat);
            Vector2 leftBottom = Vector2.Transform(new Vector2(-size.X / 2, size.Y / 2), rMat);
            Vector2 rightBottom = Vector2.Transform(new Vector2(size.X / 2, size.Y / 2), rMat);

            Vertices verts = new Vertices();
            verts.Add(leftTop); verts.Add(rightTop); verts.Add(rightBottom); verts.Add(leftBottom);
            FixtureFactory.AttachPolygon(verts, density, body);

            this.width = max(max(leftTop.X, rightTop.X), max(leftBottom.X, rightBottom.X)) - min(min(leftTop.X, rightTop.X), min(leftBottom.X, rightBottom.X));
            this.height = max(max(leftTop.Y, rightTop.Y), max(leftBottom.Y, rightBottom.Y)) - min(min(leftTop.Y, rightTop.Y), min(leftBottom.Y, rightBottom.Y));
        }
        /// <summary>
        /// Create static collidable bodies from vertices in each layer
        /// sent with the parameter
        /// </summary>
        /// <param name="layers">List of layers ment for making collisionboxes</param>
        void CreateStaticCollidables(List<Layer> layers, World world)
        {
            foreach (Layer layer in layers)
            {
                TileArray tileArray = layer.Tiles;
                Size tileSize = layer.TileSize;
                Size amntOfTiles = layer.LayerSize;
                Vertices vertices = new Vertices();

                for (int x = 0; x < amntOfTiles.Width; x++)
                {
                    for (int y = 0; y < amntOfTiles.Height; y++)
                    {
                        Location tileLocation = new Location(x, y);
                        Tile thisTile = tileArray[tileLocation];
                        if (thisTile != null)
                        {
                            //Vector2 vertex = new Vector2(x * tileSize.Width, y * tileSize.Height);
                            Vector2 vertex = new Vector2(ConvertUnits.ToSimUnits(x * tileSize.Width), ConvertUnits.ToSimUnits(y * tileSize.Height));
                            vertices.Add(vertex);
                        }
                    }
                }
                layerVertices.Add(vertices);

                Vertices hull = GiftWrap.GetConvexHull(vertices);
                Body body = BodyFactory.CreateLoopShape(world, hull);
                body.BodyType = BodyType.Static;
                body.Friction = 0.8f;
                body.Restitution = 0;
            }
        }
        public RectanglePhysicsComponent(Engine engine, Rectangle rectangle, Vector2 gameWorldPosition, bool dynamic)
            : base(engine)
        {
            // create vertices to create a rectangle in the physics world with
            Vertices vertices = new Vertices();
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Bottom)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Bottom)));

            MainFixture = FixtureFactory.CreatePolygon(Engine.Physics.World, vertices, 1.0f);
            MainFixture.Body.Position = Engine.Physics.PositionToPhysicsWorld(gameWorldPosition);
            if (dynamic)
            {
                MainFixture.Body.BodyType = BodyType.Dynamic;
            }
            else
            {
                MainFixture.Body.BodyType = BodyType.Static;
            }
            MainFixture.Restitution = 0.5f;

            // adding some linear damping gives a max speed and seems to smooth out player motion really well
            MainFixture.Body.LinearDamping = 1.0f;
        }
Example #17
0
        /// <summary>
        /// Removes all collinear points on the polygon.
        /// </summary>
        /// <param name="vertices">The polygon that needs simplification.</param>
        /// <param name="collinearityTolerance">The collinearity tolerance.</param>
        /// <returns>A simplified polygon.</returns>
        public static Vertices CollinearSimplify(Vertices vertices, float collinearityTolerance)
        {
            //We can't simplify polygons under 3 vertices
            if (vertices.Count < 3)
                return vertices;

            Vertices simplified = new Vertices();

            for (int i = 0; i < vertices.Count; i++)
            {
                int prevId = vertices.PreviousIndex(i);
                int nextId = vertices.NextIndex(i);

                Vector2 prev = vertices[prevId];
                Vector2 current = vertices[i];
                Vector2 next = vertices[nextId];

                //If they collinear, continue
                if (MathUtils.Collinear(ref prev, ref current, ref next, collinearityTolerance))
                    continue;

                simplified.Add(current);
            }

            return simplified;
        }
Example #18
0
        public TestRendering(IoCContainer container)
        {
            camera = new Camera2D();

            RenderDelegateChainStep renderStep = new RenderDelegateChainStep("TestRendering", Render);

            container.Resolve<IUIRenderChain>().RegisterStep(renderStep);

            IInput input = container.Resolve<IInput>();

            input.AddBinding(string.Empty, false, false, false, System.Windows.Forms.Keys.Up, null, (s, e) => { camera.Position += Vector3.UnitY; });
            input.AddBinding(string.Empty, false, false, false, System.Windows.Forms.Keys.Down, null, (s, e) => { camera.Position -= Vector3.UnitY; });
            input.AddBinding(string.Empty, false, false, false, System.Windows.Forms.Keys.Left, null, (s, e) => { camera.Position += Vector3.UnitX; });
            input.AddBinding(string.Empty, false, false, false, System.Windows.Forms.Keys.Right, null, (s, e) => { camera.Position -= Vector3.UnitX; });

            IDeviceContextService deviceContextService = container.Resolve<IDeviceContextService>();
            DeviceContext context = deviceContextService.Context;

            deviceContextService.Form.ResizeEnd += new EventHandler(Form_ResizeEnd);

            _texture = Texture2D.FromFile(context, "Resources\\Helix.jpg", Usage.None, Pool.Managed);
            _elements = new TexturedElement[250];

            for (int i = 0; i < _elements.Length; i++)
            {
                _elements[i] = new TexturedElement(new SharpDX.Vector2(50, 50));
                _elements[i].Position = new Vector2(i * 20, i * 20);
            }

            _vertices = new Vertices<VertexPositionTexture>(context,
                new VertexPositionTexture() { Position = new Vector3(-0.5f, -0.5f, 0), TextureCoordinate = new Vector2(0, 0) },
                new VertexPositionTexture() { Position = new Vector3(-0.5f,  0.5f, 0), TextureCoordinate = new Vector2(1, 0) },
                new VertexPositionTexture() { Position = new Vector3( 0.5f, -0.5f, 0), TextureCoordinate = new Vector2(0, 1) },
                new VertexPositionTexture() { Position = new Vector3( 0.5f,  0.5f, 0), TextureCoordinate = new Vector2(1, 1) });
        }
Example #19
0
        private static bool CanSee(int i, int j, Vertices vertices)
        {
            if (Reflex(i, vertices))
            {
                if (LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)) && RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)))
                    return false;
            }
            else
            {
                if (RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)) || LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)))
                    return false;
            }
            if (Reflex(j, vertices))
            {
                if (LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)) && RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)))
                    return false;
            }
            else
            {
                if (RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)) || LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)))
                    return false;
            }
            for (int k = 0; k < vertices.Count; ++k)
            {
                if ((k + 1) % vertices.Count == i || k == i || (k + 1) % vertices.Count == j || k == j)
                    continue; // ignore incident edges

                Vector2 intersectionPoint;

                if (LineTools.LineIntersect(At(i, vertices), At(j, vertices), At(k, vertices), At(k + 1, vertices), out intersectionPoint))
                    return false;
            }
            return true;
        }
Example #20
0
        public override void Placed()
        {
            placed = true;
            dragable = false;

            //reset color
            color = Color.White;

            //Compute Vertices
            top = new Vector2((float)position.X, (float)position.Y - (float)size.Y / 2f);
            bottomLeft = new Vector2((float)position.X - (float)size.X / 2f, (float)position.Y + (float)size.Y / 2f);
            bottomRight = new Vector2((float)position.X + (float)size.X / 2f, (float)position.Y + (float)size.Y / 2f);

            //initialize body physics parameters
            Vertices vertices = new Vertices();
            vertices.Add(UnitConverter.toSimSpace(top));
            vertices.Add(UnitConverter.toSimSpace(bottomLeft));
            vertices.Add(UnitConverter.toSimSpace(bottomRight));
            brickBody = BodyFactory.CreatePolygon(Game1.world, vertices, 1.0f, "TriangleBrick");
            //brickBody = BodyFactory.CreateRectangle(Game1.world, UnitConverter.toSimSpace(brickWidth), UnitConverter.toSimSpace(brickHeight), 1.0f, UnitConverter.toSimSpace(position));
            brickBody.BodyType = BodyType.Static;
            brickBody.OnCollision += BrickBody_OnCollision;
            brickBody.Restitution = 0.1f;
            brickBody.AngularDamping = 20;
            brickBody.Friction = 0.5f;
        }
Example #21
0
        private ConvexHullTest2()
        {
            _pointCloud1 = new Vertices(32);

            for (int i = 0; i < 32; i++)
            {
                float x = Rand.RandomFloat(-10, 10);
                float y = Rand.RandomFloat(-10, 10);

                _pointCloud1.Add(new Vector2(x, y));
            }

            _pointCloud2 = new Vertices(_pointCloud1);
            _pointCloud3 = new Vertices(_pointCloud1);

            //Melkman DOES NOT work on point clouds. It only works on simple polygons.
            _pointCloud1.Translate(new Vector2(-20, 30));
            _melkman = Melkman.GetConvexHull(_pointCloud1);

            //Giftwrap works on point clouds

            _pointCloud2.Translate(new Vector2(20, 30));
            _giftWrap = GiftWrap.GetConvexHull(_pointCloud2);

            _pointCloud3.Translate(new Vector2(20, 10));
            _chainHull = ChainHull.GetConvexHull(_pointCloud3);
        }
Example #22
0
        void Initialize()
        {
            Vertices vertices = new Vertices();

            vertices.Add(new Vector2(1, 749));
            vertices.Add(new Vector2(999, 749));

            vertices.Add(new Vector2(999, 550));
            vertices.Add(new Vector2(900, 530));
            vertices.Add(new Vector2(800, 540));
            vertices.Add(new Vector2(700, 530));
            vertices.Add(new Vector2(620, 450));
            vertices.Add(new Vector2(580, 420));
            vertices.Add(new Vector2(500, 410));
            vertices.Add(new Vector2(470, 500));
            vertices.Add(new Vector2(400, 550));
            vertices.Add(new Vector2(370, 540));
            vertices.Add(new Vector2(300, 550));
            vertices.Add(new Vector2(1, 510));

            this.Body = BodyFactory.Instance.CreatePolygonBody(this.simulator, vertices, 10);
            this.Body.IsStatic = true;

            Geom geometry;
            geometry = GeomFactory.Instance.CreatePolygonGeom(this.simulator, this.Body, vertices, 1f);
            geometry.RestitutionCoefficient = .1f;
            geometry.FrictionCoefficient = 1f;
            geometry.Tag = this;

            this.brush = new Round4GroundBrush();
            this.brush.Extender.Body = this.Body;
        }
Example #23
0
        private static void SimplifySection(Vertices vertices, int i, int j)
        {
            if ((i + 1) == j)
                return;

            Vector2 A = vertices[i];
            Vector2 B = vertices[j];
            double maxDistance = -1.0;
            int maxIndex = i;
            for (int k = i + 1; k < j; k++)
            {
                double distance = DistancePointLine(vertices[k], A, B);

                if (distance > maxDistance)
                {
                    maxDistance = distance;
                    maxIndex = k;
                }
            }
            if (maxDistance <= _distanceTolerance)
                for (int k = i + 1; k < j; k++)
                    _usePt[k] = false;
            else
            {
                SimplifySection(vertices, i, maxIndex);
                SimplifySection(vertices, maxIndex, j);
            }
        }
        /// <summary>
        /// Decomposes a non-convex polygon into a number of convex polygons, up
        /// to maxPolys (remaining pieces are thrown out).
        /// Each resulting polygon will have no more than Settings.MaxPolygonVertices
        /// vertices.
        /// Warning: Only works on simple polygons
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="maxPolys">The maximum number of polygons.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns></returns>
        public static List<Vertices> ConvexPartition(Vertices vertices, int maxPolys, float tolerance)
        {
            if (vertices.Count < 3)
                return new List<Vertices> {vertices};

            List<Triangle> triangulated;

            if (vertices.IsCounterClockWise())
            {
                Vertices tempP = new Vertices(vertices);
                tempP.Reverse();
                triangulated = TriangulatePolygon(tempP);
            }
            else
            {
                triangulated = TriangulatePolygon(vertices);
            }
            if (triangulated.Count < 1)
            {
                //Still no luck?  Oh well...
                throw new Exception("Can't triangulate your polygon.");
            }

            List<Vertices> polygonizedTriangles = PolygonizeTriangles(triangulated, maxPolys, tolerance);

            //The polygonized triangles are not guaranteed to be without collinear points. We remove
            //them to be sure.
            for (int i = 0; i < polygonizedTriangles.Count; i++)
            {
                polygonizedTriangles[i] = SimplifyTools.CollinearSimplify(polygonizedTriangles[i], 0);
            }

            return polygonizedTriangles;
        }
Example #25
0
        //box2D rev 32 - for details, see http://www.box2d.org/forum/viewtopic.php?f=4&t=83&start=50
        /// <summary>
        /// Decompose the polygon into several smaller non-concave polygon.
        /// Each resulting polygon will have no more than Settings.MaxPolygonVertices vertices.
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="tolerance">The tolerance.</param>
        public static List<Vertices> ConvexPartition(Vertices vertices, float tolerance = 0.001f)
        {
            Debug.Assert(vertices.Count > 3);
            Debug.Assert(!vertices.IsCounterClockWise());

            return TriangulatePolygon(vertices, tolerance);
        }
Example #26
0
			public static Body createPolygon( World world, Vertices vertices, float density, Vector2 position = new Vector2(), float rotation = 0, BodyType bodyType = BodyType.Static, object userData = null )
			{
				for( var i = 0; i < vertices.Count; i++ )
					vertices[i] *= FSConvert.displayToSim;

				return FarseerPhysics.Factories.BodyFactory.CreatePolygon( world, vertices, density, FSConvert.toSimUnits( position ), rotation, bodyType, userData );
			}
Example #27
0
			public static Body createLoopShape( World world, Vertices vertices, Vector2 position = new Vector2(), object userData = null )
			{
				for( var i = 0; i < vertices.Count; i++ )
					vertices[i] *= FSConvert.displayToSim;

				return FarseerPhysics.Factories.BodyFactory.CreateLoopShape( world, vertices, FSConvert.toSimUnits( position ), userData );
			}
Example #28
0
        /// <summary>
        /// Implements "A new algorithm for Boolean operations on general polygons" 
        /// available here: http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf
        /// Merges two polygons, a subject and a clip with the specified operation. Polygons may not be 
        /// self-intersecting.
        /// 
        /// Warning: May yield incorrect results or even crash if polygons contain collinear points.
        /// </summary>
        /// <param name="subject">The subject polygon.</param>
        /// <param name="clip">The clip polygon, which is added, 
        /// substracted or intersected with the subject</param>
        /// <param name="clipType">The operation to be performed. Either
        /// Union, Difference or Intersection.</param>
        /// <param name="error">The error generated (if any)</param>
        /// <returns>A list of closed polygons, which make up the result of the clipping operation.
        /// Outer contours are ordered counter clockwise, holes are ordered clockwise.</returns>
        private static List<Vertices> Execute(Vertices subject, Vertices clip,
                                              PolyClipType clipType, out PolyClipError error)
        {
            Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!", "Input polygons must be simple (cannot intersect themselves).");

            // Copy polygons
            Vertices slicedSubject;
            Vertices slicedClip;
            // Calculate the intersection and touch points between
            // subject and clip and add them to both
            CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);

            // Translate polygons into upper right quadrant
            // as the algorithm depends on it
            Vector2 lbSubject = subject.GetAABB().LowerBound;
            Vector2 lbClip = clip.GetAABB().LowerBound;
            Vector2 translate;
            Vector2.Min(ref lbSubject, ref lbClip, out translate);
            translate = Vector2.One - translate;
            if (translate != Vector2.Zero)
            {
                slicedSubject.Translate(ref translate);
                slicedClip.Translate(ref translate);
            }

            // Enforce counterclockwise contours
            slicedSubject.ForceCounterClockWise();
            slicedClip.ForceCounterClockWise();

            List<Edge> subjectSimplices;
            List<float> subjectCoeff;
            List<Edge> clipSimplices;
            List<float> clipCoeff;
            // Build simplical chains from the polygons and calculate the
            // the corresponding coefficients
            CalculateSimplicalChain(slicedSubject, out subjectCoeff, out subjectSimplices);
            CalculateSimplicalChain(slicedClip, out clipCoeff, out clipSimplices);

            List<Edge> resultSimplices;

            // Determine the characteristics function for all non-original edges
            // in subject and clip simplical chain and combine the edges contributing
            // to the result, depending on the clipType
            CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType,
                                 out resultSimplices);

            List<Vertices> result;
            // Convert result chain back to polygon(s)
            error = BuildPolygonsFromChain(resultSimplices, out result);

            // Reverse the polygon translation from the beginning
            // and remove collinear points from output
            translate *= -1f;
            for (int i = 0; i < result.Count; ++i)
            {
                result[i].Translate(ref translate);
                SimplifyTools.CollinearSimplify(result[i]);
            }
            return result;
        }
        public PathTile(List<Vector2> localPoints, Vector2 position, World world, bool MakroCollision = false)
        {
            body = new Body(world);
            body.Position = ConvertUnits.ToSimUnits(position);
            body.UserData = "Wall";
            body.IsStatic = true;

            Vertices terrain = new Vertices();

            foreach (Vector2 point in localPoints)
            {
                terrain.Add(ConvertUnits.ToSimUnits(point));
            }

            for (int i = 0; i < terrain.Count - 1; ++i)
            {
                FixtureFactory.AttachEdge(terrain[i], terrain[i + 1], body);
                body.FixtureList[i].UserData = "Wall";
            }
            body.Restitution = 0f;
            body.Friction = float.MaxValue;
            if (!MakroCollision)
                body.CollisionCategories = Category.Cat15 & ~Category.Cat3;
            else
                body.CollidesWith = Category.Cat29;
        }
Example #30
0
 public FSCollisionPolygon(List <Vector2> vertices) : this()
 {
     _verts = new Vertices(vertices);
     _verts.Scale(new Vector2(FSConvert.DisplayToSim));
 }
Example #31
-1
        public static List<Vertices> ConvexPartition(Vertices vertices)
        {
            Polygon poly = new Polygon();

            foreach (FVector2 vertex in vertices)
            {
                poly.Points.Add(new TriangulationPoint(vertex.X, vertex.Y));
            }

            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);

            List<Vertices> results = new List<Vertices>();

            foreach (DelaunayTriangle triangle in poly.Triangles)
            {
                Vertices v = new Vertices();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v.Add(new FVector2((float)p.X, (float)p.Y));
                }
                results.Add(v);
            }

            return results;
        }