24 #include <geometry/bezier.h> 25 #include <geometry/hom_point.h> 26 #include <geometry/hom_vector.h> 40 m_de_casteljau_points = NULL;
42 m_num_subdivisions = 0;
44 register_primitives();
50 Bezier::Bezier(
const vector<HomPoint>& control_points)
51 : m_control_points(control_points)
53 m_num_control_points = m_control_points.size();
55 m_de_casteljau_points = NULL;
59 m_num_subdivisions = 0;
68 : m_control_points(b.m_control_points)
70 m_num_control_points = b.m_num_control_points;
71 m_de_casteljau_points = NULL;
75 m_num_subdivisions = 0;
84 for (
unsigned int i = 0; i < m_dclj_array_size; ++i)
85 {
delete m_de_casteljau_points[i].first; }
87 delete[] m_de_casteljau_points;
96 m_control_points.clear();
97 m_control_points = control_points;
99 m_num_control_points = m_control_points.size();
110 Bezier::init_dclj_array()
112 m_dclj_array_size = m_num_control_points * (m_num_control_points + 1) / 2;
113 m_dclj_array_size -= m_num_control_points;
115 delete m_de_casteljau_points;
116 m_de_casteljau_points =
new pair<HomPoint*, bool>[m_dclj_array_size];
118 for (
unsigned int i = 0; i < m_dclj_array_size; ++i)
120 m_de_casteljau_points[i].first = NULL;
121 m_de_casteljau_points[i].second =
false;
132 m_control_points[index] = control_point;
133 m_de_casteljau_points[index] = pair<HomPoint*, bool>( &(m_control_points[index]),
true );
144 std::vector<HomPoint>
147 return m_control_points;
157 if (i < m_num_control_points)
158 {
return m_control_points.at(i); }
160 {
throw exception(); }
169 return m_num_control_points - 1;
180 {
throw exception(); }
182 return de_casteljau(m_num_control_points - 1, 0, t);
193 HomPoint b0 = de_casteljau(m_num_control_points - 2, 0, t);
194 HomPoint b1 = de_casteljau(m_num_control_points - 2, 1, t);
208 if (index > m_num_control_points)
211 { t = index / (float) m_num_control_points; }
224 if ( t < 0 || t > 1 )
225 {
throw exception(); }
227 vector<HomPoint> control_points;
229 for (
unsigned k = 0; k < m_num_control_points; ++k)
232 control_points.push_back(p);
236 control_points.clear();
238 for (
unsigned i = 0; i < m_num_control_points; ++i)
240 unsigned int k = m_num_control_points - i - 1;
242 control_points.push_back(p);
252 const vector<HomPoint>&
255 if (m_num_subdivisions == num_subdivisions)
256 {
return m_approximation; }
261 b1.push_back( *
this );
263 for (
unsigned int i = 0; i < num_subdivisions; ++i)
267 for ( vector<Bezier>::iterator iter = b1.begin();
281 for ( vector<Bezier>::iterator bit = b2.begin();
285 vector<HomPoint> points = bit->get_control_points();
287 vector<HomPoint>::iterator pit = points.begin();
289 if ( bit != b2.begin() )
294 for ( vector<HomPoint>::iterator iter = pit;
295 iter != points.end();
297 { m_approximation.push_back( *iter); }
300 m_num_subdivisions = num_subdivisions;
302 return m_approximation;
306 Bezier::de_casteljau(
unsigned int k,
unsigned int i,
float t)
309 {
return m_control_points.at(i); }
313 for (
unsigned int j = 0;
314 j < m_dclj_array_size;
317 delete m_de_casteljau_points[j].first;
319 m_de_casteljau_points[j].first = NULL;
320 m_de_casteljau_points[j].second =
false;
326 unsigned int index = get_dclj_array_index(k, i);
328 if ( m_de_casteljau_points[index].second )
329 {
return *( m_de_casteljau_points[index].first ); }
333 *p = de_casteljau(k-1, i, t) * (1.0 - t) + de_casteljau(k-1, i+1, t) * t;
334 m_de_casteljau_points[index] = pair<HomPoint*, bool>(p,
true);
340 Bezier::get_dclj_array_index(
unsigned int k,
unsigned int i)
const 342 unsigned int index = 0;
344 for (
unsigned int j = 0; j < k; ++j)
345 { index += m_num_control_points - j; }
348 index -= m_num_control_points;
356 vector<HomPoint>::iterator iter;
357 for ( iter = m_control_points.begin();
358 iter != m_control_points.end();
HomVector tangent_at_t(float t)
Compute the tangent vector at position t.
unsigned int degree() const
Get the degree of the polynom.
virtual void register_primitives()
Here, a derived class should register its primitives (HomPoints and HomVectors) by calling add_primit...
Fawkes library namespace.
void subdivide(float t, Bezier &c, Bezier &d)
Subdivide the curve into two polynome of the same degree.
void set_control_points(const std::vector< HomPoint > &control_points)
Set the control points.
HomPoint get_control_point(unsigned int i) const
Get a specific control point.
const std::vector< HomPoint > & approximate(unsigned int num_subdivisions=4)
Approximate the curve with points.
virtual void post_transform()
This method is called after the primitives are transformed.
HomVector tangent_at_point(unsigned int index)
Compute the tangent vector at the specified control point.
HomPoint eval(float t)
Evalutate the polynom for a given t.
void set_control_point(unsigned int index, const HomPoint &control_point)
Replace a specific control point.
std::vector< HomPoint > get_control_points() const
Get the control points.