예제 #1
0
    def __init__(self, filament, order, *args, **keyargs):
        """
            コンストラクタ

            初期化時に呼ばれる
            引数:
                filament: 粒子を内包するフィラメントのインスタンス
                order:  フィラメント内の順番
        """
        # 内部のインスタンスへ引数のリンクを保存
        self.order = order
        self.filament = filament
        # フィラメントを内包する培地インスタンスのリンクを保存
        self.medium = self.filament.medium
        
        # 先頭粒子か後続粒子か
        if self.is_head():
            # 配置時の向きはランダム
            init_pos_th = random.random() * (2*math.pi) - math.pi
            # 配置時の場所はfilament_init_rangeの範囲内
            init_pos_r  = random.random() * config.getfloat("lc","filament_init_range")
            self.x  = self.n_x  = math.cos(init_pos_th) * init_pos_r
            self.y  = self.n_y  = math.sin(init_pos_th) * init_pos_r
            self.th = self.n_th = random.random() * (2*math.pi) - math.pi
            # 速度はinit_verocityに従う
            self.v  = self.n_v  = config.getfloat("lc","init_verocity")
        else:
            # 後続粒子は1つ前の粒子に追従する
            self.x   = self.n_x  = self.prev().x
            self.y   = self.n_y  = self.prev().y
            self.th  = self.n_th = self.prev().th
            self.v   = self.n_v  = self.prev().v
        
        self.w = 0.0 # 角速度を初期化
예제 #2
0
 def factory(self):
     for p in self.particles:
         p.factory()
     if len(self.particles) > config.getfloat("lc","filament_init_length") and random.random() < (config.getfloat("lc","division_rate")/self.medium.filament_num):
         self.division()
     if random.random() < (config.getfloat("lc","growth_rate")/self.medium.filament_num):
         self.growth()
     if random.random() < (config.getfloat("lc","switch_rate")/self.medium.filament_num):
         self.switch()
예제 #3
0
    def interact_neighborhood(self):
        """
            近傍粒子との相互作用を行う
        """
        neighborhoods = []  # 近傍粒子へのリンクを格納するテンポラリ
        # 角速度=後続粒子の向きの変化量の平均
        # curv_sin_sum,curv_cos_sumは平均を取るための合計値を格納するテンポラリ
        curv_sin_sum = 0.0  # sin値の合計  
        curv_cos_sum = 0.0  # cos値の合計
        # 培地内のすべてのフィラメントのすべての粒子を総覧
        for f in self.medium.filaments:
            for p in f.particles:
                dx = math.fabs(self.x - p.x)
                dy = math.fabs(self.y - p.y)
                dl = math.sqrt(math.pow(dx,2) + math.pow(dy, 2))
                # 近傍範囲内の粒子ならテンポラリにリンクを格納
                if dl < config.getfloat("lc","neighbor_range"):
                    neighborhoods.append(p)
                # この粒子の同一フィラメント内の他の粒子の場合、
                # 角速度とする粒子数の範囲内で
                # テンポラリの合計値を更新する
                if f == self.filament and p.order < config.getfloat("lc","angle_ave_step"):
                    # 変化量のsin,cos値の合計をとる
                    curv_sin_sum = curv_sin_sum + math.sin(p.w)
                    curv_cos_sum = curv_cos_sum + math.cos(p.w)
        
        # 近傍粒子の計算
        th_sin_sum = 0.0    # 近傍粒子の向きのsin値合計
        th_cos_sum = 0.0    # 近傍粒子の向きのcos値合計
        for p in neighborhoods:
            # ラジアンの合計値を計算するために符号を調整
            # 向き同士の成す角が鈍角なら向きを反転する必要がある
            if math.cos(self.th - p.th) < 0:
                th_sin_sum = th_sin_sum - math.sin(p.th)
                th_cos_sum = th_cos_sum - math.cos(p.th)
            else:
                th_sin_sum = th_sin_sum + math.sin(p.th)
                th_cos_sum = th_cos_sum + math.cos(p.th)
        # 近傍粒子の向きの合計値から平均値を計算
        th_sin_ave = th_sin_sum / len(neighborhoods)
        th_cos_ave = th_cos_sum / len(neighborhoods)
        # 平均値からこの粒子の次の向きを計算
        candidate_th = math.atan2(th_sin_ave, th_cos_ave)

        # 角速度を計算するため、後続粒子の平均とする範囲内の粒子の、
        # 角度変化量の平均を計算する
        curv_sin_ave = curv_sin_sum / config.getfloat("lc","angle_ave_step")
        curv_cos_ave = curv_cos_sum / config.getfloat("lc","angle_ave_step")
        curv_ave = math.atan2(curv_sin_ave, curv_cos_ave)
        
        # ガウス分布に従う摂動を計算する
        rand = random.gauss(curv_ave*config.getfloat("lc","amplitude_rate"), config.getfloat("lc","amplitude_std"))
        
        # 次の向きに摂動を加える
        candidate_th = candidate_th + rand
        self.drive(candidate_th, self.v)
예제 #4
0
 def __init__(self, *args, **keyargs):
     self.filament_num = config.getfloat("lc","filament_init_num")
     for i in range(config.getint("lc","filament_init_num")):
         self.setout()