GteBezierCurve.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.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <LowLevel/GteArray2.h>
11 #include <LowLevel/GteLogger.h>
13 
14 namespace gte
15 {
16 
17 template <int N, typename Real>
18 class BezierCurve : public ParametricCurve<N, Real>
19 {
20 public:
21  // Construction and destruction. The number of control points must be
22  // degree + 1. This object copies the input array. The domain is t
23  // in [0,1]. To validate construction, create an object as shown:
24  // BezierCurve<N, Real> curve(parameters);
25  // if (!curve) { <constructor failed, handle accordingly>; }
26  virtual ~BezierCurve();
27  BezierCurve(int degree, Vector<N, Real> const* controls);
28 
29  // Member access.
30  inline int GetDegree() const;
31  inline int GetNumControls() const;
32  inline Vector<N, Real> const* GetControls() const;
33 
34  // Evaluation of the curve. The function supports derivative calculation
35  // through order 3; that is, maxOrder <= 3 is required. If you want
36  // only the position, pass in maxOrder of 0. If you want the position and
37  // first derivative, pass in maxOrder of 1, and so on. The output
38  // 'values' are ordered as: position, first derivative, second derivative,
39  // third derivative.
40  virtual void Evaluate(Real t, unsigned int maxOrder,
41  Vector<N, Real> values[4]) const;
42 
43 protected:
44  // Support for Evaluate(...).
45  Vector<N, Real> Compute(Real t, Real omt, int order) const;
46 
48  std::vector<Vector<N, Real>> mControls[4];
50 };
51 
52 
53 template <int N, typename Real>
55 {
56 }
57 
58 template <int N, typename Real>
60  :
61  ParametricCurve<N, Real>((Real)0, (Real)1),
62  mDegree(degree),
63  mNumControls(degree + 1),
65 {
66  if (degree < 2 || !controls)
67  {
68  LogError("Invalid input.");
69  return;
70  }
71 
72  // Copy the controls.
73  mControls[0].resize(mNumControls);
74  std::copy(controls, controls + mNumControls, mControls[0].begin());
75 
76  // Compute first-order differences.
77  mControls[1].resize(mNumControls - 1);
78  for (int i = 0; i < mNumControls - 1; ++i)
79  {
80  mControls[1][i] = mControls[0][i + 1] - mControls[0][i];
81  }
82 
83  // Compute second-order differences.
84  mControls[2].resize(mNumControls - 2);
85  for (int i = 0; i < mNumControls - 2; ++i)
86  {
87  mControls[2][i] = mControls[1][i + 1] - mControls[1][i];
88  }
89 
90  // Compute third-order differences.
91  if (degree >= 3)
92  {
93  mControls[3].resize(mNumControls - 3);
94  for (int i = 0; i < mNumControls - 3; ++i)
95  {
96  mControls[3][i] = mControls[2][i + 1] - mControls[2][i];
97  }
98  }
99 
100  // Compute combinatorial values Choose(n,k) and store in mChoose[n][k].
101  // The values mChoose[r][c] are invalid for r < c; that is, we use only
102  // the entries for r >= c.
103  mChoose[0][0] = (Real)1;
104  mChoose[1][0] = (Real)1;
105  mChoose[1][1] = (Real)1;
106  for (int i = 2; i <= mDegree; ++i)
107  {
108  mChoose[i][0] = (Real)1;
109  mChoose[i][i] = (Real)1;
110  for (int j = 1; j < i; ++j)
111  {
112  mChoose[i][j] = mChoose[i - 1][j - 1] + mChoose[i - 1][j];
113  }
114  }
115 
116  this->mConstructed = true;
117 }
118 
119 template <int N, typename Real> inline
121 {
122  return mDegree;
123 }
124 
125 template <int N, typename Real> inline
127 {
128  return mNumControls;
129 }
130 
131 template <int N, typename Real> inline
133 {
134  return &mControls[0][0];
135 }
136 
137 template <int N, typename Real>
138 void BezierCurve<N, Real>::Evaluate(Real t, unsigned int maxOrder,
139  Vector<N, Real> values[4]) const
140 {
141  if (!this->mConstructed)
142  {
143  // Errors were already generated during construction.
144  for (unsigned int order = 0; order < 4; ++order)
145  {
146  values[order].MakeZero();
147  }
148  return;
149  }
150 
151  // Compute position.
152  Real omt = (Real)1 - t;
153  values[0] = Compute(t, omt, 0);
154  if (maxOrder >= 1)
155  {
156  // Compute first derivative.
157  values[1] = Compute(t, omt, 1);
158  if (maxOrder >= 2)
159  {
160  // Compute second derivative.
161  values[2] = Compute(t, omt, 2);
162  if (maxOrder >= 3 && mDegree >= 3)
163  {
164  // Compute third derivative.
165  values[3] = Compute(t, omt, 3);
166  }
167  else
168  {
169  values[3].MakeZero();
170  }
171  }
172  }
173 }
174 
175 template <int N, typename Real>
177 const
178 {
180 
181  Real tpow = t;
182  int isup = mDegree - order;
183  for (int i = 1; i < isup; ++i)
184  {
185  Real c = mChoose[isup][i] * tpow;
186  result = (result + c * mControls[order][i]) * omt;
187  tpow *= t;
188  }
189  result = (result + tpow * mControls[order][isup]);
190 
191  int multiplier = 1;
192  for (int i = 0; i < order; ++i)
193  {
194  multiplier *= mDegree - i;
195  }
196  result *= (Real)multiplier;
197 
198  return result;
199 }
200 
201 
202 }
Array2< Real > mChoose
void MakeZero()
Definition: GteVector.h:279
GLfixed GLfixed GLint GLint order
Definition: glext.h:4927
int GetNumControls() const
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
int GetDegree() const
virtual void Evaluate(Real t, unsigned int maxOrder, Vector< N, Real > values[4]) const
const GLubyte * c
Definition: glext.h:11671
#define LogError(message)
Definition: GteLogger.h:92
virtual ~BezierCurve()
GLdouble GLdouble t
Definition: glext.h:239
Vector< N, Real > Compute(Real t, Real omt, int order) const
Vector< N, Real > const * GetControls() const
BezierCurve(int degree, Vector< N, Real > const *controls)
std::vector< Vector< N, Real > > mControls[4]
GLuint64EXT * result
Definition: glext.h:10003


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