Ejemplo n.º 1
0
def ellipsoid_sheet(a, b, c, n_zs, **kwargs):
    """Creates an ellipsoidal apical mesh.

    Parameters
    ----------
    a, b, c : floats
       Size of the ellipsoid half axes in
       the x, y, and z directions, respectively
    n_zs : int
       The (approximate) number of faces along the z axis.

    kwargs are passed to `get_ellipsoid_centers`

    Returns
    -------
    eptm : a :class:`Epithelium` object

    The mesh returned is an `Epithelium` and not a simpler `Sheet`
    so that a unique cell data can hold information on the
    whole volume of the ellipsoid.

    """
    centers = get_ellipsoid_centers(a, b, c, n_zs, **kwargs)

    centers = centers.append(
        pd.Series({"x": 0, "y": 0, "z": 0, "theta": 0, "phi": 0}), ignore_index=True
    )

    centers["x"] /= a
    centers["y"] /= b
    centers["z"] /= c

    vor3d = Voronoi(centers[list("xyz")].values)
    vor3d.close()
    dsets = from_3d_voronoi(vor3d)
    veptm = Epithelium("v", dsets, config.geometry.bulk_spec())
    eptm_ = single_cell(veptm, centers.shape[0] - 1)
    eptm_.reset_index()
    eptm = get_outer_sheet(eptm_)
    eptm.reset_index()
    eptm.reset_topo()
    eptm.vert_df["rho"] = np.linalg.norm(eptm.vert_df[eptm.coords], axis=1)
    eptm.vert_df["theta"] = np.arcsin(eptm.vert_df.eval("z/rho"))
    eptm.vert_df["phi"] = np.arctan2(eptm.vert_df["y"], eptm.vert_df["x"])

    eptm.vert_df["x"] = a * (
        np.cos(eptm.vert_df["theta"]) * np.cos(eptm.vert_df["phi"])
    )
    eptm.vert_df["y"] = b * (
        np.cos(eptm.vert_df["theta"]) * np.sin(eptm.vert_df["phi"])
    )
    eptm.vert_df["z"] = c * np.sin(eptm.vert_df["theta"])
    eptm.settings["abc"] = [a, b, c]
    EllipsoidGeometry.update_all(eptm)
    return eptm
Ejemplo n.º 2
0
def Astar(initCord, clrn, exp=0, scale=2):
    actionSet = []
    fact = 1
    hc = 250
    wc = -250
    clrr = np.array(clrn, dtype='f')
    cart = np.array(initCord, dtype='f')
    print(clrr)
    if (clrr[0] >= 0):
        clr = clrr[0]
    else:
        print('Clearnace cannot be negative.....\nTerminating')
        return actionSet, -1
    # clr = float(int(clr*100)/100.)
    rad = 17.7  # 35,4/2 cm
    tot = int(math.ceil((rad + clr)) * fact)
    map1 = FinalMap(500, 500, tot)
    map1.circ(100, 200, 225)
    map1.circ(50, 400, 100)
    map1.circ(40, 375, 375)
    obsChk = Obs(500, 500, tot)
    cv2.imwrite('grid_init.jpg', map1.grid)
    map2 = cv2.imread('grid_init.jpg')
    map2 = cv2.cvtColor(map2, cv2.COLOR_BGR2RGB)
    plt.grid()
    plt.ion()
    plt.imshow(map2)
    print('Generating voronoi diagram.....')
    density = 0.8  # in percentage of total pixels
    samples = np.random.randint(tot,
                                501 - tot,
                                size=(int(500 * 500 * density), 2))
    vor = Voronoi(samples, incremental=True)
    print('Voronoi generated....')
    plt.show()
    init = np.array([hc - cart[1], cart[0] - wc, cart[2]], dtype='f')
    if (not obsChk.notObs(init[:-1])):
        print('Start position cannot be in the obstacle.....\nTerminating')
        return actionSet, -1
    checkInp = True
    while checkInp:
        print('Total clearance set at: ', tot)
        print(
            'Enter the step "d" in integer (1<=d<total clearance (value as above)): '
        )
        step_d = int(input())
        if (step_d < 1 or step_d >= tot):
            print('Wrong step size, try again.....')
        else:
            checkInp = False

