Example #1
0
    def evaluate_rational(self):
        """ Evaluates the NURBS curve.

        .. note:: The evaluated surface points are stored in :py:attr:`~curvepts`.

        :return: None
        """
        # Check all parameters are set before the curve evaluation
        self._check_variables()
        # Clean up the curve points, if necessary
        self._reset_curve()

        # Algorithm A4.1
        for u in utils.frange(0, 1, self._mDelta):
            span = utils.find_span(self._mDegree, tuple(self._mKnotVector),
                                   len(self._mCtrlPts), u)
            basis = utils.basis_functions(self._mDegree,
                                          tuple(self._mKnotVector), span, u)
            curveptw = [0.0, 0.0, 0.0]
            for i in range(0, self._mDegree + 1):
                curveptw[0] += (basis[i] *
                                (self._mCtrlPts[span - self._mDegree + i][0] *
                                 self._mWeights[span - self._mDegree + i]))
                curveptw[1] += (basis[i] *
                                (self._mCtrlPts[span - self._mDegree + i][1] *
                                 self._mWeights[span - self._mDegree + i]))
                curveptw[2] += (basis[i] *
                                self._mWeights[span - self._mDegree + i])
            # Divide by weight
            curvept = [
                float(curveptw[0] / curveptw[2]),
                float(curveptw[1] / curveptw[2])
            ]
            self._mCurvePts.append(curvept)
Example #2
0
    def evaluate(self):
        """ Evaluates the B-Spline curve.

        .. note:: The evaluated surface points are stored in :py:attr:`~curvepts`.

        :return: None
        """
        # Check all parameters are set before the curve evaluation
        self._check_variables()
        # Clean up the curve points, if necessary
        self._reset_curve()

        # Algorithm A3.1
        for u in utils.frange(0, 1, self._mDelta):
            span = utils.find_span(self._mDegree, tuple(self._mKnotVector),
                                   len(self._mCtrlPts), u)
            basis = utils.basis_functions(self._mDegree,
                                          tuple(self._mKnotVector), span, u)
            curvept = [0.0, 0.0]
            for i in range(0, self._mDegree + 1):
                curvept[0] += (basis[i] *
                               self._mCtrlPts[span - self._mDegree + i][0])
                curvept[1] += (basis[i] *
                               self._mCtrlPts[span - self._mDegree + i][1])
            self._mCurvePts.append(curvept)
Example #3
0
    def evaluate(self):
        """ Evaluates the B-Spline surface.

        .. note:: The evaluated surface points are stored in :py:attr:`~surfpts`.

        :return: None
        """
        # Check all parameters are set before the surface evaluation
        self._check_variables()
        # Clean up the surface points lists, if necessary
        self._reset_surface()

        # Algorithm A3.5
        for v in utils.frange(0, 1, self._mDelta):
            span_v = utils.find_span(self._mDegreeV, tuple(self._mKnotVectorV),
                                     self._mCtrlPts_sizeV, v)
            basis_v = utils.basis_functions(self._mDegreeV,
                                            tuple(self._mKnotVectorV), span_v,
                                            v)
            for u in utils.frange(0, 1, self._mDelta):
                span_u = utils.find_span(self._mDegreeU,
                                         tuple(self._mKnotVectorU),
                                         self._mCtrlPts_sizeU, u)
                basis_u = utils.basis_functions(self._mDegreeU,
                                                tuple(self._mKnotVectorU),
                                                span_u, u)
                idx_u = span_u - self._mDegreeU
                surfpt = [0.0, 0.0, 0.0]
                for l in range(0, self._mDegreeV + 1):
                    temp = [0.0, 0.0, 0.0]
                    idx_v = span_v - self._mDegreeV + l
                    for k in range(0, self._mDegreeU + 1):
                        temp[0] += (basis_u[k] *
                                    self._mCtrlPts2D[idx_u + k][idx_v][0])
                        temp[1] += (basis_u[k] *
                                    self._mCtrlPts2D[idx_u + k][idx_v][1])
                        temp[2] += (basis_u[k] *
                                    self._mCtrlPts2D[idx_u + k][idx_v][2])
                    surfpt[0] += (basis_v[l] * temp[0])
                    surfpt[1] += (basis_v[l] * temp[1])
                    surfpt[2] += (basis_v[l] * temp[2])
                self._mSurfPts.append(surfpt)
