Beispiel #1
0
    def const_par_curve(self, knot, direction):
        """  Get a Curve representation of the parametric line of some constant
        knot value.
        :param float knot: The constant knot value to sample the surface
        :param int direction: The parametric direction for the constant value
        :return: curve on this surface
        :rtype: Curve
        """
        direction = check_direction(direction, 2)

        # clone basis since we need to augment this by knot insertion
        b = self.bases[direction].clone()

        # compute mapping matrix C which is the knotinsertion operator
        mult = min(b.continuity(knot), b.order - 1)
        C = np.identity(self.shape[direction])
        for i in range(mult):
            C = b.insert_knot(knot) @ C

        # at this point we have a C0 basis, find the right interpolating index
        i = max(bisect_left(b.knots, knot) - 1, 0)

        # compute the controlpoints and return Curve
        cp = np.tensordot(C[i, :], self.controlpoints, axes=(0, direction))
        return Curve(self.bases[1 - direction], cp, self.rational)
Beispiel #2
0
    def const_par_curve(self, knot, direction):
        """  Get a Curve representation of the parametric line of some constant
        knot value.
        :param float knot: The constant knot value to sample the surface
        :param int direction: The parametric direction for the constant value
        :return: curve on this surface
        :rtype: Curve
        """
        direction = check_direction(direction, 2)

        # clone basis since we need to augment this by knot insertion
        b    = self.bases[direction].clone()

        # compute mapping matrix C which is the knotinsertion operator
        mult = min(b.continuity(knot), b.order-1)
        C    = np.matrix(np.identity(self.shape[direction]))
        for i in range(mult):
            C = b.insert_knot(knot) * C

        # at this point we have a C0 basis, find the right interpolating index
        i  = max(bisect_left(b.knots, knot) - 1,0)

        # compute the controlpoints and return Curve
        cp = np.tensordot(C[i,:], self.controlpoints, axes=(1, direction))
        return Curve(self.bases[1-direction], cp, self.rational)
Beispiel #3
0
def geometric_refine(obj, alpha, n, direction=0, reverse=False):
    """geometric_refine(obj, alpha, n, [direction=0], [reverse=False])

    Refine a spline object by making a geometric distribution of element sizes.

    :param obj: The object to refine
    :type obj: :class:`splipy.SplineObject`
    :param float alpha: The length ratio between two sequential knot segments
    :param int n: The number of knots to insert
    :param direction: The direction to refine in
    :param bool reverse: Set to `True` to refine towards the other end
    """
    # some error tests on input
    if n<=0:
        raise ValueError('n should be greater than 0')

    direction = check_direction(direction, obj.pardim)
    if reverse:
        obj.reverse(direction)

    # fetch knots
    knots = obj.knots()
    knot_start = knots[direction][0]
    knot_end   = knots[direction][-1]
    dk = knot_end - knot_start

    # evaluate the factors
    n = n+1 # redefine n to be knot spans instead of new internal knots
    totProd = 1.0
    totSum  = 0.0
    for i in range(n):
        totSum  += totProd
        totProd *= alpha
    d1 = 1.0 / totSum
    knot = d1

    # compute knot locations
    new_knots = []
    for i in range(n-1):
        k = knot_start + knot*dk
        if not knot_exists(knots[direction], k):
            new_knots.append(k)
        knot += alpha*d1
        d1   *= alpha

    # do the actual knot insertion
    obj.insert_knot(new_knots, direction)

    if reverse:
        obj.reverse(direction)
    return obj
Beispiel #4
0
def geometric_refine(obj, alpha, n, direction=0, reverse=False):
    """geometric_refine(obj, alpha, n, [direction=0], [reverse=False])

    Refine a spline object by making a geometric distribution of element sizes.

    :param obj: The object to refine
    :type obj: :class:`splipy.SplineObject`
    :param float alpha: The length ratio between two sequential knot segments
    :param int n: The number of knots to insert
    :param direction: The direction to refine in
    :param bool reverse: Set to `True` to refine towards the other end
    """
    # some error tests on input
    if n <= 0:
        raise ValueError('n should be greater than 0')

    direction = check_direction(direction, obj.pardim)
    if reverse:
        obj.reverse(direction)

    # fetch knots
    knots = obj.knots()
    knot_start = knots[direction][0]
    knot_end = knots[direction][-1]
    dk = knot_end - knot_start

    # evaluate the factors
    n = n + 1  # redefine n to be knot spans instead of new internal knots
    totProd = 1.0
    totSum = 0.0
    for i in range(n):
        totSum += totProd
        totProd *= alpha
    d1 = 1.0 / totSum
    knot = d1

    # compute knot locations
    new_knots = []
    for i in range(n - 1):
        k = knot_start + knot * dk
        if not knot_exists(knots[direction], k):
            new_knots.append(k)
        knot += alpha * d1
        d1 *= alpha

    # do the actual knot insertion
    obj.insert_knot(new_knots, direction)

    if reverse:
        obj.reverse(direction)
    return obj
Beispiel #5
0
def center_refine(obj, S, n, direction=0):
    """center_refine(obj, S, n, [direction=0])

    Refine an object towards the center in a direction, by sampling an
    tan function.

    :param obj: The object to refine
    :type obj: :class:`splipy.SplineObject`
    :param float S: The slope of the tan function (range 0,pi/2)
    :param int n: The number of knots to insert
    :param direction: The direction to refine in
    """
    # some error tests on input
    if n <= 0:
        raise ValueError('n should be greater than 0')
    assert 0 < S < np.pi / 2

    direction = check_direction(direction, obj.pardim)

    # fetch knots
    knots = obj.knots()
    knot_start = knots[direction][0]
    knot_end = knots[direction][-1]
    dk = knot_end - knot_start

    # compute knot locations
    new_knots = []
    max_tan = tan(S)
    for i in range(1, n + 1):
        xi = -1.0 + 2.0 * i / (n + 1)
        xi *= S
        k = knot_start + (tan(xi) + max_tan) / 2 / max_tan * dk
        if not knot_exists(knots[direction], k):
            new_knots.append(k)

    # do the actual knot insertion
    obj.insert_knot(new_knots, direction)
    return obj
Beispiel #6
0
def edge_refine(obj, S, n, direction=0):
    """edge_refine(obj, S, n, [direction=0])

    Refine an object towards both edges in a direction, by sampling an
    arctan function.

    :param obj: The object to refine
    :type obj: :class:`splipy.SplineObject`
    :param float S: The slope of the arctan function.
    :param int n: The number of knots to insert
    :param direction: The direction to refine in
    """
    # some error tests on input
    if n<=0:
        raise ValueError('n should be greater than 0')

    direction = check_direction(direction, obj.pardim)

    # fetch knots
    knots = obj.knots()
    knot_start = knots[direction][0]
    knot_end   = knots[direction][-1]
    dk = knot_end - knot_start

    # compute knot locations
    new_knots = []
    max_atan  = atan(S)
    for i in range(1,n+1):
        xi  = -1.0 + 2.0*i/(n+1)
        xi *= S
        k   = knot_start + (atan(xi)+max_atan)/2/max_atan*dk
        if not knot_exists(knots[direction], k):
            new_knots.append(k)

    # do the actual knot insertion
    obj.insert_knot(new_knots, direction)
    return obj