1 /**************************************************************************** 2 * 3 * ViSP, open source Visual Servoing Platform software. 4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved. 5 * 6 * This software is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * See the file LICENSE.txt at the root directory of this source 11 * distribution for additional information about the GNU GPL. 12 * 13 * For using ViSP with software that can not be combined with the GNU 14 * GPL, please contact Inria about acquiring a ViSP Professional 15 * Edition License. 16 * 17 * See http://visp.inria.fr for more information. 18 * 19 * This software was developed at: 20 * Inria Rennes - Bretagne Atlantique 21 * Campus Universitaire de Beaulieu 22 * 35042 Rennes Cedex 23 * France 24 * 25 * If you have questions regarding the use of this file, please contact 26 * Inria at visp@inria.fr 27 * 28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 30 * 31 * Description: 32 * This class implements the Non Uniform Rational B-Spline (NURBS) 33 * 34 * Authors: 35 * Nicolas Melchior 36 * 37 *****************************************************************************/ 38 39 #ifndef vpNurbs_H 40 #define vpNurbs_H 41 42 /*! 43 \file vpNurbs.h 44 \brief Class that provides tools to compute and manipulate a Non Uniform 45 Rational B-Spline curve. 46 */ 47 48 #include <visp3/core/vpBSpline.h> 49 #include <visp3/core/vpImagePoint.h> 50 #include <visp3/core/vpList.h> 51 #include <visp3/core/vpMath.h> 52 #include <visp3/core/vpMatrix.h> 53 #include <visp3/me/vpMeSite.h> 54 55 #include <list> 56 57 /*! 58 \class vpNurbs 59 \ingroup module_me 60 61 \brief Class that provides tools to compute and manipulate a Non Uniform 62 Rational B-Spline curve. 63 64 The different parameters are : 65 66 - The knot vector \f$ U = {u_0, ... , u_m} \f$ where the knots \f$ u_i, i = 67 0, ...,m \f$ are real number such as \f$ u_i < u_{i+1} i = 0, ...,m \f$. To 68 define a curve, the knot vector is such as : \f$ U = {a , ... , a, u_{p+1} , 69 ... , u_{m-p-1} , b , ... , b} \f$ where \f$ a \f$ and \f$ b \f$ are real 70 numbers and p is the degree of the B-Spline basis functions. 71 72 - The B-Spline basis functions \f$ N_{i,p} \f$ defined as : 73 \f[ N_{i,0}(u) = \left\{\begin{array}{cc} 74 1 & \mbox{if } u_i \leq u_{i+1} \\ 0 & else 75 \end{array}\right.\f] 76 77 \f[ N_{i,p}(u) = 78 \frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)+\frac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u)\f] 79 80 where \f$ i = 0 , ... , m-1 \f$ and p is the degree of the B-Spline basis 81 functions. 82 83 - The control points \f$ {P_i} \f$ which are defined by the coordinates \f$ 84 (i,j) \f$ of a point in an image. 85 86 - The weight \f$ {w_i} \f$ associated to each control points.The wheights 87 value is upper than 0. 88 89 It is possible to compute the coordinates of a point corresponding to the 90 knots \f$ u \f$ (\f$ u \in [u_0,u_m]\f$) thanks to the formula : \f[ C(u) = 91 \frac{\sum_{i=0}^n (N_{i,p}(u)w_iP_i)}{\sum_{i=0}^n (N_{i,p}(u)w_i)}\f] 92 93 You can find much more information about the B-Splines and the 94 implementation of all the methods in the Nurbs Book. 95 */ 96 97 class VISP_EXPORT vpNurbs : public vpBSpline 98 { 99 protected: 100 std::vector<double> weights; // Vector which contains the weights associated 101 // to each control Points 102 103 protected: 104 static vpMatrix computeCurveDers(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, 105 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, 106 std::vector<double> &l_weights); 107 vpMatrix computeCurveDers(double u, unsigned int der); 108 109 public: 110 vpNurbs(); 111 vpNurbs(const vpNurbs &nurbs); 112 virtual ~vpNurbs(); 113 114 /*! 115 Gets all the weights relative to the control points. 116 117 \param list [out] : A std::list containing weights relative to the 118 control points. 119 */ get_weights(std::list<double> & list)120 inline void get_weights(std::list<double> &list) const 121 { 122 list.clear(); 123 for (unsigned int i = 0; i < weights.size(); i++) 124 list.push_back(*(&(weights[0]) + i)); 125 } 126 127 /*! 128 Sets all the knots. 129 130 \param list : A std::list containing the value of the knots. 131 */ set_weights(const std::list<double> & list)132 inline void set_weights(const std::list<double> &list) 133 { 134 weights.clear(); 135 for (std::list<double>::const_iterator it = list.begin(); it != list.end(); ++it) { 136 weights.push_back(*it); 137 } 138 } 139 140 static vpImagePoint computeCurvePoint(double l_u, unsigned int l_i, unsigned int l_p, std::vector<double> &l_knots, 141 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights); 142 vpImagePoint computeCurvePoint(double u); 143 144 static vpImagePoint *computeCurveDersPoint(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, 145 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, 146 std::vector<double> &l_weights); 147 vpImagePoint *computeCurveDersPoint(double u, unsigned int der); 148 149 static void curveKnotIns(double l_u, unsigned int l_k, unsigned int l_s, unsigned int l_r, unsigned int l_p, 150 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, 151 std::vector<double> &l_weights); 152 void curveKnotIns(double u, unsigned int s = 0, unsigned int r = 1); 153 154 static void refineKnotVectCurve(double *l_x, unsigned int l_r, unsigned int l_p, std::vector<double> &l_knots, 155 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights); 156 void refineKnotVectCurve(double *x, unsigned int r); 157 158 static unsigned int removeCurveKnot(double l_u, unsigned int l_r, unsigned int l_num, double l_TOL, unsigned int l_s, 159 unsigned int l_p, std::vector<double> &l_knots, 160 std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights); 161 unsigned int removeCurveKnot(double l_u, unsigned int l_r, unsigned int l_num, double l_TOL); 162 163 static void globalCurveInterp(std::vector<vpImagePoint> &l_crossingPoints, unsigned int l_p, 164 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, 165 std::vector<double> &l_weights); 166 void globalCurveInterp(vpList<vpMeSite> &l_crossingPoints); 167 void globalCurveInterp(const std::list<vpImagePoint> &l_crossingPoints); 168 void globalCurveInterp(const std::list<vpMeSite> &l_crossingPoints); 169 void globalCurveInterp(); 170 171 static void globalCurveApprox(std::vector<vpImagePoint> &l_crossingPoints, unsigned int l_p, unsigned int l_n, 172 std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, 173 std::vector<double> &l_weights); 174 void globalCurveApprox(vpList<vpMeSite> &l_crossingPoints, unsigned int n); 175 void globalCurveApprox(const std::list<vpImagePoint> &l_crossingPoints, unsigned int n); 176 void globalCurveApprox(const std::list<vpMeSite> &l_crossingPoints, unsigned int n); 177 void globalCurveApprox(unsigned int n); 178 }; 179 180 #endif 181