/// <summary> /// sets the vertices without copying over the data from verts to the local List. /// </summary> /// <param name="verts">Verts.</param> public void setVerticesNoCopy(Vertices verts) { Debug.Assert(verts.Count >= 3 && verts.Count <= Settings.maxPolygonVertices); _vertices = verts; if (Settings.useConvexHullPolygons) { // FPE note: This check is required as the GiftWrap algorithm early exits on triangles // So instead of giftwrapping a triangle, we just force it to be clock wise. if (_vertices.Count <= 3) { _vertices.forceCounterClockWise(); } else { _vertices = GiftWrap.getConvexHull(_vertices); } } if (_normals == null) { _normals = new Vertices(_vertices.Count); } else { _normals.Clear(); } // Compute normals. Ensure the edges have non-zero length. for (var i = 0; i < _vertices.Count; ++i) { var next = i + 1 < _vertices.Count ? i + 1 : 0; var edge = _vertices[next] - _vertices[i]; Debug.Assert(edge.LengthSquared() > Settings.epsilon * Settings.epsilon); // FPE optimization: Normals.Add(MathHelper.Cross(edge, 1.0f)); var temp = new Vector2(edge.Y, -edge.X); Nez.Vector2Ext.normalize(ref temp); _normals.Add(temp); } // Compute the polygon mass data computeProperties(); }
static bool validatePolygon(Vertices polygon) { var errorCode = polygon.checkPolygon(); if (errorCode == PolygonError.InvalidAmountOfVertices || errorCode == PolygonError.AreaTooSmall || errorCode == PolygonError.SideTooSmall || errorCode == PolygonError.NotSimple) { return(false); } if (errorCode == PolygonError.NotCounterClockWise) //NotCounterCloseWise is the last check in CheckPolygon(), thus we don't need to call ValidatePolygon again. { polygon.Reverse(); } if (errorCode == PolygonError.NotConvex) { polygon = GiftWrap.getConvexHull(polygon); return(validatePolygon(polygon)); } return(true); }