/// <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(); }