public GeoCoordinate[] Tessellate(LineairRing ring) { List <GeoCoordinate> geoCoordinateList = new List <GeoCoordinate>(); if (ring.Coordinates.Count < 3) { throw new ArgumentOutOfRangeException("Invalid ring detected, only 1 or 2 vertices."); } List <GeoCoordinate> coordinates; for (LineairRing lineairRing = new LineairRing((IEnumerable <GeoCoordinate>)ring.Coordinates); lineairRing.Coordinates.Count > 3; lineairRing = new LineairRing((IEnumerable <GeoCoordinate>)coordinates)) { int vertexIdx = 0; while (!lineairRing.IsEar(vertexIdx)) { ++vertexIdx; } GeoCoordinate[] neigbours = lineairRing.GetNeigbours(vertexIdx); geoCoordinateList.Add(neigbours[0]); geoCoordinateList.Add(neigbours[1]); geoCoordinateList.Add(lineairRing.Coordinates[vertexIdx]); coordinates = lineairRing.Coordinates; int index = vertexIdx; coordinates.RemoveAt(index); } if (ring.Coordinates.Count == 3) { geoCoordinateList.Add(ring.Coordinates[0]); geoCoordinateList.Add(ring.Coordinates[1]); geoCoordinateList.Add(ring.Coordinates[2]); } return(geoCoordinateList.ToArray()); }
/// <summary> /// Tessellates the given LineairRings. /// </summary> /// <param name="ring"></param> /// <returns>A list of coordinates grouped per three.</returns> public GeoCoordinate[] Tessellate(LineairRing ring) { // TODO: yes i know this can be more efficient; proof of concept! // TODO: yes i know we know the number of triangles beforehand. // TODO: yes i know we can create a strip instead of duplicating coordinates!! List <GeoCoordinate> triangles = new List <GeoCoordinate>(); if (ring.Coordinates.Count < 3) { throw new ArgumentOutOfRangeException("Invalid ring detected, only 1 or 2 vertices."); } LineairRing workRing = new LineairRing(ring.Coordinates); while (workRing.Coordinates.Count > 3) { // cut an ear. int earIdx = 0; while (!workRing.IsEar(earIdx)) { earIdx++; } // ear should be found, cut it! GeoCoordinate[] neighbours = workRing.GetNeigbours(earIdx); triangles.Add(neighbours[0]); triangles.Add(neighbours[1]); triangles.Add(workRing.Coordinates[earIdx]); // remove ear and update workring. List <GeoCoordinate> ringCoordinates = workRing.Coordinates; ringCoordinates.RemoveAt(earIdx); workRing = new LineairRing(ringCoordinates); } if (ring.Coordinates.Count == 3) { // this ring is already a triangle. triangles.Add(ring.Coordinates[0]); triangles.Add(ring.Coordinates[1]); triangles.Add(ring.Coordinates[2]); } return(triangles.ToArray()); }