Example #4
0
    def derivatives2(self, u=-1, order=0):
        """ Evaluates n-th order curve derivatives at the given u using Algorithm A3.2

        :param u: knot value
        :type u: float
        :param order: derivative order
        :type order: integer
        :return: A list containing up to {order}-th derivative of the curve
        :rtype: list
        """
        # Check all parameters are set before the curve evaluation
        self._check_variables()
        # Check u parameters are correct
        if u < 0.0 or u > 1.0:
            raise ValueError('"u" value should be between 0 and 1.')

        # Algorithm A3.2: CurveDerivsAlg1
        du = min(self._mDegree, order)

        CK = [[None for x in range(2)] for y in range(order + 1)]
        for k in range(self._mDegree + 1, order + 1):
            CK[k] = [0.0 for x in range(2)]

        span = utils.find_span(self._mDegree, tuple(self._mKnotVector),
                               len(self._mCtrlPts), u)
        bfunsders = utils.basis_functions_ders(self._mDegree,
                                               tuple(self._mKnotVector), span,
                                               u, du)

        for k in range(0, du + 1):
            CK[k] = [0.0 for x in range(2)]
            for j in range(0, self._mDegree + 1):
                CK[k][0] += (bfunsders[k][j] *
                             self._mCtrlPts[span - self._mDegree + j][0])
                CK[k][1] += (bfunsders[k][j] *
                             self._mCtrlPts[span - self._mDegree + j][1])

        # Return the derivatives
        return CK
Example #5
0
    def derivatives(self, u=-1, v=-1, order=0):
        """ Evaluates n-th order surface derivatives at the given (u,v) parameter.

        * SKL[0][0] will be the surface point itself
        * SKL[0][1] will be the 1st derivative w.r.t. v
        * SKL[2][1] will be the 2nd derivative w.r.t. u and 1st derivative w.r.t. v

        :param u: parameter in the U direction
        :type u: float
        :param v: parameter in the V direction
        :type v: float
        :param order: derivative order
        :type order: integer
        :return: A list SKL, where SKL[k][l] is the derivative of the surface S(u,v) w.r.t. u k times and v l times
        :rtype: list
        """
        # Check all parameters are set before the surface evaluation
        self._check_variables()
        # Check u and v parameters are correct
        utils.check_uv(u, v)

        # Algorithm A3.6
        du = min(self._mDegreeU, order)
        dv = min(self._mDegreeV, order)

        SKL = [[[0.0 for x in range(3)] for y in range(dv + 1)]
               for z in range(du + 1)]

        span_u = utils.find_span(self._mDegreeU, tuple(self._mKnotVectorU),
                                 self._mCtrlPts_sizeU, u)
        bfunsders_u = utils.basis_functions_ders(self._mDegreeU,
                                                 self._mKnotVectorU, span_u, u,
                                                 du)
        span_v = utils.find_span(self._mDegreeV, tuple(self._mKnotVectorV),
                                 self._mCtrlPts_sizeV, v)
        bfunsders_v = utils.basis_functions_ders(self._mDegreeV,
                                                 self._mKnotVectorV, span_v, v,
                                                 dv)

        for k in range(0, du + 1):
            temp = [[] for y in range(self._mDegreeV + 1)]
            for s in range(0, self._mDegreeV + 1):
                temp[s] = [0.0 for x in range(3)]
                for r in range(0, self._mDegreeU + 1):
                    cu = span_u - self._mDegreeU + r
                    cv = span_v - self._mDegreeV + s
                    temp[s][0] += (bfunsders_u[k][r] *
                                   self._mCtrlPts2D[cu][cv][0])
                    temp[s][1] += (bfunsders_u[k][r] *
                                   self._mCtrlPts2D[cu][cv][1])
                    temp[s][2] += (bfunsders_u[k][r] *
                                   self._mCtrlPts2D[cu][cv][2])
            dd = min(order - k, dv)
            for l in range(0, dd + 1):
                for s in range(0, self._mDegreeV + 1):
                    SKL[k][l][0] += (bfunsders_v[l][s] * temp[s][0])
                    SKL[k][l][1] += (bfunsders_v[l][s] * temp[s][1])
                    SKL[k][l][2] += (bfunsders_v[l][s] * temp[s][2])

        # Return the derivatives
        return SKL
