docs: def set_points(self, mode='', points=None, range_=RANGE, size=1):
          """ Initialize points according to predefined modes.
  
          :param range_:[xmin, xmax, ymin, ymax], range of point sets
          """
          if mode == 'last':
              if points is None:
                  print('Error: empty last point specification given.')
                  return
              tol = 0.1
              [i, j, k] = points
              alpha = 2.0 * np.random.rand(1) + 0.5
              beta = 2.0 * np.random.rand(1) + 0.5
              if i >= 0 and j < 0 and k < 0:
                  # at one corner of triangle
                  assert i < 3
                  other = np.delete(np.arange(3), i)
                  u = (self.points[i, :] - self.points[other[0], :]
                       ) / np.linalg.norm(
                           self.points[i, :] - self.points[other[0], :])
                  v = (self.points[i, :] - self.points[other[1], :]
                       ) / np.linalg.norm(
                           self.points[i, :] - self.points[other[1], :])
                  self.points[-1, :] = self.points[i, :] + alpha * u + beta * v
              elif i >= 0 and j >= 0 and k < 0:
                  found = False
                  safety_it = 0
                  while not found:
                      alpha = np.random.uniform(tol, 1 - tol)
                      beta = 1.0 - alpha
                      gamma = 2 * np.random.rand(1) + tol
                      assert j < 3
                      other = np.delete(np.arange(3), (i, j))
                      u = (
                          self.points[i, :] - self.points[other, :]
                      )  # /np.linalg.norm(self.points[i,:] - self.points[other,:])
                      v = (
                          self.points[j, :] - self.points[other, :]
                      )  # /np.linalg.norm(self.points[j,:] - self.points[other,:])
                      self.points[-1, :] = (1.0 + gamma) * (
                          self.points[other, :] + alpha * u + beta * v)
                      #check if new direction lies between u and v.
                      new_direction = self.points[-1, :] - self.points[other, :]
                      new_direction = new_direction.reshape(
                          (-1, )) / np.linalg.norm(new_direction)
                      u = u.reshape((-1, )) / np.linalg.norm(u)
                      v = v.reshape((-1, )) / np.linalg.norm(v)
                      #print('{} + {} = {}'.format(acos(np.dot(new_direction,u)),acos(np.dot(new_direction,v)),acos(np.dot(u,v))))
                      if abs(
                              acos(np.dot(new_direction, u)) +
                              acos(np.dot(new_direction, v)) -
                              acos(np.dot(u, v))) < 1e-10:
                          found = True
                      safety_it += 1
                      if safety_it > 100:
                          print('Error: nothing found after 100 iterations.')
                          return
              elif i >= 0 and j >= 0 and k >= 0:
                  # inside triangle
                  assert k < 3
                  found = False
                  safety_it = 0
                  while not found:
                      alpha = np.random.rand(1) + tol
                      beta = np.random.rand(1) + tol
                      other = np.delete(np.arange(3), i)
                      u = self.points[other[0], :] - self.points[i, :]
                      v = self.points[other[1], :] - self.points[i, :]
                      temptative_point = self.points[i, :] + alpha * u + beta * v
                      vjk = self.points[other[1], :] - self.points[other[0], :]
                      njk = [vjk[1], -vjk[0]]
                      if (np.dot(self.points[j, :] - self.points[i, :], njk) >
                              0) != (np.dot(temptative_point - self.points[j, :],
                                            njk) > 0):
                          self.points[-1, :] = temptative_point
                          found = True
                      safety_it += 1
                      if safety_it > 100:
                          print('Error: nothing found after 100 iterations.')
                          return
              elif i < 0 and j < 0 and k < 0:
                  x = range_[0] + (
                      range_[1] - range_[0]) * np.random.rand(1)
                  y = range_[2] + (
                      range_[1] - range_[0]) * np.random.rand(1)
                  self.points[-1, :] = [x, y]
              else:
                  print("Error: non-valid arguments.")
          elif mode == 'random':
              """ Create N uniformly distributed points in [0, size] x [0, size]
              """
              self.points = np.random.uniform(0, size, (self.N, self.d))
          elif mode == 'normal':
              self.points = np.random.normal(0, size, (self.N, self.d))
          elif mode == 'circle':
              from math import cos, sin
              x_range = size / 2.0
              y_range = size / 2.0
              c = np.array((x_range, y_range))
              r = 0.9 * min(x_range, y_range)
              theta = 2 * pi / self.N
              for i in range(self.N):
                  theta_tot = i * theta
                  self.points[i, :] = c + np.array(
                      (r * cos(theta_tot), r * sin(theta_tot)))
          elif mode == 'set':
              """
              Place points according to hard coded rule.
              """
              if self.N == 3:
                  x = [-1.0, 1.0, 0.0]
                  y = [-1.0, -1.0, 1.0]
              elif self.N == 4:
                  x = [-1.0, 1.0, 0.0, 0.0]
                  y = [-1.0, -1.0, 1.0, 0.0]
              elif self.N == 5:
                  x = [-0.0, 1.5, 1.5, -0.0, -1.0]
                  y = [-1.0, -1.0, 1.0, 1.0, 0.0]
              else:
                  print("Error: No rule defined for N = ", self.N)
                  return
              self.points = np.c_[x, y]
          elif mode == 'geogebra':
              if self.N == 4:
                  self.points = np.array(((1.5, 1.8), (7.9, 2.5), (2.3, 5.1),
                                          (3.34, -1.36)))
              elif self.N == 5:
                  self.points = np.array(((1.5, 1.8), (7.9, 2.5), (2.3, 5.1),
                                          (3.34, -1.36), (5, 1.4)))
              else:
                  print("Error: No rule defined for N = ", self.N)
          elif mode == '':
              if points is None:
                  raise NotImplementedError("Need to give either mode or points.")
              else:
                  self.points = points
                  self.N, self.d = points.shape
  
          self.init()