Esempio n. 1
0
 def test_arc_derivative_1(self):
     pt1 = (-5, 0, 0)
     pt2 = (-4, 3, 0)
     pt3 = (-3, 4, 0)
     eq = circle_by_three_points(pt1, pt2, pt3)
     circle = SvCircle.from_equation(eq)
     dv = circle.tangent(0)
     expected = np.array([0, 5, 0])
     self.assert_numpy_arrays_equal(dv, expected, precision=8)
Esempio n. 2
0
 def test_arc_values_1(self):
     pt1 = np.array((-4, 2, 0))
     pt2 = np.array((0, 2.5, 0))
     pt3 = np.array((4, 2, 0))
     eq = circle_by_three_points(pt1, pt2, pt3)
     circle = SvCircle.from_equation(eq)
     res1 = circle.evaluate(0)
     self.assert_numpy_arrays_equal(res1, pt1, precision=6)
     t_max = eq.arc_angle
     res2 = circle.evaluate(t_max)
     self.assert_numpy_arrays_equal(res2, pt3, precision=6)
Esempio n. 3
0
def nurbs_revolution_surface(curve,
                             origin,
                             axis,
                             v_min=0,
                             v_max=2 * pi,
                             global_origin=True):
    my_control_points = curve.get_control_points()
    my_weights = curve.get_weights()
    control_points = []
    weights = []

    any_circle = SvCircle(Matrix(), 1)
    any_circle.u_bounds = (v_min, v_max)
    any_circle = any_circle.to_nurbs()
    # all circles with given (v_min, v_max)
    # actually always have the same knotvector
    # and the same number of control points
    n = len(any_circle.get_control_points())
    circle_knotvector = any_circle.get_knotvector()
    circle_weights = any_circle.get_weights()

    # TODO: vectorize with numpy? Or better let it so for better readability?
    for my_control_point, my_weight in zip(my_control_points, my_weights):
        eq = CircleEquation3D.from_axis_point(origin, axis, my_control_point)
        if abs(eq.radius) < 1e-8:
            parallel_points = np.empty((n, 3))
            parallel_points[:] = np.array(eq.center)  #[np.newaxis].T
        else:
            circle = SvCircle.from_equation(eq)
            circle.u_bounds = (v_min, v_max)
            nurbs_circle = circle.to_nurbs()
            parallel_points = nurbs_circle.get_control_points()
        parallel_weights = circle_weights * my_weight
        control_points.append(parallel_points)
        weights.append(parallel_weights)
    control_points = np.array(control_points)
    if global_origin:
        control_points = control_points - origin

    weights = np.array(weights)
    degree_u = curve.get_degree()
    degree_v = 2  # circle

    return SvNurbsSurface.build(curve.get_nurbs_implementation(), degree_u,
                                degree_v, curve.get_knotvector(),
                                circle_knotvector, control_points, weights)
