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)
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)
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
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
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
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