// Join two polygons (assuming that they are adjacent and share an edge) public Polygon Join(Polygon other) { int thisEdgeId = -1; int otherEdgeId = -1; for (int i = 0; i < Length() && thisEdgeId == -1; i++) { Vector3 thisFrom = Vertex(i); Vector3 thisTo = Vertex((i + 1) % Length()); for (int j = 0; j < other.Length(); j++) { Vector3 otherFrom = other.Vertex(j); Vector3 otherTo = other.Vertex((j + 1) % other.Length()); if ((thisFrom - otherTo).sqrMagnitude < 0.001f && (thisTo - otherFrom).sqrMagnitude < 0.001f) { thisEdgeId = i; otherEdgeId = j; break; } } } if (thisEdgeId == -1) { return(null); } Polygon res = new Polygon(); // add current points for (int i = 0; i < Length(); i++) { res.vertices.Add(vertices[(i + thisEdgeId + 1) % Length()]); } otherEdgeId = otherEdgeId + 2; // skip current since this equals the last vertex of res // add vertices from other for (int i = 0; i < other.Length() - 2; i++) { res.vertices.Add(other.vertices[(i + otherEdgeId) % other.Length()]); } // remove any edge (where two edges share endpoints but has different directions for (int i = 0; i < res.Length(); i++) { var thisVert = res.Vertex(i); var nextNextVert = res.Vertex((i + 2) % res.Length()); bool almostEqual = (thisVert - nextNextVert).sqrMagnitude < 0.001f; if (almostEqual) { var vects = new int[] { (i + 1) % res.Length(), i }; System.Array.Sort(vects); res.vertices.RemoveRange(vects[1], 1); res.vertices.RemoveRange(vects[0], 1); i = i + 2; } } return(res); }
public void Polygon_Vertices() { Point[] actual = thePolygon.Vertices.ToArray(); Assert.Equal(expected.Length, actual.Length); for (int i = 0; i < expected.Length; i++) { Assert.Equal(expected[i], actual[i]); } for (int i = 0; i < expected.Length; i++) { Assert.Equal(expected[i], thePolygon.Vertex(i)); Assert.Equal(expected[i], thePolygon.Vertex(i + expected.Length)); Assert.Equal(expected[i], thePolygon.Vertex(i - expected.Length)); } }
public ColoredParticleRenderer(Polygon polygon) { if (polygon.Length < 3) { throw new ArgumentException("The polygon must have at least three vertices.", nameof(polygon)); } _verticesPerParticle = 3 + (polygon.Length - 3) * 3; // First three vertices contribute one triangle; each remaining vertex contributes one triangle _polygonVertices = new GraphicsPoint[_verticesPerParticle]; _polygonVertices[0] = (GraphicsPoint)polygon.Vertex(0); _polygonVertices[1] = (GraphicsPoint)polygon.Vertex(1); _polygonVertices[2] = (GraphicsPoint)polygon.Vertex(2); for (int i = 3, c = 3; i < polygon.Length; i++) { _polygonVertices[c++] = _polygonVertices[0]; _polygonVertices[c++] = (GraphicsPoint)polygon.Vertex(i - 1); _polygonVertices[c++] = (GraphicsPoint)polygon.Vertex(i); } }
public static GraphicsPoint[] Tesselate(this Polygon polygon) { var result = new GraphicsPoint[polygon.Length]; for (int i = 0, sign = 1; i < polygon.Length; i++, sign = -sign) { result[i] = (GraphicsPoint)polygon.Vertex(i * sign); } return(result); }
/// <summary> /// Splits a polygon by a given plane, resulting in two polygons. Note /// that this function assumes that the polygon intersects the split plane. /// </summary> /// <param name="poly"></param> /// <param name="splitPlane"></param> /// <returns>Two polygons in a list.</returns> public static List <Polygon> SplitPolygon(Polygon poly, Plane splitPlane) { Polygon front = new Polygon(); Polygon back = new Polygon(); front.Used = poly.Used; front.Plane = poly.Plane; back.Used = poly.Used; back.Plane = poly.Plane; Vector3 pointA, pointB; PointClassification sideA, sideB; pointA = poly.Vertices.Last(); sideA = ClassifyPoint(pointA, splitPlane); for (int i = 0; i < poly.Vertices.Count; i++) { pointB = poly.Vertex(i); sideB = ClassifyPoint(pointB, splitPlane); if (sideB == PointClassification.Front) { if (sideA == PointClassification.Back) { Vector3 v = (pointB - pointA).normalized; Ray r = new Ray(pointA, v); float e; splitPlane.Raycast(r, out e); Vector3 intersectionPoint = pointA + v * e; front.AddVertex(intersectionPoint); back.AddVertex(intersectionPoint); } front.AddVertex(pointB); } else if (sideB == PointClassification.Back) { if (sideA == PointClassification.Front) { Vector3 v = (pointB - pointA).normalized; Ray r = new Ray(pointA, v); float e; splitPlane.Raycast(r, out e); Vector3 intersectionPoint = pointA + v * e; front.AddVertex(intersectionPoint); back.AddVertex(intersectionPoint); } back.AddVertex(pointB); } else { front.AddVertex(pointB); back.AddVertex(pointB); } pointA = pointB; sideA = sideB; } return(new List <Polygon>() { front, back }); }
// Join two polygons (assuming that they are adjacent and share an edge) public Polygon Join(Polygon other) { int thisEdgeId = -1; int otherEdgeId = -1; for (int i=0;i<Length() && thisEdgeId == -1;i++){ Vector3 thisFrom = Vertex(i); Vector3 thisTo = Vertex((i+1)%Length()); for (int j=0;j<other.Length();j++){ Vector3 otherFrom = other.Vertex(j); Vector3 otherTo = other.Vertex((j+1)%other.Length()); if ((thisFrom-otherTo).sqrMagnitude < 0.001f && (thisTo-otherFrom).sqrMagnitude < 0.001f){ thisEdgeId = i; otherEdgeId = j; break; } } } if (thisEdgeId == -1){ return null; } Polygon res = new Polygon(); // add current points for (int i=0;i<Length();i++){ res.vertices.Add(vertices[(i+thisEdgeId+1)%Length()]); } otherEdgeId=otherEdgeId+2; // skip current since this equals the last vertex of res // add vertices from other for (int i=0;i<other.Length()-2;i++){ res.vertices.Add(other.vertices[(i+otherEdgeId)%other.Length()]); } // remove any edge (where two edges share endpoints but has different directions for (int i=0;i<res.Length();i++){ var thisVert = res.Vertex(i); var nextNextVert = res.Vertex((i+2)%res.Length()); bool almostEqual = (thisVert - nextNextVert).sqrMagnitude < 0.001f; if (almostEqual){ var vects = new int[]{(i+1)%res.Length(),i}; System.Array.Sort(vects); res.vertices.RemoveRange(vects[1],1); res.vertices.RemoveRange(vects[0],1); i = i+2; } } return res; }