Esempio n. 4
0
def extend_curve(curve,
                 t_before,
                 t_after,
                 mode='LINE',
                 len_mode='T',
                 len_resolution=50):
    def make_line(point, tangent, t_ext, sign):
        if sign < 0:
            before_start = point - t_ext * tangent  # / np.linalg.norm(tangent_start)
            return SvLine.from_two_points(before_start, point)
        else:
            after_end = point + t_ext * tangent  # / np.linalg.norm(tangent_end)
            return SvLine.from_two_points(point, after_end)

    u_min, u_max = curve.get_u_bounds()
    start, end = curve.evaluate(u_min), curve.evaluate(u_max)
    start_extent, end_extent = None, None
    is_nurbs = isinstance(curve, SvNurbsCurve)

    if mode == 'LINE':
        tangent_start = curve.tangent(u_min)
        tangent_end = curve.tangent(u_max)

        if t_before > 0:
            start_extent = make_line(start, tangent_start, t_before, -1)
            start_extent = set_length(curve,
                                      start_extent,
                                      t_before,
                                      -1,
                                      len_mode=len_mode,
                                      len_resolution=len_resolution)
        if t_after > 0:
            end_extent = make_line(end, tangent_end, t_after, +1)
            end_extent = set_length(curve,
                                    end_extent,
                                    t_after,
                                    +1,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    elif mode == 'ARC':
        tangent_start = curve.tangent(u_min)
        tangent_end = curve.tangent(u_max)
        second_start = curve.second_derivative(u_min)
        second_end = curve.second_derivative(u_max)

        if t_before > 0:
            if np.linalg.norm(second_start) > 1e-6:
                eq1 = circle_by_two_derivatives(start, -tangent_start,
                                                second_start)
                start_extent = SvCircle.from_equation(eq1)
                start_extent = set_length(curve,
                                          start_extent,
                                          t_before,
                                          -1,
                                          len_mode=len_mode,
                                          len_resolution=len_resolution)
                if is_nurbs:
                    start_extent = start_extent.to_nurbs()
                start_extent = reverse_curve(start_extent)
            else:
                start_extent = make_line(start, tangent_start, t_before, -1)
                start_extent = set_length(curve,
                                          start_extent,
                                          t_before,
                                          -1,
                                          len_mode=len_mode,
                                          len_resolution=len_resolution)

        if t_after > 0:
            if np.linalg.norm(second_end) > 1e-6:
                eq2 = circle_by_two_derivatives(end, tangent_end, second_end)
                end_extent = SvCircle.from_equation(eq2)
            else:
                end_extent = make_line(end, tangent_end, t_after, +1)
            end_extent = set_length(curve,
                                    end_extent,
                                    t_after,
                                    +1,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    elif mode == 'QUAD':
        tangent_start = curve.tangent(u_min)
        tangent_end = curve.tangent(u_max)
        second_start = curve.second_derivative(u_min)
        second_end = curve.second_derivative(u_max)

        if t_before > 0:
            start_extent = SvTaylorCurve(start, [-tangent_start, second_start])
            start_extent = set_length(curve,
                                      start_extent,
                                      t_before,
                                      len_mode=len_mode,
                                      len_resolution=len_resolution)
            if is_nurbs:
                start_extent = start_extent.to_nurbs()
            start_extent = reverse_curve(start_extent)

        if t_after > 0:
            end_extent = SvTaylorCurve(end, [tangent_end, second_end])
            end_extent = set_length(curve,
                                    end_extent,
                                    t_after,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    elif mode == 'CUBIC':
        tangent_start = curve.tangent(u_min)
        tangent_end = curve.tangent(u_max)
        second_start = curve.second_derivative(u_min)
        second_end = curve.second_derivative(u_max)
        third_start, third_end = curve.third_derivative_array(
            np.array([u_min, u_max]))

        if t_before > 0:
            start_extent = SvTaylorCurve(
                start, [-tangent_start, second_start, -third_start])
            start_extent = set_length(curve,
                                      start_extent,
                                      t_before,
                                      len_mode=len_mode,
                                      len_resolution=len_resolution)
            if is_nurbs:
                start_extent = start_extent.to_nurbs()
            start_extent = reverse_curve(start_extent)
        if t_after > 0:
            end_extent = SvTaylorCurve(end,
                                       [tangent_end, second_end, third_end])
            end_extent = set_length(curve,
                                    end_extent,
                                    t_after,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    else:
        raise Exception("Unsupported mode")

    if is_nurbs:
        if start_extent is not None and not isinstance(start_extent,
                                                       SvNurbsCurve):
            start_extent = start_extent.to_nurbs(
                implementation=curve.get_nurbs_implementation())
        if end_extent is not None and not isinstance(end_extent, SvNurbsCurve):
            end_extent = end_extent.to_nurbs(
                implementation=curve.get_nurbs_implementation())

    return start_extent, end_extent