GteBSplineCurve.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 BSplineCurve : 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, pass a null pointer
22  // and later access the control points via GetControls() or SetControl()
23  // member functions. The domain is t in [t[d],t[n]], where t[d] and t[n]
24  // are knots with d the degree and n the number of control points. To
25  // validate construction, create an object as shown:
26  // BSplineCurve<N, Real> curve(parameters);
27  // if (!curve) { <constructor failed, handle accordingly>; }
29  Vector<N, Real> const* controls);
30 
31  // Member access.
32  inline BasisFunction<Real> const& GetBasisFunction() const;
33  inline int GetNumControls() const;
34  inline Vector<N, Real> const* GetControls() const;
35  inline Vector<N, Real>* GetControls();
36  void SetControl(int i, Vector<N, Real> const& control);
37  Vector<N, Real> const& GetControl(int i) const;
38 
39  // Evaluation of the curve. The function supports derivative calculation
40  // through order 3; that is, maxOrder <= 3 is required. If you want
41  // only the position, pass in maxOrder of 0. If you want the position and
42  // first derivative, pass in maxOrder of 1, and so on. The output
43  // 'values' are ordered as: position, first derivative, second derivative,
44  // third derivative.
45  virtual void Evaluate(Real t, unsigned int maxOrder,
46  Vector<N, Real> values[4]) const;
47 
48 private:
49  // Support for Evaluate(...).
50  Vector<N, Real> Compute(unsigned int order, int imin, int imax) const;
51 
53  std::vector<Vector<N, Real>> mControls;
54 };
55 
56 
57 template <int N, typename Real>
59  Vector<N, Real> const* controls)
60  :
61  ParametricCurve<N, Real>((Real)0, (Real)1),
62  mBasisFunction(input)
63 {
64  if (!mBasisFunction)
65  {
66  // Errors were already generated during construction of the
67  // basis function.
68  return;
69  }
70 
71  // The mBasisFunction stores the domain but so does ParametricCurve.
72  this->mTime.front() = mBasisFunction.GetMinDomain();
73  this->mTime.back() = mBasisFunction.GetMaxDomain();
74 
75  // The replication of control points for periodic splines is avoided
76  // by wrapping the i-loop index in Evaluate.
77  mControls.resize(input.numControls);
78  if (controls)
79  {
80  std::copy(controls, controls + input.numControls, mControls.begin());
81  }
82  else
83  {
84  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
85  }
86  this->mConstructed = true;
87 }
88 
89 template <int N, typename Real>
91 {
92  return mBasisFunction;
93 }
94 
95 template <int N, typename Real>
97 {
98  return static_cast<int>(mControls.size());
99 }
100 
101 template <int N, typename Real>
103 {
104  return mControls.data();
105 }
106 
107 template <int N, typename Real>
109 {
110  return mControls.data();
111 }
112 
113 template <int N, typename Real>
115 {
116  if (0 <= i && i < GetNumControls())
117  {
118  mControls[i] = control;
119  }
120 }
121 
122 template <int N, typename Real>
124 {
125  if (0 <= i && i < GetNumControls())
126  {
127  return mControls[i];
128  }
129  else
130  {
131  return mControls[0];
132  }
133 }
134 
135 template <int N, typename Real>
136 void BSplineCurve<N, Real>::Evaluate(Real t, unsigned int maxOrder,
137  Vector<N, Real> values[4]) const
138 {
139  if (!this->mConstructed)
140  {
141  // Errors were already generated during construction.
142  for (unsigned int order = 0; order < 4; ++order)
143  {
144  values[order].MakeZero();
145  }
146  return;
147  }
148 
149  int imin, imax;
150  mBasisFunction.Evaluate(t, maxOrder, imin, imax);
151 
152  // Compute position.
153  values[0] = Compute(0, imin, imax);
154  if (maxOrder >= 1)
155  {
156  // Compute first derivative.
157  values[1] = Compute(1, imin, imax);
158  if (maxOrder >= 2)
159  {
160  // Compute second derivative.
161  values[2] = Compute(2, imin, imax);
162  if (maxOrder == 3)
163  {
164  values[3] = Compute(3, imin, imax);
165  }
166  else
167  {
168  values[3].MakeZero();
169  }
170  }
171  }
172 }
173 
174 template <int N, typename Real>
176  int imax) const
177 {
178  // The j-index introduces a tiny amount of overhead in order to handle
179  // both aperiodic and periodic splines. For aperiodic splines, j = i
180  // always.
181 
182  int numControls = GetNumControls();
184  result.MakeZero();
185  for (int i = imin; i <= imax; ++i)
186  {
187  Real tmp = mBasisFunction.GetValue(order, i);
188  int j = (i >= numControls ? i - numControls : i);
189  result += tmp * mControls[j];
190  }
191  return result;
192 }
193 
194 }
void MakeZero()
Definition: GteVector.h:279
GLfixed GLfixed GLint GLint order
Definition: glext.h:4927
std::vector< Real > mTime
int GetNumControls() const
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
Vector< N, Real > const & GetControl(int i) const
std::vector< Vector< N, Real > > mControls
Vector< N, Real > const * GetControls() const
GLdouble GLdouble t
Definition: glext.h:239
virtual void Evaluate(Real t, unsigned int maxOrder, Vector< N, Real > values[4]) const
BasisFunction< Real > mBasisFunction
void SetControl(int i, Vector< N, Real > const &control)
GLenum GLenum GLenum input
Definition: glext.h:9913
Vector< N, Real > Compute(unsigned int order, int imin, int imax) const
BSplineCurve(BasisFunctionInput< Real > const &input, Vector< N, Real > const *controls)
BasisFunction< Real > const & GetBasisFunction() const
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59