# checkInp= True
# while checkInp:
#     print('Enter the initial starting coordinates in y as (0,500) & x as (0,500) and angle; ')
#     print('With origin at top left, Enter in the order of y, x, theta [separated by commas]: ')
#     cart= np.array(input(), dtype='f')
#     if(len(cart)!=3):
#         print 'Wrong input....Try again \nNote: Only 3 numbers needed inside the map boundaries'
#     else:
#         init= np.array([cart[0], cart[1], cart[2]], dtype='f')
#         if(not obsChk.notObs(init[:-1])):
#             print 'Start position cannot be in the obstacle.....Try again'
#         else:
#             checkInp = False

        checkInp = True
        while checkInp:
            print(
                'Enter the goal coordinates with origin at the top left as y, x [separated by commas]: '
            )
            fs = np.array(input(), dtype='f')
            if (len(fs) != 2):
                print 'Wrong input....Try again \nNote: Only 2 numbers needed inside the map boundaries'
            else:
                finalState = np.array([fs[0], fs[1], 0], dtype='f')
                if (not obsChk.notObs(finalState[:-1])):
                    print 'Goal position cannot be in the obstacle.....Try again'
                else:
                    checkInp = False
        height = 500
        width = 500
        parentState = init
        parentNode = threshold_state(parentState)
        finalNode = threshold_state(finalState)
        samples2 = np.array([
            parentState[:-1], finalState[:-1],
            [finalState[0] - 2, finalState[1] - 2],
            [finalState[0] + 2, finalState[1] - 2],
            [finalState[0] - 2, finalState[1] + 2],
            [finalState[0] + 2, finalState[1] + 2]
        ])
        Voronoi.add_points(vor, samples2)
        Voronoi.close(vor)
        A = vor.vertices.copy()  #(x,y) with origin at bottom left
        A[:, 1] = 500 - A[:, 1]
        isOKvert = obsChk.notObs1(A)
        allOKvert = A * isOKvert
        allOKvert = allOKvert[np.unique(np.nonzero(allOKvert)[0])]
        allOKvertThres = thresh(allOKvert)
        graph = AllNodes(height, width, 12)
        parentState = init
        parentNode = threshold_state(parentState)
        finalNode = threshold_state(finalState)
        parentCost = 0
        graph.updateCost2Come(parentNode, parentCost, 0, -1, parentState,
                              finalState, scale)
        parent_ownId = graph.visit(parentNode, parentState)
        reached = goalReached(parentNode, finalNode)
        found = False
        if (reached):
            found = True
            print('Input position is within the goal region')

        for i in allOKvertThres:
            graph.visited[i[1], i[0]] = 1

        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        if exp:
            vw = cv2.VideoWriter('maskVideo.avi', fourcc, 10.0, (501, 501))
            vw2 = cv2.VideoWriter('visitVideo.avi', fourcc, 10.0, (501, 501))
            tempImg = np.zeros([501, 501, 3], dtype='uint8')
            tempVisit = np.zeros([501, 501, 3], dtype='uint8')
            tempVisit[:, :, 1] = graph.visited * 120
            tempVisit[:, :, 0] = graph.visited * 120
        itr = 0
        flag = 0
        count = 0
        step_d = 3
        Rmin = tot
        print('Processing...Please wait')
        start_time = time.time()
        while (found != True):
            itr += 1
            mask = FinalMap(500, 500, -1)
            mask.circ(Rmin, parentNode[0], parentNode[1])
            finalMask = (
                (mask.grid[:, :, 0] / 255) - 1
            ) / 255  #dtype uint8 makes -1 value as 255 as [0,255] is only allowed
            explore = ((graph.visited * finalMask) == 1) * 1
            if exp:
                tempImg[:, :, 0] = explore * 255
                vw.write(tempImg)
            for angle in range(0, 360,
                               30):  # Iterating for all possible angles
                chk = True
                for sd in range(1, step_d + 1):
                    step = action(sd, angle + parentState[2])
                    tempState = parentState + step
                    tempState[2] = tempState[2] - parentState[2]
                    if (not obsChk.notObs(tempState[:-1])):
                        chk = False
                        break
                if (chk):
                    actId = angle
                    tempNode = threshold_state(tempState)
                    if (explore[tempNode[0], tempNode[1]] == 1):
                        tempCost2Come = parentCost + step_d
                        graph.updateCost2Come(tempNode, tempCost2Come,
                                              parent_ownId, actId, tempState,
                                              finalState, scale)
            status, minCost, new_parentState, org_parentState = graph.minCostIdx(
                step_d, explore)
            if (status):
                parentState = new_parentState
                parentNode = threshold_state(parentState)
                map1.grid[parentNode[0], parentNode[1], 0] = 255
                map1.grid[parentNode[0], parentNode[1], 1] = 0
                map1.grid[parentNode[0], parentNode[1], 2] = 0
                parentCost = graph.cost2come[parentNode[0], parentNode[1]]
            parent_ownId = graph.visit(parentNode, parentState)
            # cv2.imwrite('gridExplored.jpg',map1.grid)
            if exp:
                tempVisit[:, :, 2] = graph.visited * 120
                vw2.write(tempVisit)
            reached = goalReached(parentState, finalState)
            if (reached):
                found = True
                print('Solved')
                break
        else:
            lenRemain = graph.removeLastState()
            if lenRemain:
                parentState = graph.getStates(-1)
                parentNode = threshold_state(parentState)
                parentCost = graph.cost2come[parentNode[0], parentNode[1]]
                parent_ownId = graph.getOwnId(parentNode)
            else:
                print('No solution exist, terminating....')
                count = 1
                return actionSet, -1
    if exp:
        vw.release()
        vw2.release()
    cv2.imwrite('gridExplored.jpg', map1.grid)
    plt.imshow(map1.grid)
    plt.show()
    plt.pause(0.0001)
    print("Time explored = %2.3f seconds " % (time.time() - start_time))
    map2 = cv2.imread('gridExplored.jpg')
    map3 = cv2.imread('grid_init.jpg')

    if (not count):
        reached_state = graph.getStates(int(len(graph.allStates)) - 1)
        reached_node = threshold_state(reached_state)
        ans = graph.getOwnId(reached_node)
        print '\nYellow area shows all the obstacles and White area is the free space'
        print 'Blue color show all the explored Nodes (area)'
        print 'Red line shows optimal path (traced from start node to final node)'

    allNodes = []
    nextState = graph.getStates(ans)
    nextNode = threshold_state(nextState)
    g_actId = graph.actDone[nextNode[0], nextNode[1]]
    allNodes.append(nextNode)
    actionSet.append(g_actId)
    while (ans != 0 and count == 0):
        startState = nextState
        startNode = nextNode
        ans = graph.getParentId(startNode)
        nextState = graph.getStates(ans)
        nextNode = threshold_state(nextState)
        g_actId = graph.actDone[nextNode[0], nextNode[1]]
        allNodes.append(nextNode)
        actionSet.append(g_actId)
    idx = len(allNodes) - 1
    vw1 = cv2.VideoWriter('Vid_backTrack_on_explored.avi', fourcc, 10.0,
                          (501, 501))
    vw2 = cv2.VideoWriter('Vid_backTrack.avi', fourcc, 10.0, (501, 501))
    while idx > 0:
        startNode = allNodes[idx]
        nextNode = allNodes[idx - 1]
        idx -= 1
        cv2.line(map2, (startNode[1], startNode[0]),
                 (nextNode[1], nextNode[0]), (0, 0, 255), 1)
        cv2.line(map3, (startNode[1], startNode[0]),
                 (nextNode[1], nextNode[0]), (0, 0, 255), 1)
        vw1.write(map2)
        vw2.write(map3)
    vw1.release()
    vw2.release()
    plt.imshow(map2)
    plt.show()
    plt.pause(0.0001)
    cv2.imwrite('back_tracking_explored.jpg', map2)
    cv2.imwrite('back_tracking.jpg', map3)
    if (count == 0):
        actionSet.reverse()
    input('Path computed: ')
    plt.ioff()
    return actionSet, step_d
