Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pierre Fernbach
hpp-spline
Commits
435f93a5
Unverified
Commit
435f93a5
authored
Feb 08, 2019
by
Fernbach Pierre
Committed by
GitHub
Feb 08, 2019
Browse files
Merge pull request #9 from stonneau/bernstein_horner
[BUG FIX] evalXXX methods do not consider time
parents
bf71c76b
6c796dcf
Changes
2
Hide whitespace changes
Inline
Side-by-side
include/hpp/spline/bezier_curve.h
View file @
435f93a5
...
...
@@ -139,37 +139,10 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
/// \param t : the time when to evaluate the spine
/// \param return : the value x(t)
virtual
point_t
operator
()(
const
time_t
t
)
const
{
num_t
nT
=
t
/
T_
;
if
(
Safe
&!
(
0
<=
nT
&&
nT
<=
1
))
{
throw
std
::
out_of_range
(
"can't evaluate bezier curve, out of range"
);
// TODO
}
else
{
num_t
dt
=
(
1
-
nT
);
switch
(
size_
)
{
case
1
:
return
mult_T_
*
pts_
[
0
];
case
2
:
return
mult_T_
*
(
pts_
[
0
]
*
dt
+
nT
*
pts_
[
1
]);
break
;
case
3
:
return
mult_T_
*
(
pts_
[
0
]
*
dt
*
dt
+
2
*
pts_
[
1
]
*
nT
*
dt
+
pts_
[
2
]
*
nT
*
nT
);
break
;
case
4
:
return
mult_T_
*
(
pts_
[
0
]
*
dt
*
dt
*
dt
+
3
*
pts_
[
1
]
*
nT
*
dt
*
dt
+
3
*
pts_
[
2
]
*
nT
*
nT
*
dt
+
pts_
[
3
]
*
nT
*
nT
*
nT
);
default
:
return
mult_T_
*
evalHorner
(
nT
);
break
;
}
}
if
(
Safe
&!
(
0
<=
t
&&
t
<=
T_
))
throw
std
::
out_of_range
(
"can't evaluate bezier curve, out of range"
);
// TODO
return
evalHorner
(
t
);
}
/// \brief Computes the derivative curve at order N.
...
...
@@ -225,14 +198,15 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
/// Warning: the horner scheme is about 100 times faster than this method.
/// This method will probably be removed in the future
///
point_t
evalBernstein
(
const
Numeric
u
)
const
point_t
evalBernstein
(
const
Numeric
t
)
const
{
const
Numeric
u
=
t
/
T_
;
point_t
res
=
point_t
::
Zero
(
Dim
);
typename
t_point_t
::
const_iterator
pts_it
=
pts_
.
begin
();
for
(
typename
std
::
vector
<
Bern
<
Numeric
>
>::
const_iterator
cit
=
bernstein_
.
begin
();
cit
!=
bernstein_
.
end
();
++
cit
,
++
pts_it
)
res
+=
cit
->
operator
()(
u
)
*
(
*
pts_it
);
return
res
;
return
res
*
mult_T_
;
}
...
...
@@ -241,19 +215,20 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
///
point_t
evalHorner
(
const
Numeric
t
)
const
{
const
Numeric
u
=
t
/
T_
;
typename
t_point_t
::
const_iterator
pts_it
=
pts_
.
begin
();
Numeric
u
,
bc
,
tn
;
u
=
1.0
-
t
;
Numeric
u
_op
,
bc
,
tn
;
u
_op
=
1.0
-
u
;
bc
=
1
;
tn
=
1
;
point_t
tmp
=
(
*
pts_it
)
*
u
;
++
pts_it
;
point_t
tmp
=
(
*
pts_it
)
*
u
_op
;
++
pts_it
;
for
(
unsigned
int
i
=
1
;
i
<
degree_
;
i
++
,
++
pts_it
)
{
tn
=
tn
*
t
;
tn
=
tn
*
u
;
bc
=
bc
*
((
num_t
)(
degree_
-
i
+
1
))
/
i
;
tmp
=
(
tmp
+
tn
*
bc
*
(
*
pts_it
))
*
u
;
tmp
=
(
tmp
+
tn
*
bc
*
(
*
pts_it
))
*
u
_op
;
}
return
(
tmp
+
tn
*
t
*
(
*
pts_it
));
return
(
tmp
+
tn
*
u
*
(
*
pts_it
))
*
mult_T_
;
}
const
t_point_t
&
waypoints
()
const
{
return
pts_
;}
...
...
@@ -264,12 +239,12 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
* @param t unNormalized time
* @return the point at time t
*/
point_t
evalDeCasteljau
(
const
Numeric
T
)
const
{
point_t
evalDeCasteljau
(
const
Numeric
t
)
const
{
// normalize time :
const
Numeric
t
=
T
/
T_
;
t_point_t
pts
=
deCasteljauReduction
(
waypoints
(),
t
);
const
Numeric
u
=
t
/
T_
;
t_point_t
pts
=
deCasteljauReduction
(
waypoints
(),
u
);
while
(
pts
.
size
()
>
1
){
pts
=
deCasteljauReduction
(
pts
,
t
);
pts
=
deCasteljauReduction
(
pts
,
u
);
}
return
pts
[
0
]
*
mult_T_
;
}
...
...
@@ -281,18 +256,18 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
/**
* @brief deCasteljauReduction compute the de Casteljau's reduction of the given list of points at time t
* @param pts the original list of points
* @param
t
the NORMALIZED time
* @param
u
the NORMALIZED time
* @return the reduced list of point (size of pts - 1)
*/
t_point_t
deCasteljauReduction
(
const
t_point_t
&
pts
,
const
Numeric
t
)
const
{
if
(
t
<
0
||
t
>
1
)
throw
std
::
out_of_range
(
"In deCasteljau reduction :
t
is not in [0;1]"
);
t_point_t
deCasteljauReduction
(
const
t_point_t
&
pts
,
const
Numeric
u
)
const
{
if
(
u
<
0
||
u
>
1
)
throw
std
::
out_of_range
(
"In deCasteljau reduction :
u
is not in [0;1]"
);
if
(
pts
.
size
()
==
1
)
return
pts
;
t_point_t
new_pts
;
for
(
cit_point_t
cit
=
pts
.
begin
()
;
cit
!=
(
pts
.
end
()
-
1
)
;
++
cit
){
new_pts
.
push_back
((
1
-
t
)
*
(
*
cit
)
+
t
*
(
*
(
cit
+
1
)));
new_pts
.
push_back
((
1
-
u
)
*
(
*
cit
)
+
u
*
(
*
(
cit
+
1
)));
}
return
new_pts
;
}
...
...
@@ -303,24 +278,24 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
* @param t
* @return
*/
std
::
pair
<
bezier_curve_t
,
bezier_curve_t
>
split
(
const
Numeric
T
){
if
(
T
==
T_
)
std
::
pair
<
bezier_curve_t
,
bezier_curve_t
>
split
(
const
Numeric
t
){
if
(
t
==
T_
)
throw
std
::
runtime_error
(
"can't split curve, interval range is equal to original curve"
);
t_point_t
wps_first
(
size_
),
wps_second
(
size_
);
const
double
t
=
T
/
T_
;
const
double
u
=
t
/
T_
;
wps_first
[
0
]
=
pts_
.
front
();
wps_second
[
degree_
]
=
pts_
.
back
();
t_point_t
casteljau_pts
=
waypoints
();
size_t
id
=
1
;
while
(
casteljau_pts
.
size
()
>
1
){
casteljau_pts
=
deCasteljauReduction
(
casteljau_pts
,
t
);
casteljau_pts
=
deCasteljauReduction
(
casteljau_pts
,
u
);
wps_first
[
id
]
=
casteljau_pts
.
front
();
wps_second
[
degree_
-
id
]
=
casteljau_pts
.
back
();
++
id
;
}
bezier_curve_t
c_first
(
wps_first
.
begin
(),
wps_first
.
end
(),
T
,
mult_T_
);
bezier_curve_t
c_second
(
wps_second
.
begin
(),
wps_second
.
end
(),
T_
-
T
,
mult_T_
);
bezier_curve_t
c_first
(
wps_first
.
begin
(),
wps_first
.
end
(),
t
,
mult_T_
);
bezier_curve_t
c_second
(
wps_second
.
begin
(),
wps_second
.
end
(),
T_
-
t
,
mult_T_
);
return
std
::
make_pair
(
c_first
,
c_second
);
}
...
...
tests/Main.cpp
View file @
435f93a5
...
...
@@ -181,11 +181,14 @@ void BezierCurveTest(bool& error)
ComparePoints
(
d
,
res1
,
errMsg
+
"3(1) "
,
error
);
//testing bernstein polynomes
bezier_curve_t
cf5
(
params
.
begin
(),
params
.
end
(),
2.
);
std
::
string
errMsg2
(
"In test BezierCurveTest ; Bernstein polynoms do not evaluate as analytical evaluation"
);
for
(
double
d
=
0.
;
d
<
1
.
;
d
+=
0.1
)
for
(
double
d
=
0.
;
d
<
2
.
;
d
+=
0.1
)
{
ComparePoints
(
cf3
.
evalBernstein
(
d
)
,
cf3
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf3
.
evalHorner
(
d
)
,
cf3
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf5
.
evalBernstein
(
d
)
,
cf5
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf5
.
evalHorner
(
d
)
,
cf5
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf5
.
compute_derivate
(
1
).
evalBernstein
(
d
)
,
cf5
.
compute_derivate
(
1
)
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf5
.
compute_derivate
(
1
).
evalHorner
(
d
)
,
cf5
.
compute_derivate
(
1
)
(
d
),
errMsg2
,
error
);
}
bool
error_in
(
true
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment