1 // Description:
2 //   Bezier segment template.
3 //
4 // Copyright (C) 2001 Frank Becker
5 //
6 // This program is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free Software
8 // Foundation;  either version 2 of the License,  or (at your option) any  later
9 // version.
10 //
11 // This program is distributed in the hope that it will be useful,  but  WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
14 //
15 #include <Trace.hpp>
16 #include <Bezier.hpp>
17 
18 //Construct a Bezier segment given 4 points
19 template<class POINT>
Bezier(const POINT point[4])20 Bezier<POINT>::Bezier( const POINT point[4])
21 {
22     XTRACE();
23     int dim = point[0].dimension();
24 
25     for( int d=0; d<dim; d++)
26     {
27         float val[4];
28 
29 	for( int i=0; i<4; i++)
30 	{
31             POINT pt = point[ i];
32 	    val[ i] = pt[d];
33 	}
34 	calcCoeff( val, pd[d]);
35     }
36 }
37 
38 //Calculate Bezier segment coefficients
39 template<class POINT>
calcCoeff(const float in[4],float out[4])40 void Bezier<POINT>::calcCoeff( const float in[ 4], float out[ 4])
41 {
42     XTRACE();
43     out[ 0] =  1*in[0];
44     out[ 1] = -3*in[0] +3*in[1];
45     out[ 2] =  3*in[0] -6*in[1] +3*in[2];
46     out[ 3] = -1*in[0] +3*in[1] -3*in[2] +1*in[3];
47 }
48 
49 //Calculate point on the Bezier segment at time 0<=t<=1
50 template<class POINT>
Pos(const float t,POINT & point) const51 void Bezier<POINT>::Pos( const float t, POINT &point) const
52 {
53     XTRACE();
54     float tt = t*t;
55     float ttt = t*tt;
56 
57     for( int d=0; d<point.dimension(); d++)
58     {
59 	point.set(d, pd[d][0] + t*pd[d][1] + tt*pd[d][2] + ttt*pd[d][3]);
60     }
61 }
62 
63 //Calculate perpendicular vector at time 0<=t<=1
64 //Really only makes sense in 2D
65 template<class POINT>
PVec(const float t,POINT & point) const66 void Bezier<POINT>::PVec( const float t, POINT &point) const
67 {
68     XTRACE();
69     float t2 = 2*t;
70     float tt3 = 3*t*t;
71 
72     if( point.dimension() != 2) return;
73 
74     //vector perpendicular to tangent at t
75     // x/y -> -(y/x)
76     point.set(1,  pd[0][1] + t2*pd[0][2] + tt3*pd[0][3]);
77     point.set(0,-(pd[1][1] + t2*pd[1][2] + tt3*pd[1][3]));
78 }
79 
80 //Calculate tangent vector at time 0<=t<=1
81 template<class POINT>
TVec(const float t,POINT & point) const82 void Bezier<POINT>::TVec( const float t, POINT &point) const
83 {
84     XTRACE();
85     float t2 = 2*t;
86     float tt3 = 3*t*t;
87 
88     for( int d=0; d<point.dimension(); d++)
89     {
90 	point.set(d, pd[d][1] + t2*pd[d][2] + tt3*pd[d][3]);
91     }
92 }
93