class_docstr: Constrained delaunay triangulation
  
  Implementation based on [1]_.
  
  Parameters
  ----------
  pts : array
      Nx2 array of points.
  edges : array
      Nx2 array of edges (dtype=int).
  
  Notes
  -----
  * Delaunay legalization is not yet implemented. This produces a proper
    triangulation, but adding legalisation would produce fewer thin
    triangles.
  * The pts and edges arrays may be modified.
  
  References
  ----------
  .. [1] Domiter, V. and Žalik, B. Sweep‐line algorithm for constrained
     Delaunay triangulation
class_docstr_tok: ["Constrained","delaunay","triangulation","Implementation","based","on","[","1","]","_.","Parameters","--","--","--","--","--","pts",":","array","Nx2","array","of","points",".","edges",":","array","Nx2","array","of","edges","(","dtype=int",")",".","Notes","--","--","-","*","Delaunay","legalization","is","not","yet","implemented",".","This","produces","a","proper","triangulation",",","but","adding","legalisation","would","produce","fewer","thin","triangles",".","*","The","pts","and","edges","arrays","may","be","modified",".","References","--","--","--","--","--","..","[","1","]","Domiter",",","V.","and","\u017dalik",",","B.","Sweep\u2010line","algorithm","for","constrained","Delaunay","triangulation"]
code: def _merge_duplicate_points(self):
      # generate a list of all pairs (i,j) of identical points
      dups = []
      for i in range(self.pts.shape[0] - 1):
          test_pt = self.pts[i : i + 1]
          comp_pts = self.pts[i + 1 :]
          eq = test_pt == comp_pts
          eq = eq[:, 0] & eq[:, 1]
          for j in np.argwhere(eq)[:, 0]:
              dups.append((i, i + 1 + j))
  
      dups_arr = np.array(dups)
      # remove duplicate points
      pt_mask = np.ones(self.pts.shape[0], dtype=bool)
      for i, inds in enumerate(dups_arr):
          # remove j from points
          # (note we pull the index from the original dups instead of
          # dups_arr because the indexes in pt_mask do not change)
          pt_mask[dups[i][1]] = False
  
          i, j = inds
  
          # rewrite edges to use i instead of j
          self.edges[self.edges == j] = i
  
          # decrement all point indexes > j
          self.edges[self.edges > j] -= 1
          dups_arr[dups_arr > j] -= 1
  
      self.pts = self.pts[pt_mask]
  
      # remove zero-length edges
      mask = self.edges[:, 0] != self.edges[:, 1]
      self.edges = self.edges[mask]
  
imports: from __future__ import division, print_function
  from itertools import permutations
  import numpy
  from collections import OrderedDict
label_desc: Use image node_id 18 for calling the Triangulation obj's underlying member method code with example usage: obj._merge_duplicate_points() without return types