Example #1
0
def test_smallest_triangle_sphere():

    # this test is based on test_circum

    p1 = np.array((0, 0, 0))
    p2 = np.array((3, 0, 0))
    p3 = np.array((0, 4, 0))
    exp_r = 2.5
    exp_center = (1.5, 2, 0)
    tol = 1e-10
    (r, center) = smallest_triangle_sphere(p1, p2, p3)
    feqok_(exp_r, r, tol)
    iter_ = iter(exp_center)
    for item in center:
        feqok_(next(iter_), item, tol)

    p1 = np.array((0, 0, 0))
    p2 = np.array((3, -1, 0))
    p3 = np.array((0, 4, 0))
    exp_r = sqrt(34) / 2
    exp_center = (1.5, 1.5, 0)
    tol = 1e-10
    (r, center) = smallest_triangle_sphere(p1, p2, p3)
    feqok_(exp_r, r, tol)
    iter_ = iter(exp_center)
    for item in center:
        feqok_(next(iter_), item, tol)
Example #2
0
    def edge_polygon(self):
        e = self.ale.pop()
        p1 = e.start
        p2 = e.end
        p_s = (p1 + p2) / 2.0
        #grd_s = norm_vec(self.func_gd(p_s))
        pold = e.tri_pt
        v12 = p2 - p1
        grd_old = np.cross(v12, pold - p2)

        # not like Cermak2005!!!
        c0 = vec_len(grd_old) / vec_len(v12)
        vinit = np.cross(v12, grd_old)
        radius = self.estimate_spining_radius(p1, p2, vinit, c0)
        pnew = self.search_on_plane(p_s, radius, v12, vinit)
        
        v_succ = e.succ.end - e.end
        v_pred = e.start - e.pred.start
        alpha2 = intersec_angle(v_succ, -v12)
        if np.cross(v12, v_succ).dot(grd_old) > 0:
            alpha2 = 2 * pi - alpha2
        alpha1 = intersec_angle(v12, -v_pred)
        if np.cross(v_pred, v12).dot(grd_old) > 0:
            alpha1 = 2 * pi - alpha1
        alpha = min(alpha1, alpha2)

        # MARK: alpha_n_assuming the pnew made by edge_spining is on the plan P:
        #   P across the mid point of e
        #   P is perpendicular to e

        if pnew is not None:
            alpha_n = intersec_angle(pnew - p1, v12)
            alpha_shape = alpha_n + self.alpha_shape_min
        else:
            alpha_shape = self.alpha_shape_big

        # neibourhood test

        if alpha < alpha_shape:
            if e.succ.succ is e.pred:
                self.ale.remove(e.succ)
                self.ale.remove(e.pred)
                self.triangles.append((e.end_index, e.start_index, e.pred.start_index))
                return
            # situation a) in Fig8 & Fig9
            if alpha == alpha1:
                case = 1
                (r, center) = smallest_triangle_sphere(p1, p2,
                        e.pred.start)
                except_pts = (p1, p2, e.pred.start)
                check_dir = p2 - e.pred.start
                radius_check_pts = (e.pred.pred.start, e.succ.end)
            else:
                case = 2
                (r, center) = smallest_triangle_sphere(p1, p2,
                        e.succ.end)
                except_pts = (p1, p2, e.succ.end)
                check_dir = e.succ.end - p1
                radius_check_pts = (e.pred.start, e.succ.succ.end)
        elif pnew is None:
            r = vec_len(v12) * 0.5
            center = (p1 + p2) * 0.5
            except_pts = (p1, p2)
            check_dir = e
            radius_check_pts = (e.pred.start, e.succ.end)
            case = 3
        else:
            (r, center) = smallest_triangle_sphere(p1, p2, pnew)
            r = r * self.dist_test_cf
            except_pts = (p1, p2)
            check_dir = e
            radius_check_pts = (e.pred.start, e.succ.end)
            case = 4
            
        # filet out a NAEL,distance test
        emin = self._distance_test(e, r, center, check_dir, except_pts, radius_check_pts)
        if emin is e.pred.pred:
            emin = None
            case = 1
        elif emin is e.succ:
            emin = None
            case = 2
        
        if emin is None:
            if 1 == case:
                self.ale.remove(e.pred)
                self._add_tri_ale_A(e.pred, e)
            elif 2 == case:
                self.ale.remove(e.succ)
                self._add_tri_ale_A(e, e.succ)
            elif 3 == case:
                self.ale.appendleft(e)
            elif 4 == case:
                pnew_index = len(self.points)
                self.points.append(pnew)
                self.triangles.append((pnew_index, e.end_index,
                        e.start_index))
                e_new1 = _WingedEdge(e.start, pnew, e.start_index,
                        pnew_index, e.end)
                e_new2 = _WingedEdge(pnew, e.end, pnew_index,
                        e.end_index, e.start)
                e_new1.succ = e_new2
                e_new1.pred = e.pred
                e_new2.pred = e_new1
                e_new2.succ = e.succ
                e.pred.succ = e_new1
                e.succ.pred = e_new2
                self.ale.append(e_new1)
                self.ale.append(e_new2)
        else:
            emin1 = emin
            emin2 = emin.succ
            alpha_m1 = intersec_angle(emin2.end - emin2.start, e.start
                    - emin2.start)
            alpha_m2 = intersec_angle(emin1.start - emin1.end, e.end
                    - emin1.end)
            if alpha_m1 < alpha_m2:
                te = _WingedEdge(e.start, emin2.end)
                (r, center) = smallest_triangle_sphere(e.start,
                        emin2.start, emin2.end)
                except_pts = (emin2.start, emin2.end, e.start, e.end)
                radius_check_pts = (emin2.succ.end, emin1.start, e.pred.start)
            else:
                te = _WingedEdge(emin1.start, e.end)
                (r, center) = smallest_triangle_sphere(e.end,
                        emin1.start, emin1.end)
                except_pts = (emin1.start, emin1.end, e.start, e.end)
                radius_check_pts = (emin2.end, emin1.pred.start, e.succ.end)
            check_dir = te.end - te.start
            t_emin = self._distance_test(te, r, center, check_dir, except_pts, radius_check_pts)
            
            if t_emin is not None:
                self.ale.appendleft(e)
                return
            
            if alpha_m1 < alpha_m2:
                self.ale.remove(emin2)
                if emin2.succ is e.pred:
                    self.ale.remove(e.pred)
                else:
                    enew1 = _WingedEdge(
                        e.start,
                        emin2.end,
                        e.start_index,
                        emin2.end_index,
                        emin2.start,
                        e.pred,
                        emin2.succ,
                        )
                    e.pred.succ = enew1
                    emin2.succ.pred = enew1
                    self.ale.append(enew1)
                enew2 = _WingedEdge(
                    emin2.start,
                    e.end,
                    emin2.start_index,
                    e.end_index,
                    e.start,
                    emin1,
                    e.succ,
                    )
                emin1.succ = enew2
                e.succ.pred = enew2
                self.ale.append(enew2)
                self.triangles.append((emin2.end_index,
                                      emin2.start_index, e.start_index))
            else:
                self.ale.remove(emin1)
                if e.succ is emin1.pred:
                    self.ale.remove(emin1.pred)
                else:
                    enew1 = _WingedEdge(
                        emin1.start,
                        e.end,
                        emin1.start_index,
                        e.end_index,
                        emin1.end,
                        emin1.pred,
                        e.succ,
                        )
                    emin1.pred.succ = enew1
                    e.succ.pred = enew1
                    self.ale.append(enew1)
                enew2 = _WingedEdge(
                    e.start,
                    emin1.end,
                    e.start_index,
                    emin1.end_index,
                    e.end,
                    e.pred,
                    emin2,
                    )     
                e.pred.succ = enew2
                emin2.pred = enew2
                self.ale.append(enew2)
                self.triangles.append((emin1.end_index,
                        emin1.start_index, e.end_index))
            self.triangles.append((emin2.start_index, e.end_index,
                                  e.start_index))
            pass