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()