Example #6
0
    def evaluate_rational(self):
        """ Evaluates the NURBS surface.

        .. note:: The evaluated surface points are stored in :py:attr:`~surfpts`.

        :return: None
        """
        # Check all parameters are set before the surface evaluation
        self._check_variables()
        # Clean up the surface points lists, if necessary
        self._reset_surface()

        # Prepare a 2D weighted control points array
        ctrlptsw = []
        c_u = 0
        while c_u < self._mCtrlPts_sizeU:
            ctrlptsw_v = []
            c_v = 0
            while c_v < self._mCtrlPts_sizeV:
                temp = [
                    self._mCtrlPts2D[c_u][c_v][0] *
                    self._mWeights[c_u + (c_v * self._mCtrlPts_sizeU)],
                    self._mCtrlPts2D[c_u][c_v][1] *
                    self._mWeights[c_u + (c_v * self._mCtrlPts_sizeU)],
                    self._mCtrlPts2D[c_u][c_v][2] *
                    self._mWeights[c_u + (c_v * self._mCtrlPts_sizeU)],
                    self._mWeights[c_u + (c_v * self._mCtrlPts_sizeU)]
                ]
                ctrlptsw_v.append(temp)
                c_v += 1
            ctrlptsw.append(ctrlptsw_v)
            c_u += 1

        # Algorithm A4.3
        for v in utils.frange(0, 1, self._mDelta):
            span_v = utils.find_span(self._mDegreeV, tuple(self._mKnotVectorV),
                                     self._mCtrlPts_sizeV, v)
            basis_v = utils.basis_functions(self._mDegreeV,
                                            tuple(self._mKnotVectorV), span_v,
                                            v)
            for u in utils.frange(0, 1, self._mDelta):
                span_u = utils.find_span(self._mDegreeU,
                                         tuple(self._mKnotVectorU),
                                         self._mCtrlPts_sizeU, u)
                basis_u = utils.basis_functions(self._mDegreeU,
                                                tuple(self._mKnotVectorU),
                                                span_u, u)
                idx_u = span_u - self._mDegreeU
                surfptw = [0.0, 0.0, 0.0, 0.0]
                for l in range(0, self._mDegreeV + 1):
                    temp = [0.0, 0.0, 0.0, 0.0]
                    idx_v = span_v - self._mDegreeV + l
                    for k in range(0, self._mDegreeU + 1):
                        temp[0] += (basis_u[k] * ctrlptsw[idx_u + k][idx_v][0])
                        temp[1] += (basis_u[k] * ctrlptsw[idx_u + k][idx_v][1])
                        temp[2] += (basis_u[k] * ctrlptsw[idx_u + k][idx_v][2])
                        temp[3] += (basis_u[k] * ctrlptsw[idx_u + k][idx_v][3])
                    surfptw[0] += (basis_v[l] * temp[0])
                    surfptw[1] += (basis_v[l] * temp[1])
                    surfptw[2] += (basis_v[l] * temp[2])
                    surfptw[3] += (basis_v[l] * temp[3])
                # Divide by weight to obtain 3D surface points
                surfpt = [
                    surfptw[0] / surfptw[3], surfptw[1] / surfptw[3],
                    surfptw[2] / surfptw[3]
                ]
                self._mSurfPts.append(surfpt)