def deriv(self, u, v, k, l, rtype='Vector', domain='local'): """ Compute the surface derivative. :param float u: Parametric point. :param float v: Parametric point. :param int k: Derivative to return in u-direction (0 <= k <= d). :param int l: Derivative to return in v-direction (0 <= l <= d). :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray'). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Surface derivative. :rtype: :class:`.Vector` or ndarray """ if self._cp is None: return None # Use NURBS rational curve derivative to compute Bezier derivative. # Convert to global since using a NURBS method. if is_local_domain(domain): u = self.local_to_global_param('u', u) v = self.local_to_global_param('v', v) d = k + l der = rat_surface_derivs(self._n, self._p, self._uk, self._m, self._q, self._vk, self._cpw, u, v, d) if is_array_type(rtype): return der[k, l] else: p0 = Point(der[0, 0]) return Vector(der[k, l], p0)
def deriv(self, u, k, d=None, rtype='Vector', domain='local'): """ Compute the *k* -th derivative at point *u*. :param float u: Parametric point. :param int k: Derivative to return (0 <= k <= d). :param int d: Highest derivative to compute. If *d* = *None*, then only the *k* th derivative will be computed. :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :return: Curve *k* -th derivative. :rtype: :class:`.Vector` or ndarray """ if self._cp is None: return None if d is None: d = k if is_local_domain(domain): u = self.local_to_global_param(u) der = rat_curve_derivs(self._n, self._p, self._uk, self._cpw, u, d) if is_array_type(rtype): return der[k] else: p0 = Point(der[0]) return Vector(der[k], p0)
def eval(self, u, v, rtype='Point', domain='local'): """ Evaluate surface at parametric points. :param float u: Parametric point in u-direction. :param float v: Parametric point in v-direction. :param str rtype: Option to return a NumPy array or Point instance (rtype = 'ndarray' or 'Point'). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Point on surface. :rtype: :class:`.Point` or ndarray """ if is_array_like(u) and is_array_like(v): return self.eval_params(u, v, rtype, domain) if is_local_domain(domain): u = self.local_to_global_param('u', u) v = self.local_to_global_param('v', v) pnt = surface_point(self._n, self._p, self._uk, self._m, self._q, self._vk, self._cpw, u, v) if is_array_type(rtype): return pnt else: return Point(pnt)
def eval_params(self, ulist, vlist, rtype='Point', domain='local'): """ Evaluate the surface at multiple parameters. :param array_like ulist: Parameters in u-direction. :param array_like vlist: Parameters in v-direction. :param str rtype: Option to return a NumPy array or Point instance (rtype = 'ndarray' or 'Point'). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Points on surface. :rtype: List :class:`.Point` instances or ndarray """ if not is_array_like(ulist) or not is_array_like(vlist): return self.eval(ulist, vlist, rtype, domain) if not is_local_domain(domain): ulist = [self.global_to_local_param('u', ui) for ui in ulist] vlist = [self.global_to_local_param('v', vi) for vi in vlist] pnts = bezier_surface_points(self._n, self._m, self._cpw, ulist, vlist) if is_array_type(rtype): return pnts else: return [Point(pi) for pi in pnts]
def eval2d(self, u, rtype='Point', domain='local', tol=None, sref=None): """ Evaluate the intersection curve in 2-D space for each surface. :param float u: Parametric point. :param str rtype: Option to return a NumPy array or Point2D instance (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :param float tol: Tolerance for point refinement. :param surface_like sref: Option to provide one of the two surfaces used in the intersection curve. If present, the method will only return the 2-D parameters associated to that surface. :return: Point on curve. Will return *None* if *sref* is not in the intersection. :rtype: :class:`.Point2D` or ndarray """ if is_local_domain(domain): u = self.local_to_global_param(u) # Evaluate 2-D curves. s1, s2 = self._s1, self._s2 u1, v1 = self._crv2d_s1.eval(u, rtype='ndarray', domain='global')[:-1] u2, v2 = self._crv2d_s2.eval(u, rtype='ndarray', domain='global')[:-1] # Project 3-D point to surfaces to get initial parameters. # s1, s2 = self._s1, self._s2 # p3d = self._crv3d.eval(u, domain='global') # u1, v1 = invert_point_on_surface(p3d, s1) # if self.is_spi: # u2, v2 = invert_point_on_plane(p3d, s2) # else: # u2, v2 = invert_point_on_surface(p3d, s2) # Refine parameters. if tol is None: tol = Settings.gtol / 100. if self.is_spi: u1, v1, u2, v2 = refine_spi_point(s1, s2, u1, v1, tol)[:-1] else: u1, v1, u2, v2 = refine_ssi_point(s1, s2, u1, v1, u2, v2, tol)[:-1] if is_array_type(rtype): if sref is s1: return array([u1, v1], dtype=float64) if sref is s2: return array([u2, v2], dtype=float64) return (array([u1, v1], dtype=float64), array([u2, v2], dtype=float64)) else: if sref is s1: return Point2D((u1, v1)) if sref is s2: return Point2D((u2, v2)) return Point2D((u1, v1)), Point2D((u2, v2))
def eval(self, u, rtype='Point', *args, **kwargs): """ Evaluate point on line. :param float u: Parameter (-inf < u < inf). :param str rtype: Option to return a NumPy array or :class:`.Point` instance (rtype = 'ndarray' or 'Point'). :return: Point on line. :rtype: :class:`.Point` or ndarray """ pnt = self._p0.xyz + u * self._v.ijk if is_array_type(rtype): return pnt else: return Point(pnt)
def eval(self, u=0., v=0., w=0., rtype='Point', *args, **kwargs): """ Evaluate point on the plane at (u, v). :param u: :param v: :param w: :param rtype: :return: """ pnt = (self._p0.xyz + u * self._vu.ijk + v * self._vv.ijk + w * self._vn.ijk) if is_array_type(rtype): return pnt else: return Point(pnt)
def norm(self, u, v, rtype='Vector', **kwargs): """ Compute the plane normal. :param float u: Parametric point. :param float v: Parametric point. :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray). :return: """ vnorm = self._vn.ijk if is_array_type(rtype): return vnorm p0 = self.eval(u, v) return Vector(vnorm, p0)
def deriv(self, u, rtype='Vector'): """ Compute the line derivative. This only returns the line direction vector with magnitude, and is implemented only for consistency with Bezier and NURBS curve objects. :param float u: Parametric point (-inf < u < inf). :param str rtype: Option to return a NumPy array or :class:`.Vector` instance (rtype = 'ndarray' or 'Vector'). :return: Line derivative. :rtype: :class:`.Vector` or ndarray """ if is_array_type(rtype): return self._v.vxyz else: p0 = self.eval(u) return Vector(self._v.vxyz, p0)
def eval(self, dx, dy, dz, rtype='Point', *args, **kwargs): """ Evaluate a point relative to the system. :param dx: :param dy: :param dz: :param rtype: :param args: :param kwargs: :return: """ pnt = (self._origin.xyz + dx * self._vx.ijk + dy * self._vy.ijk + dz * self._vz.ijk) if is_array_type(rtype): return pnt else: return Point(pnt)
def curve_eval2d(curve, u, sref=None, rtype='Point', domain='local', tol=None): """ Evaluate a curve in the parametric space of the surface. :param curve_like curve: Curve to evaluate. :param float u: Curve parameter. :param surface_like sref: The surface to return the 2-D parameters on. :param str rtype: Option to return a NumPy array or Point2D instance (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :param float tol: Tolerance for point refinement (ICurve only). :return: Parameters on surface at curve parameter. :rtype: tuple """ if not CheckGeom.is_curve_like(curve) or not \ CheckGeom.is_surface_like(sref): return None if tol is None: tol = Settings.gtol / 100. # ICurve already has built-in method. if CheckGeom.is_icurve(curve) and curve.has_surf(sref): return curve.eval2d(u, rtype, domain, tol, sref) # Evaluate curve and invert on surface. p3d = curve.eval(u, domain=domain) u, v = ProjectGeom.invert(p3d, sref, True) if None in [u, v]: return None # Return desired type. if is_array_type(rtype): return array([u, v], dtype=float64) return CreateGeom.point2d((u, v))
def tangent(self, u, v, rtype='Vector', domain='local'): """ Surface tangent at (u, v). :param float u: Parametric point. :param float v: Parametric point. :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Surface tangent vector. :rtype: :class:`.Vector` or ndarray """ du = self.deriv(u, v, 1, 0, rtype='ndarray', domain=domain) dv = self.deriv(u, v, 0, 1, rtype='ndarray', domain=domain) if is_array_type(rtype): return du + dv else: p0 = self.eval(u, v, domain=domain) return Vector(du + dv, p0)
def norm(self, u, v, rtype='Vector', domain='local'): """ Compute the surface normal. :param float u: Parametric point. :param float v: Parametric point. :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Surface normal. :rtype: :class:`.Vector` or ndarray """ du = self.deriv(u, v, 1, 0, rtype='ndarray', domain=domain) dv = self.deriv(u, v, 0, 1, rtype='ndarray', domain=domain) norm = cross(du, dv) if is_array_type(rtype): return norm else: p0 = self.eval(u, v, domain=domain) return Vector(norm, p0)
def eval(self, u, rtype='Point', domain='local', tol=None): """ Evaluate curve at parametric point. :param float u: Parametric point. :param str rtype: Option to return a NumPy array or Point instance (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :param float tol: Tolerance for point refinement. :return: Point on curve. :rtype: :class:`.Point` or ndarray """ if is_local_domain(domain): u = self.local_to_global_param(u) uv1, uv2 = self.eval2d(u, rtype='ndarray', domain='global', tol=tol) p3d = self._s1.eval(uv1[0], uv1[1], rtype='ndarray', domain='global') if is_array_type(rtype): return p3d else: return Point(p3d)
def eval_params(self, ulist, rtype='Point', domain='local'): """ Evaluate the curve at multiple parameters. :param array_like ulist: Curve parameters. :param str rtype: Option to return a NumPy array or list of Point instances (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :return: Points at parameters. :rtype: List of :class:`.Point` instances or NumPy array """ if not is_array_like(ulist): return self.eval(ulist, rtype, domain) if is_local_domain(domain): ulist = map(self.global_to_local_param, ulist) pnts = curve_points(self._n, self._p, self._uk, self._cpw, ulist) if is_array_type(rtype): return pnts else: return [Point(pi) for pi in pnts]
def eval(self, u, rtype='Point', domain='local'): """ Evaluate curve at parametric point. :param float u: Parametric point. :param str rtype: Option to return a NumPy array or Point instance (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :return: Point on curve. :rtype: :class:`.Point` or ndarray """ if is_array_like(u): return self.eval_params(u, rtype, domain) if is_local_domain(domain): u = self.local_to_global_param(u) pnt = curve_point(self._n, self._p, self._uk, self._cpw, u) if is_array_type(rtype): return pnt else: return Point(pnt)
def eval(self, u, v, rtype='Point', domain='local'): """ Evaluate surface at parametric points. :param float u: Parametric point in u-direction. :param float v: Parametric point in v-direction. :param str rtype: Option to return a NumPy array or Point instance (rtype = 'Point' or 'ndarray'). :param str domain: Option to use local (0 <= u, v <= 1) or global (a <= u, v <= b) domain ('local', 'l', 'global', 'g'). :return: Point on surface. :rtype: :class:`.Point` or ndarray """ if not is_local_domain(domain): u = self.global_to_local_param('u', u) v = self.global_to_local_param('v', v) pw = deCasteljau2(self._cpw, self._n, self._m, u, v) pnt = pw[:-1] / pw[-1] if is_array_type(rtype): return pnt else: return Point(pnt)
def deriv(self, u, k=1, d=1, rtype='Vector', domain='local', tol=None): """ Compute the derivative of the intersection curve. Only supports first derivates. :param float u: Parametric point. :param int k: Derivative to return (0 <= k <= 1). :param int d: Highest derivative to compute. Currently only supports first derivative. :param str rtype: Option to return a NumPy array or a Vector instance (rtype = 'Vector' or 'ndarray'). :param str domain: Option to use local (0 <= u <= 1) or global (a <= u <= b) domain ('local', 'l', 'global', 'g'). :param float tol: Tolerance for point refinement. :return: First derivative or intersection curve. :rtype: :class:`.Vector` or ndarray """ if is_local_domain(domain): u = self.local_to_global_param(u) # Evaluate 2-D points. s1, s2 = self._s1, self._s2 uv1, uv2 = self.eval2d(u, rtype='ndarray', domain='global', tol=tol) # Evaluate surface normals. vn1 = s1.norm(uv1[0], uv1[1], rtype='ndarray', domain='global') if self.is_spi: vn2 = s2.vn.ijk else: vn2 = s2.norm(uv2[0], uv2[1], rtype='ndarray', domain='global') # First derivative is cross product du = cross(vn1, vn2) if is_array_type(rtype): return du else: p0 = self.eval(u, domain='global') return Vector(du, p0)