Draws a convex hull around ligand atoms and expands it, giving space to put diagramms on.
        This is done with the help of Shapely.geometry class. The initial convex hull the residue
        coordinates are inserted on, determines the order the coordinates are going to be moved, i.e.
        if the residue 1 is on the right side of residue 2, it will be pushed to the right, while
        residue 2 will be moved to the left.


        Also determines the 2D coordinates of all atoms in drawing and makes a list with those.

def convex_hull(self):
        """
        Draws a convex hull around ligand atoms and expands it, giving space to put diagramms on.
        This is done with the help of Shapely.geometry class. The initial convex hull the residue
        coordinates are inserted on, determines the order the coordinates are going to be moved, i.e.
        if the residue 1 is on the right side of residue 2, it will be pushed to the right, while
        residue 2 will be moved to the left.


        Also determines the 2D coordinates of all atoms in drawing and makes a list with those.

        """
        #Get coordinates of ligand atoms (needed to draw the convex hull around)
        self.ligand_atom_coords = []
        ligand_atoms = [x.name for x in self.topology_data.universe.ligand_noH.atoms]
        with open ("molecule.svg", "r") as f:
            lines = f.readlines()
            i=0
            for line in lines:
                if line.startswith("<ellipse"):
                    self.ligand_atom_coords.append([float(line.rsplit("'",10)[1]), float(line.rsplit("'",10)[3])])
                    for atom_id in self.atom_identities:
                        if i == self.atom_identities[atom_id]:
                            self.ligand_atom_coords_from_diagr[ligand_atoms[int(atom_id)]]=[float(line.rsplit("'",10)[1]), float(line.rsplit("'",10)[3])]
                    i+=1

        self.ligand_atom_coords=np.array(self.ligand_atom_coords)
        self.a = geometry.MultiPoint(self.ligand_atom_coords).convex_hull
        self.b = self.a.boundary.buffer(130).convex_hull
        self.b_for_all ={}
        self.b_lenght = self.b.boundary.length
        for residue in self.topology_data.closest_atoms:
            mean_distance =np.array([x[1] for x in self.topology_data.closest_atoms[residue]]).mean()
            b = self.a.boundary.parallel_offset(mean_distance*50+50,"left",join_style=2).convex_hull
            projection =[]
            projection_init = []
            for atom in self.topology_data.closest_atoms[residue]:
                point =geometry.Point((self.ligand_atom_coords_from_diagr[atom[0]][0],self.ligand_atom_coords_from_diagr[atom[0]][1]))
                projection.append(abs(b.boundary.project(point) % b.boundary.length))
                projection_init.append(abs(self.b.boundary.project(point) % self.b.boundary.length))
            # Check whether projections are not crossing the boundary point (i.e. end of circle) - is one number in the projection very different from any other?
            for (index1,number1), (index2,number2) in combinations(enumerate(projection),2):
                if abs(number1-number2)>b.boundary.length/2:
                    proj =[]
                    for atom in projection:
                        if atom == max([number1,number2]):
                            proj.append(atom-b.boundary.length)
                        else:
                            proj.append(atom)
                    projection = proj
            for (index1,number1), (index2,number2) in combinations(enumerate(projection_init),2):
                if abs(number1-number2)>self.b.boundary.length/2:
                    proj =[]
                    for atom in projection_init:
                        if atom == max([number1,number2]):
                            proj.append(atom-self.b.boundary.length)
                        else:
                            proj.append(atom)
                    projection_init = proj
            self.nearest_points_projection[residue] = np.array(projection).mean()
            self.b_for_all[residue] = np.array(projection_init).mean()
            self.nearest_points[residue] = b.boundary.interpolate(self.nearest_points_projection[residue] % b.boundary.length)
            self.nearest_points_coords[residue]=self.nearest_points[residue].x,self.nearest_points[residue].y