コード例 #1
0
ファイル: cs_method.py プロジェクト: epsilony/imptri
    def first_triangle(self, p0, c0):
        self.ale.clear()
        self.triangles.clear()
        self.points.clear()

        n = norm_vec(self.func_gd(p0))
        if n[1] > 0.5 or n[0] > 0.5:
            tg_vec = np.array((n[1], -n[0], 0))
        else:
            tg_vec = np.array((-n[2], 0, n[0]))
        tg_vec = norm_vec(tg_vec)
        vinit = np.cross(tg_vec, n)
        radius = self.estimate_spining_radius(p0 - tg_vec * c0 * 0.5, p0 + tg_vec * c0 * 0.5, vinit, c0)
        p1 = self.search_on_plane(p0, radius, tg_vec, vinit)
        plane_norm = p1 - p0
        vinit = np.cross(plane_norm, n)
        radius = self.estimate_spining_radius(p0, p1, vinit, vec_len(plane_norm))
        p2 = self.search_on_plane((p0 + p1) * 0.5, radius, plane_norm, vinit)
        self.points.extend((p0, p1, p2))
        self.triangles.append((0, 2, 1))
        e0 = _WingedEdge(p0, p1, 0, 1, p2)
        e1 = _WingedEdge(p1, p2, 1, 2, p0)
        e2 = _WingedEdge(p2, p0, 2, 0, p1)
        e0.pred = e2
        e0.succ = e1
        e1.pred = e0
        e1.succ = e2
        e2.pred = e1
        e2.succ = e0
        self.ale.extend((e0, e1, e2))
コード例 #2
0
ファイル: tools_test.py プロジェクト: epsilony/imptri
def test_norm_vec():
    while True:
        vec = random_vec(100)
        if vec_len(vec) != 1:
            break
    normed_vec = norm_vec(vec)
    feqok_(np.dot(normed_vec, normed_vec), 1, 1e-6)
コード例 #3
0
ファイル: cs_method.py プロジェクト: epsilony/imptri
    def _search_root_on_plane(self, p_init, plane_norm, normed=True):

        # MARK: alpha_n_assuming see also self.edge_polygon
        # in Cermak2005 it is not directly presented
        # that grd should in the circle plan,
        # but the Neighborhood test in S7.1 assumed that.
        if not normed:
            plane_norm = norm_vec(plane_norm)
        
        grd = self.func_gd(p_init)
        grd = projection_to_plan(grd, plane_norm)
        func_val = self.func(p_init)
        delta = self.line_search_dlt * -cmp(func_val, 0)
        delta = delta * grd
        pnew2 = p_init + delta
        func_val2 = self.func(pnew2)
        pnew = p_init

        while func_val * func_val2 > 0:
            pnew = pnew2
            pnew2 = pnew + delta
            func_val = func_val2
            func_val2 = self.func(pnew2)

        rslt = brentq(lambda t: self.func(pnew * (1 - t) + pnew2 * t),
                      0, 1)
        pnew = pnew * (1 - rslt) + pnew2 * rslt
        return pnew
コード例 #4
0
ファイル: cs_method.py プロジェクト: epsilony/imptri
 def check_alpha_err(self, grd, pnew, normed=True):
     if normed:
         grdnew = norm_vec(self.func_gd(pnew))
         if intersec_angle(grdnew, grd, True) < self._alpha_err:
             return True
     else:
         grdnew = self.func_gd(pnew)
         if intersec_angle(grdnew, grd) < self._alpha_err:
             return True
     return False
コード例 #5
0
ファイル: cs_method.py プロジェクト: epsilony/imptri
    def spining_search(
        self,
        center,
        radius,
        plane_norm,
        vinit
        ):
        """ edge spinning method
        
        p1->p2 is the activate edge,
        grd_old is the triangle normal vector, no need with length 1
        c the circle radius for estimation spining circle radius"""

        # MARK: alpha_n_assuming see self.edge_polygon
        # Estimation of the circle radius(S6.1), radius

        # edge spin root finding (S6.2)
        #   determine init point pnew, init search direction of rotation

        vinit = norm_vec(vinit)
        vnew = vinit * radius
        pnew = center + vnew
        rot_mat = rotation_array(self.dlt_alpha, plane_norm)
        vnew2 = rot_mat.dot(vnew)
        pnew2 = vnew2 + center
        func_val2 = self.func(pnew2)
        func_val = self.func(pnew)
        delta = self.dlt_alpha
        if abs(func_val2) > abs(func_val) and func_val2 * func_val > 0 :
            delta = -delta
            rot_mat = rotation_array(-self.dlt_alpha, plane_norm)
            vnew2 = rot_mat.dot(vnew)
            pnew2 = vnew2 + center
            func_val2 = self.func(pnew2)
        alpha = delta

        #   find the sign different interval
        while func_val * func_val2 > 0:
            func_val = func_val2
            vnew2 = rot_mat.dot(vnew2)
            pnew = pnew2
            pnew2 = vnew2 + center
            func_val2 = self.func(pnew2)
            alpha += delta
            if abs(alpha) > self.alpha_lim:
                return None

        #   interval search( not bisection search!!!
            # that's different to Cermak2005)

        rslt = brentq(lambda t: self.func(pnew * (1 - t) + pnew2 * t),
                      0, 1)
        pnew = pnew * (1 - rslt) + pnew2 * rslt
        return pnew
コード例 #6
0
ファイル: cs_method.py プロジェクト: epsilony/imptri
 def estimate_spining_radius(self, p2, p1, vinit, c0):
     p_s = (p1 + p2) / 2.0
     vinit = norm_vec(vinit)
     pinit = p_s + vinit * c0
     grdinit = norm_vec(self.func_gd(pinit))
     rcmin = None
     for item in (p1, p2, p_s):
         item_gd = norm_vec(self.func_gd(item))
         t = rb_acos(item_gd.dot(grdinit))
         if t == 0:
             rc = self.rmax
         else:
             rc = vec_len(item - pinit) / t
         if None is rcmin or rc < rcmin:
             rc_min = rc
     rc = rc_min
     r2 = rc * self._surf_curv_coef
     if r2 < self.rmin:
         r2 = self.rmin
     elif r2 > self.rmax:
         r2 = self.rmax
     return r2