Ejemplo n.º 3
0
    def natneigh(self, anisotropy=1.0, smoothie=0, plane='sn', plot=False):
        """
        Performs Natural Neighbor (NN) interpolation with defined anisotropy 
        to the instance's data. The algorithm assumes a brute-force way of 
        calculating the Voronoi cells every time an unsampled point's value is
        computed.
        
        Kwargs: anisotropy <float>  : anisotropy parameter: if >1.0, it brings points closer in the
                                      longitudinal (s) direction, if <1.0 it brings points closer 
                                      in the transverse (n) direction
                smoothie <int>      : smoothing degree (Gaussian window)
                plane <str>         : chooses plane for interpolation; 'xy' for Cartesian, 'sn' for flow-oriented
                plot <boolean>      : decides to plot or not the resulting NN values
        """

        from scipy.spatial import voronoi_plot_2d
        import matplotlib.pyplot as plt

        gc.enable()
        print "Calculating: Natural Neighbour [NN]"

        nn = deepcopy(self.z)  #avoid overwrite

        #choose plane
        if plane == 'sn':
            x = self.s * 1. / anisotropy  #already flattened
            y = self.n  #already flattened
        elif plane == 'xy':
            x = self.x.flatten() * 1. / anisotropy
            y = self.y.flatten()
        else:
            print "Error: Plane for interpolation not correctly specified. No interpolation performed."
            return

        #DEFINE BOUNDARY FOR INTERPOLATION
        #griddify points to choose boundary easier:
        Gx = common.to_grid(x, self.rows, self.cols)
        Gy = common.to_grid(y, self.rows, self.cols)
        bx = np.hstack((Gx[0, :], Gx[1:-1, -1], Gx[-1, :][::-1], Gx[1:-1,
                                                                    0][::-1]))
        by = np.hstack((Gy[0, :], Gy[1:-1, -1], Gy[-1, :][::-1], Gy[1:-1,
                                                                    0][::-1]))
        #define boundary:
        boundary = np.array(zip(bx, by))

        #VORONOI OF SAMPLED DATA POINTS:
        vorpoints = np.array(zip(x[self.isdata], y[self.isdata]))
        #shift points around central point of the dataset (for precision purposes)
        center = vorpoints.mean(axis=0)
        vorpoints -= center
        #construct Voronoi diagram from (centered) sampled data points
        vor = Voronoi(vorpoints)
        vor.close()
        """
        #TODO: delete:
        voronoi_plot_2d(vor)
        plt.ion()
        plt.axis('equal')
        plt.show()
        """
        #calculate areas of sampled dataset Voronoi cells
        original_areas, vor = self.__find_areas(vor, boundary - center)
        """
        #TODO: delete:        
        # colorize
        for region in vor.regions[1:]:
            polygon = vor.vertices[region]
            plt.fill(*zip(*polygon), alpha=0.4)
        plt.plot(vorpoints[:,0], vorpoints[:,1], 'ko')
        plt.xlim(vor.min_bound[0] - 0.1, vor.max_bound[0] + 0.1)
        plt.ylim(vor.min_bound[1] - 0.1, vor.max_bound[1] + 0.1)
        plt.axis('equal')
        plt.ion()
        plt.show()
        """

        #ITERATE THROUGH UNSAMPLED DATA POINTS:
        # ~ For each unsampled point, construct the new Voronoi diagram consisting of the
        # ~ sampled data and the current unsampled point. Then calculate the new areas and
        # ~ find the normalized weights based on how much of each area is "stolen away" from
        # ~ each sampled dataset Voronoi cell (https://en.wikipedia.org/wiki/Natural_neighbor).
        # ~ The areas are always bounded by the river polygon (based on the grid defined).
        unknown = []
        for i in range(len(x[self.nodata])):
            if i % 1000 == 0:
                print i, "out of ", len(x[self.nodata])
            #add new point shifted around central point
            varys = np.vstack((vorpoints, [
                x[self.nodata][i] - center[0], y[self.nodata][i] - center[1]
            ]))

            #calculate new Voronoi
            pntvor = Voronoi(varys)
            pntvor.close()

            #calculate areas
            new_areas, pntvor = self.__find_areas(pntvor, boundary - center)
            new_areas = new_areas[:-1]  #exclude new point's area
            w = new_areas / original_areas
            w[w >
              1.0] = 1.0  #make sure that no area is larger than initial areas
            areaweight = 1.0 - w
            normalize = np.nansum(areaweight)
            if normalize == 0.0:  #to avoid division by 0
                normalize = 1e-12
            areaweight /= normalize
            unknown.append(np.nansum(areaweight * self.z[self.isdata]))

        nn[self.nodata] = np.array(unknown)

        #grid (matrix) notation
        nn = common.to_grid(nn, self.rows, self.cols)
        #add pre-defined banks
        nn = self.__add_banks(nn)
        #smoothen
        for i in range(self.rows):
            nn[i, :] = common.smooth(nn[i, :], smoothie)
        print "Finished [NN]."
        self.z_interpol = nn
        del nn
        #plot
        if plot:
            self.plot(fignum='NN')
