( points: Sequence[Point23Input], 
                        subdivisions:int = DEFAULT_SUBDIVISIONS, 
                        close_loop: bool=False,
                        start_tangent: Vec23 = None,
                        end_tangent: Vec23 = None)
return catmull_points
Return a smooth set of points through `points`, with `subdivisions` points 
    between each pair of control points. 
    
    If `close_loop` is False, `start_tangent` and `end_tangent` can specify 
    tangents at the open ends of the returned curve. If not supplied, tangents 
    will be colinear with first and last supplied segments

    Credit due: Largely taken from C# code at: 
    https://www.habrador.com/tutorials/interpolation/1-catmull-rom-splines/
    retrieved 20190712
Return a smooth set of points through `points`, with `subdivisions` points 
    between each pair of control points. 
    
    If `close_loop` is False, `start_tangent` and `end_tangent` can specify 
    tangents at the open ends of the returned curve. If not supplied, tangents 
    will be colinear with first and last supplied segments
Return a smooth set of points through points with subdivisions points between each pair of control points . If close_loop is False start_tangent and end_tangent can specify tangents at the open ends of the returned curve . If not supplied tangents will be colinear with first and last supplied segments
def catmull_rom_points( points: Sequence[Point23Input], 
                        subdivisions:int = DEFAULT_SUBDIVISIONS, 
                        close_loop: bool=False,
                        start_tangent: Vec23 = None,
                        end_tangent: Vec23 = None) -> List[Point3]:
    """
    Return a smooth set of points through `points`, with `subdivisions` points 
    between each pair of control points. 
    
    If `close_loop` is False, `start_tangent` and `end_tangent` can specify 
    tangents at the open ends of the returned curve. If not supplied, tangents 
    will be colinear with first and last supplied segments

    Credit due: Largely taken from C# code at: 
    https://www.habrador.com/tutorials/interpolation/1-catmull-rom-splines/
    retrieved 20190712
    """
    catmull_points: List[Point3] = []
    cat_points: List[Point3] = []
    # points_list = cast(List[Point23], points)

    points_list = list([euclidify(p, Point3) for p in points])

    if close_loop:
        cat_points = euclidify([points_list[-1]] + points_list + points_list[0:2], Point3)
    else:
        # Use supplied tangents or just continue the ends of the supplied points
        start_tangent = start_tangent or (points_list[1] - points_list[0])
        start_tangent = euclidify(start_tangent, Vector3)
        end_tangent = end_tangent or (points_list[-2] - points_list[-1])
        end_tangent = euclidify(end_tangent, Vector3)
        cat_points = [points_list[0]+ start_tangent] + points_list + [points_list[-1] + end_tangent]

    last_point_range = len(cat_points) - 3 if close_loop else len(cat_points) - 3

    for i in range(0, last_point_range):
        include_last = True if i == last_point_range - 1 else False
        controls = cat_points[i:i+4]
        # If we're closing a loop, controls needs to wrap around the end of the array
        points_needed = 4 - len(controls)
        if points_needed > 0:
            controls += cat_points[0:points_needed]
        controls_tuple = cast(FourPoints, controls)
        catmull_points += _catmull_rom_segment(controls_tuple, subdivisions, include_last)

    return catmull_points
def catmull_rom_points ( points : Sequence [ Point23Input ] , subdivisions : int = DEFAULT_SUBDIVISIONS , close_loop : bool = False , start_tangent : Vec23 = None , end_tangent : Vec23 = None ) -> List [ Point3 ] : catmull_points : List [ Point3 ] = [ ] cat_points : List [ Point3 ] = [ ] # points_list = cast(List[Point23], points) points_list = list ( [ euclidify ( p , Point3 ) for p in points ] ) if close_loop : cat_points = euclidify ( [ points_list [ - 1 ] ] + points_list + points_list [ 0 : 2 ] , Point3 ) else : # Use supplied tangents or just continue the ends of the supplied points start_tangent = start_tangent or ( points_list [ 1 ] - points_list [ 0 ] ) start_tangent = euclidify ( start_tangent , Vector3 ) end_tangent = end_tangent or ( points_list [ - 2 ] - points_list [ - 1 ] ) end_tangent = euclidify ( end_tangent , Vector3 ) cat_points = [ points_list [ 0 ] + start_tangent ] + points_list + [ points_list [ - 1 ] + end_tangent ] last_point_range = len ( cat_points ) - 3 if close_loop else len ( cat_points ) - 3 for i in range ( 0 , last_point_range ) : include_last = True if i == last_point_range - 1 else False controls = cat_points [ i : i + 4 ] # If we're closing a loop, controls needs to wrap around the end of the array points_needed = 4 - len ( controls ) if points_needed > 0 : controls += cat_points [ 0 : points_needed ] controls_tuple = cast ( FourPoints , controls ) catmull_points += _catmull_rom_segment ( controls_tuple , subdivisions , include_last ) return catmull_points