GteNURBSCurve.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.1 (2016/06/26)
7 
8 #pragma once
9 
12 
13 namespace gte
14 {
15 
16 template <int N, typename Real>
17 class NURBSCurve : public ParametricCurve<N, Real>
18 {
19 public:
20  // Construction. If the input controls is non-null, a copy is made of
21  // the controls. To defer setting the control points or weights, pass
22  // null pointers and later access the control points or weights via
23  // GetControls(), GetWeights(), SetControl(), or SetWeight() member
24  // functions. The domain is t in [t[d],t[n]], where t[d] and t[n] are
25  // knots with d the degree and n the number of control points. To
26  // validate construction, create an object as shown:
27  // NURBSCurve<N, Real> curve(parameters);
28  // if (!curve) { <constructor failed, handle accordingly>; }
30  Vector<N, Real> const* controls, Real const* weights);
31 
32  // Member access.
33  inline BasisFunction<Real> const& GetBasisFunction() const;
34  inline int GetNumControls() const;
35  inline Vector<N, Real> const* GetControls() const;
36  inline Vector<N, Real>* GetControls();
37  inline Real const* GetWeights() const;
38  inline Real* GetWeights();
39  void SetControl(int i, Vector<N, Real> const& control);
40  Vector<N, Real> const& GetControl(int i) const;
41  void SetWeight(int i, Real weight);
42  Real const& GetWeight(int i) const;
43 
44  // Evaluation of the curve. The function supports derivative calculation
45  // through order 3; that is, maxOrder <= 3 is required. If you want
46  // only the position, pass in maxOrder of 0. If you want the position and
47  // first derivative, pass in maxOrder of 1, and so on. The output
48  // 'values' are ordered as: position, first derivative, second derivative,
49  // third derivative.
50  virtual void Evaluate(Real t, unsigned int maxOrder,
51  Vector<N, Real> values[4]) const;
52 
53 private:
54  // Support for Evaluate(...).
55  void Compute(unsigned int order, int imin, int imax, Vector<N, Real>& X,
56  Real& w) const;
57 
59  std::vector<Vector<N, Real>> mControls;
60  std::vector<Real> mWeights;
61 };
62 
63 
64 template <int N, typename Real>
66  Vector<N, Real> const* controls, Real const* weights)
67  :
68  ParametricCurve<N, Real>((Real)0, (Real)1),
69  mBasisFunction(input)
70 {
71  if (!mBasisFunction)
72  {
73  // Errors were already generated during construction of the
74  // basis function.
75  return;
76  }
77 
78  // The mBasisFunction stores the domain but so does ParametricCurve.
79  this->mTime.front() = mBasisFunction.GetMinDomain();
80  this->mTime.back() = mBasisFunction.GetMaxDomain();
81 
82  // The replication of control points for periodic splines is avoided
83  // by wrapping the i-loop index in Evaluate.
84  mControls.resize(input.numControls);
85  mWeights.resize(input.numControls);
86  if (controls)
87  {
88  std::copy(controls, controls + input.numControls, mControls.begin());
89  }
90  else
91  {
92  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
93  }
94  if (weights)
95  {
96  std::copy(weights, weights + input.numControls, mWeights.begin());
97  }
98  else
99  {
100  memset(mWeights.data(), 0, mWeights.size() * sizeof(mWeights[0]));
101  }
102  this->mConstructed = true;
103 }
104 
105 template <int N, typename Real>
107 {
108  return mBasisFunction;
109 }
110 
111 template <int N, typename Real>
113 {
114  return static_cast<int>(mControls.size());
115 }
116 
117 template <int N, typename Real>
119 {
120  return mControls.data();
121 }
122 
123 template <int N, typename Real>
125 {
126  return mControls.data();
127 }
128 
129 template <int N, typename Real>
131 {
132  return mWeights.data();
133 }
134 
135 template <int N, typename Real>
137 {
138  return mWeights.data();
139 }
140 
141 template <int N, typename Real>
143 {
144  if (0 <= i && i < GetNumControls())
145  {
146  mControls[i] = control;
147  }
148 }
149 
150 template <int N, typename Real>
152 {
153  if (0 <= i && i < GetNumControls())
154  {
155  return mControls[i];
156  }
157  else
158  {
159  // Invalid index, return something.
160  return mControls[0];
161  }
162 }
163 
164 template <int N, typename Real>
166 {
167  if (0 <= i && i < GetNumControls())
168  {
169  mWeights[i] = weight;
170  }
171 }
172 
173 template <int N, typename Real>
174 Real const& NURBSCurve<N, Real>::GetWeight(int i) const
175 {
176  if (0 <= i && i < GetNumControls())
177  {
178  return mWeights[i];
179  }
180  else
181  {
182  // Invalid index, return something.
183  return mWeights[0];
184  }
185 }
186 
187 template <int N, typename Real>
188 void NURBSCurve<N, Real>::Evaluate(Real t, unsigned int maxOrder,
189  Vector<N, Real> values[4]) const
190 {
191  if (!this->mConstructed)
192  {
193  // Errors were already generated during construction.
194  for (unsigned int order = 0; order < 4; ++order)
195  {
196  values[order].MakeZero();
197  }
198  return;
199  }
200 
201  int imin, imax;
202  mBasisFunction.Evaluate(t, maxOrder, imin, imax);
203 
204  // Compute position.
205  Vector<N, Real> X;
206  Real w;
207  Compute(0, imin, imax, X, w);
208  Real invW = ((Real)1) / w;
209  values[0] = invW * X;
210 
211  if (maxOrder >= 1)
212  {
213  // Compute first derivative.
214  Vector<N, Real> XDer1;
215  Real wDer1;
216  Compute(1, imin, imax, XDer1, wDer1);
217  values[1] = invW * (XDer1 - wDer1 * values[0]);
218 
219  if (maxOrder >= 2)
220  {
221  // Compute second derivative.
222  Vector<N, Real> XDer2;
223  Real wDer2;
224  Compute(2, imin, imax, XDer2, wDer2);
225  values[2] = invW * (XDer2 - ((Real)2) * wDer1 * values[1] -
226  wDer2 * values[0]);
227 
228  if (maxOrder == 3)
229  {
230  // Compute third derivative.
231  Vector<N, Real> XDer3;
232  Real wDer3;
233  Compute(3, imin, imax, XDer3, wDer3);
234  values[3] = invW * (XDer3 - ((Real)3) * wDer1 * values[2] -
235  ((Real)3) * wDer2 * values[1] - wDer3 * values[0]);
236  }
237  else
238  {
239  values[3].MakeZero();
240  }
241  }
242  }
243 }
244 
245 template <int N, typename Real>
246 void NURBSCurve<N, Real>::Compute(unsigned int order, int imin, int imax,
247  Vector<N, Real>& X, Real& w) const
248 {
249  // The j-index introduces a tiny amount of overhead in order to handle
250  // both aperiodic and periodic splines. For aperiodic splines, j = i
251  // always.
252 
253  int numControls = GetNumControls();
254  X.MakeZero();
255  w = (Real)0;
256  for (int i = imin; i <= imax; ++i)
257  {
258  int j = (i >= numControls ? i - numControls : i);
259  Real tmp = mBasisFunction.GetValue(order, i) * mWeights[j];
260  X += tmp * mControls[j];
261  w += tmp;
262  }
263 }
264 
265 }
void MakeZero()
Definition: GteVector.h:279
GLfixed GLfixed GLint GLint order
Definition: glext.h:4927
const GLbyte * weights
Definition: glext.h:4455
std::vector< Vector< N, Real > > mControls
Definition: GteNURBSCurve.h:59
void SetControl(int i, Vector< N, Real > const &control)
Vector< N, Real > const & GetControl(int i) const
std::vector< Real > mTime
GLuint GLuint GLfloat weight
Definition: glext.h:9668
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
BasisFunction< Real > const & GetBasisFunction() const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
virtual void Evaluate(Real t, unsigned int maxOrder, Vector< N, Real > values[4]) const
std::vector< Real > mWeights
Definition: GteNURBSCurve.h:60
Vector< N, Real > const * GetControls() const
Real const * GetWeights() const
NURBSCurve(BasisFunctionInput< Real > const &input, Vector< N, Real > const *controls, Real const *weights)
Definition: GteNURBSCurve.h:65
GLdouble GLdouble t
Definition: glext.h:239
void SetWeight(int i, Real weight)
Real const & GetWeight(int i) const
int GetNumControls() const
GLenum GLenum GLenum input
Definition: glext.h:9913
BasisFunction< Real > mBasisFunction
Definition: GteNURBSCurve.h:58
void Compute(unsigned int order, int imin, int imax, Vector< N, Real > &X, Real &w) const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01