class Ingot:
    def __init__(self, hx=0, hy=0, x=[], y=[]):
        # размеры
        self.hx, self.hy = self.h = (hx, hy)
        # приблизительная длина стороны квадрата
        # в котором в среднем есть одна точка
        self.num=num=math.sqrt(hx*hy/len(x))    
        # формирую узлы с шагом num
        # по осям
        d_x=list(np.arange(-num,hx+2*num,num))    
        d_y=list(np.arange(-num,hy+2*num,num))
        # формируем границу, с ней будет удобнее контроллировать граничные условия
        granica=[d_x*2+[-num]*(len(d_y)-2)+[hx+num]*(len(d_y)-2),
            [-num]*len(d_x)+[hy+num]*len(d_x)+d_y[1:-1]*2]
        # координаты всех узлов, и граничных и внутренних. Какие из них какими
        # будут, выяснится после построения диаграммы Вороного
        self.x, self.y = [list(x)+granica[0],list(y)+granica[1]]
        # центр слитка
        self.materialcentercell = self.getcellinarea((hx/2-num,hx/2+num),(hy/2-num,hy/2+num))
        # количество ячеек, клеток.
        self.cellsnumber = cellsnumber = len(self.x)
        # строим диаграмму Вороного
        self.voron = Voronoi(np.array([self.x,self.y]).transpose())
        # в этом массиве будет инофрмация о соседях для каждой клетки
        self.neighbours=[]
        # здесь будут хранится для каждой клетки расстояния до соседей
        self.distances_to_neighbours=[]
        # пока все клетки внутренние
        # для каждой точки 0-внутренняя, 1-граничная
        self.borders=[0]*cellsnumber
        # здесь будут храниться для каждой клетки площади поверхностей соприкосновения с соседними
        self.contact_surface_area=[]
        # для вычисления условия сходимости
        self.sumcontactareadevideddistance=[math.inf]*cellsnumber 
        # полная площадь соприкосновения каждой ячейки с другим ячейками
        self.complete_cell_surface_area=[math.inf]*cellsnumber # площадь поверхности клетки
        # объем ячейки, по умолчанию -1=infinite
        self.volume=[-1]*cellsnumber
        # инициализируем массивы для списков соседей, растояний до них, и площади соприкосновения
        for i in range(cellsnumber):
            self.neighbours.append([])
            self.distances_to_neighbours.append([])
            self.contact_surface_area.append([])
        #  находим для каждой точкие его соседей
        for i in self.voron.ridge_points:
            self.neighbours[i[0]].append(i[1])
            self.neighbours[i[1]].append(i[0])
        # находим для каждой точки расстояния до его соседей и площади поверхностей
        # соприкосновения с ячейками соседей. Соседей перечисляем
        # согласно последовательности списка в neighbours
        for i in range(len(self.neighbours)):
            # Ищем объем ячейки, если она конечная, если бесконечная, то граница
            xx=[]
            yy=[]
            flag=0 # по умолчанию точка внутренняя
            for vert in self.voron.regions[self.voron.point_region[i]]:
                xx.append(self.voron.vertices[vert][0])
                yy.append(self.voron.vertices[vert][1])
                if vert==-1:
                    flag=1 # значит точка граничная
                    self.borders[i]=1 # запомним, что граничная
            if flag==0:
                self.volume[i]=PolyArea(xx,yy)
                self.mass[i]=self.ro()*self.volume[i]
                # клетка i неграничная -> считаем позже площадь поверхности
                # перед этим площадь math.inf переводим в 0.
                self.complete_cell_surface_area[i]=0
                self.sumcontactareadevideddistance[i]=0
        # закончили вычислять объемы (размеры) ячеек
            for ii in range(len(self.neighbours[i])):
                # ищем расстояния
                self.distances_to_neighbours[i].append(\
                    euklid_distance(\
                    (self.x[i],self.y[i]),\
                    (self.x[self.neighbours[i][ii]],self.y[self.neighbours[i][ii]])\
                    ))
                # ищем площади поверхностей (граней) касания
                # слабое место, поскольку свойство ridge_dict не описано в документации
                # но фактически есть и как раз то, что мне здесь нужно.
                # ridge_dict - словарь, ключь - пары соседних в диаграмме points,
                # значение - пары vertices вершин - концов перпендикулярного ребра
                temp1=(i,self.neighbours[i][ii])
                temp2=(self.neighbours[i][ii],i)
                tmp_vertices = []
                if temp1 in self.voron.ridge_dict:
                    tmp_vertices=self.voron.ridge_dict[temp1]
                elif temp2 in self.voron.ridge_dict:
                    tmp_vertices=self.voron.ridge_dict[temp2]
                if -1 in tmp_vertices: # бесконечно ли ребро
                    self.contact_surface_area[i].append(math.inf)
                else:
                    self.contact_surface_area[i].append(\
                        euklid_distance(\
                        self.voron.vertices[tmp_vertices[0]],\
                        self.voron.vertices[tmp_vertices[1]]\
                        ))
                self.complete_cell_surface_area[i]+=self.contact_surface_area[i][ii]
                self.sumcontactareadevideddistance[i]+=(self.contact_surface_area[i][ii]/self.distances_to_neighbours[i][ii])
            if self.sumcontactareadevideddistance[i]==self.mass[i]==math.inf:
                self.sumcontactareadevideddistance[i]=math.inf
            else:
                self.sumcontactareadevideddistance[i]/=self.mass[i]
            
        self.polygons =[] # строим полигоны, которые поместим потом на рисунок
        self.markphase=[] # точка в центре полигона, маркер ликвидуса/солидуса
        
        # физические парметры слитка для возможного анализа        
        self.materialmass = sum(filter(lambda x:x<math.inf,self.mass)) # фактическая масса слитка
        self.maxcellmass = max(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка
        self.mincellmass = min(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка
        self.materialvolume = sum(filter(lambda x:x>0,self.volume)) # фактическая ... слитка
        self.mincellvolume = min(filter(lambda x:x>0,self.volume)) # фактическая ... слитка
        self.maxcellvolume = max(filter(lambda x:x>0,self.volume)) # фактическая ... слитка
        self.mindistance=min(list(map(min,self.distances_to_neighbours)))
        self.maxdistance=max(list(map(max,self.distances_to_neighbours)))
        self.maxcellsurfacearea=max(filter(lambda x:x<math.inf,self.complete_cell_surface_area))
        self.mincellsurfacearea=min(filter(lambda x:x<math.inf,self.complete_cell_surface_area))
        suftemp=max(filter(lambda x:x<math.inf,self.sumcontactareadevideddistance))
        self.sufficientstabilitycondition_dt=(self.c()/self.k(0))/suftemp

        # 0.97 чтобы чуточку меньше взять, чем позволено рассуждениями
        self.dt = 0.99 * self.sufficientstabilitycondition_dt # in seconds
        self.life = 0
        self.CellProtocolTime=[]   # здесь запоманаем возраст и температуру
        self.CellProtocolT =[]     # какой-нибудь клетки
        self.voron.close() # больше точек не добавляем
        self.ax = [] 
        self.pathx=[] # для рисунка полигонов
        self.pathy=[] # для рисунка полигонов
        for i in range(len(self.voron.point_region)):
            self.pathx.append([])
            self.pathy.append([])
            if self.voron.regions[self.voron.point_region[i]].count(-1)==0\
                and len(self.voron.regions[self.voron.point_region[i]])>0:
                for ii in self.voron.regions[self.voron.point_region[i]]:
                    self.pathx[i].append(self.voron.vertices[ii][0])
                    self.pathy[i].append(self.voron.vertices[ii][1])
        self.flag_fig=0
#        fignumber=fignumber+1
#        self.fig=plt.figure(fignumber, figsize=(10,10))
        self.flag_printtcircle=0
#        self.flag_nexttime=0
        self.flag_plotpolygon=0
        self.ax_printtcircle=0
        self.ax_nexttime=0
    def initpolygons(self):
        for i in range(len(self.pathx)):
            self.markphase.append([])
            self.polygons.append([])
            if len(self.pathx[i])>0:
                self.polygons[i]=\
                patches.Polygon(np.asarray([self.pathx[i],self.pathy[i]]).transpose(),\
                color=self.colormap.to_rgba(self.T[i]))
                self.markphase[i]=plt.Line2D\
                ([self.voron.points[i][0]],[self.voron.points[i][1]],marker=',',color='white')
#                self.polygons[i].set_alpha(self.alpha0)
#        self.flag_plotpolygon=1 # ставим флаг
        self.ax_nexttime=self.initfig() # инициализируем рисунок (axe)
        for i in range(len(self.polygons)):
            if self.polygons[i]!=[]:
                self.ax_nexttime.add_patch(self.polygons[i])
                self.ax_nexttime.add_line(self.markphase[i])
#        ppl.colorbar.ColorbarBase(self.ax_nexttime,cmap=self.cmap, norm=self.tcnorm)
    def initfig(self):
#        global fignumber
        if self.flag_fig==0:
            self.flag_fig=1
            temp=plt.get_fignums()
            temp.append(0)
            fignumber=max(temp)+1
            self.fig = plt.figure(fignumber, figsize=(10,10))
            self.fig.clf()
        ax = self.fig.add_axes([0.05, 0.05, 0.7,0.9],axisbg='w',aspect='equal')
        ax.set_xlim(-self.num,hx+self.num)
        ax.set_ylim(-self.num,hy+self.num)
        axbar=self.fig.add_axes([0.8, 0.05, 0.1,0.9])
#        axbar.set_xlim(0.8,0.1)
#        axbar.set_ylim(-self.num,hy+self.num)
#        mpl.colorbar.ColorbarBase(cax, cmap=cm, norm=norm, orientation='vertical')
        ppl.colorbar.ColorbarBase(axbar,cmap=self.cmap, norm=self.tcnorm)
        return(ax)        

    def getcellinarea(self,o1,o2):
        for i in range(len(self.x)):
            if o1[0] < self.x[i] < o1[1] and o2[0] < self.y[i] < o2[1]:
                return(i)
        return(-1)

    def Tnext(self,cell): # Meltingpoint = MP
        if self.flag_plotpolygon==0:
            self.flag_plotpolygon=1
            self.initpolygons()
        if self.borders[cell]:
            return(self.T[cell],self.cellphase[cell])
        mass=self.mass[cell] 
        phase=self.cellphase[cell]
        changephase=0
        dQ=self.dt*sum(
            list(map(
            (lambda x: self.k((self.T[self.neighbours[cell][x]]+self.T[cell])/2)*
            self.contact_surface_area[cell][x]*
            (self.T[self.neighbours[cell][x]]-self.T[cell])/
            self.distances_to_neighbours[cell][x]),
            range(len(self.neighbours[cell]))
            )))
        TnextXX=self.T[cell]+dQ/(self.c()*mass)
        # если работаем без смены фаз, то выходим
        if self.phasechange == 0: 
            return(TnextXX,0)
        # Если температура клетки ниже температуры плавления,
        # а её фаза сейчас ликвидус, вычислим next температуру в случае
        # кристаллизации
        if self.T[cell] < self.melting_point() and phase == 0:
            flag = np.random.uniform(TnextXX,TnextXX + self.mu()/self.c()) # для выбора: осуществлять ли фазовый переход
            if  flag < self.melting_point():
                changephase=1                
                phase = 1
#                self.polygons[cell].set_alpha(self.alpha1)
#                self.count=self.count+1
        # Если температура клетки выеше температуры плавления,
        # а её фаза сейчас солидус, вычислим next температуру в случае
        # плавления
        if self.T[cell] > self.melting_point() and phase == 1:
            flag = np.random.uniform(TnextXX - self.mu()/self.c(),TnextXX) # для выбора: осуществлять ли фазовый переход
            if  flag > self.melting_point():
                changephase=-1                
                phase = 0
#                self.polygons[cell].set_alpha(self.alpha0)
#                self.count1=self.count1+1
        self.cellphase[cell]=phase
        # возвращаем температуру и фазу
        return(TnextXX+changephase*self.mu()/self.c(),self.cellphase[cell])

    def nexttime(self,times):
        self.life = self.life + self.dt
        for i in range(times):
            for cell in range(len(self.T)):
                self.T1[cell]=self.Tnext(cell)[0]
            change=self.T
            self.T=self.T1
            self.T1=change
#            for cell in range(len(self.T)):
#                self.T[cell]=self.T1[cell]

    # протоколируем возраст и температуру клетки cell            
    def writeTdown(self,cell):
        self.CellProtocolTime.append(self.life)
        self.CellProtocolT.append(self.T[cell])

    # Раскрашиваем полигоны согласно температуре. Отмечаем цветом точки фазу    
    def plotpolygon(self):
        if self.flag_plotpolygon==0:
            self.flag_plotpolygon=1
            self.initpolygons()
        for cell in range(len(self.T)):
            if self.polygons[cell]!=[]:
                if self.cellphase[cell]==0:
                    self.polygons[cell].set_color(self.colormap.to_rgba(self.T[cell]))
                    self.markphase[cell].set_color('white')                    
                else:
                    self.polygons[cell].set_color(self.colormap1.to_rgba(self.T[cell]))
                    self.markphase[cell].set_color('black')                    
    # Указываем лишь только фазу
    def plotphase(self):
        if self.flag_plotpolygon==0:
            self.flag_plotpolygon=1
            self.initpolygons()
        for cell in range(len(self.T)):
            if self.polygons[cell]!=[]:
                if self.cellphase[cell]==0:
                    self.polygons[cell].set_color('white')
                else:
                    self.polygons[cell].set_color('black')

    def printtcircle(self,n):
        if self.flag_printtcircle==0:
            self.flag_printtcircle=1
            self.ax_printtcircle=self.initfig()
        temp=[]
        for i in range(n):
            for ii in range(len(self.circle)):
                for cell in self.neighbours[ii]:
                    if self.circle[cell]==self.Tmax:
                        temp.append(ii)
            for ii in temp:
                self.circle[ii]=self.Tmax
#        self.ax.clear()
#        self.ax.scatter(self.x,self.y,c=self.circle,edgecolors='None',cmap=self.cmap,marker='o',s=5)
        self.plotpolygon2(self.ax_printtcircle)

    def initT(self):
        for i in range(len(self.neighbours)):
            self.T[i]=self.Tmin
            for vert in self.voron.regions[self.voron.point_region[i]]:
                if vert==-1:
                    self.T[i]=self.Tmax

    def distance_cells(self,c1,c2):
        return(euklid_distance((self.x[c1],self.y[c1]),(self.x[c2],self.y[c2])))

    def ro(self): # [кг/м^3] плотность вещества
        return(7870)

    def c(self): # удельная теплоемкость
        # [Дж/(кг*К)] удельная теплоемкость
        return(300)

    def k(self,temp): # коэффициент теплопроводности
        # [Дж/(м*К*с)]=[Вт/(м*К)]=[кг*м^2/c^3] 50-100
        if 0<=temp<=800:
            ktemp=((temp-0)/(800-0))*(14-60)+60
        elif 800<=temp<=1520:
            ktemp=((temp-800)/(1520-800))*(34-14)+14
        elif 1520<=temp:
            ktemp=35
        return(ktemp)

    def mu(self): # теплота кристаллизации
        # [Дж/кг]
        return(220000) # сталь

    def melting_point(self):
        # [K] 1450—1520 °C для стали
        return(1500+273.15)

    def xycell(self,cell):
        return((self.x[cell],self.y[cell]))
# находит центр масс для конечного полигона  
# (ячейки, клетки и т.п. синонимов)        
    def masscenterpoints(self):
        xnew=[]
        for reg in self.voron.regions:
            tmp=[]
            if reg.count(-1)==0 and len(reg)>0:
                for i in reg:
                    tmp.append(self.voron.vertices[i])
                xnew.append(masscenter(tmp))
        return(xnew)

    def plotpolygon2(self,ax):
        ax.clear()
        for i in range(len(self.pathx)):
            if len(self.pathx[i])>0:
                ax.fill(self.pathx[i], self.pathy[i], color=self.colormap.to_rgba(self.circle[i]))