Skip to content
GitLab
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
1a6ef241
Commit
1a6ef241
authored
Apr 12, 2017
by
Steve Tonneau
Browse files
using horner's scheme to evaluate bezier curves as well. 100 times faster git add .
parent
32b39c08
Changes
2
Hide whitespace changes
Inline
Side-by-side
include/spline/bezier_curve.h
View file @
1a6ef241
...
...
@@ -127,7 +127,7 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
+
3
*
pts_
[
2
]
*
nT
*
nT
*
dt
+
pts_
[
3
]
*
nT
*
nT
*
nT
;
default
:
return
eval
Bernstein
(
nT
);
return
eval
Horner
(
nT
);
break
;
}
}
...
...
@@ -194,6 +194,27 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
return
res
;
}
///
/// \brief Evaluates all Bernstein polynomes for a certain degree using horner's scheme
///
point_t
evalHorner
(
const
Numeric
t
)
const
{
typename
t_point_t
::
const_iterator
pts_it
=
pts_
.
begin
();
Numeric
u
,
bc
,
tn
;
u
=
1.0
-
t
;
bc
=
1
;
tn
=
1
;
point_t
tmp
=
(
*
pts_it
)
*
u
;
++
pts_it
;
for
(
int
i
=
1
;
i
<
degree_
;
i
++
,
++
pts_it
)
{
tn
=
tn
*
t
;
bc
=
bc
*
(
degree_
-
i
+
1
)
/
i
;
tmp
=
(
tmp
+
tn
*
bc
*
(
*
pts_it
))
*
u
;
}
return
(
tmp
+
tn
*
t
*
(
*
pts_it
));
}
const
t_point_t
&
waypoints
()
const
{
return
pts_
;}
private:
...
...
src/tests/spline_test/Main.cpp
View file @
1a6ef241
...
...
@@ -186,6 +186,7 @@ void BezierCurveTest(bool& error)
for
(
double
d
=
0.
;
d
<
1.
;
d
+=
0.1
)
{
ComparePoints
(
cf3
.
evalBernstein
(
d
)
,
cf3
(
d
),
errMsg2
,
error
);
ComparePoints
(
cf3
.
evalHorner
(
d
)
,
cf3
(
d
),
errMsg2
,
error
);
}
bool
error_in
(
true
);
...
...
@@ -228,6 +229,102 @@ void BezierCurveTest(bool& error)
}
}
#include
<ctime>
void
BezierCurveTestCompareHornerAndBernstein
(
bool
&
error
)
{
using
namespace
std
;
std
::
vector
<
double
>
values
;
for
(
int
i
=
0
;
i
<
100000
;
++
i
)
values
.
push_back
(
rand
()
/
RAND_MAX
);
//first compare regular evaluation (low dim pol)
point_t
a
(
1
,
2
,
3
);
point_t
b
(
2
,
3
,
4
);
point_t
c
(
3
,
4
,
5
);
point_t
d
(
3
,
6
,
7
);
point_t
e
(
3
,
61
,
7
);
point_t
f
(
3
,
56
,
7
);
point_t
g
(
3
,
36
,
7
);
point_t
h
(
43
,
6
,
7
);
point_t
i
(
3
,
6
,
77
);
std
::
vector
<
point_t
>
params
;
params
.
push_back
(
a
);
params
.
push_back
(
b
);
params
.
push_back
(
c
);
// 3d curve
bezier_curve_t
cf
(
params
.
begin
(),
params
.
end
());
clock_t
s0
,
e0
,
s1
,
e1
,
s2
,
e2
;
s0
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf
(
*
cit
);
}
e0
=
clock
();
s1
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf
.
evalBernstein
(
*
cit
);
}
e1
=
clock
();
s2
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf
.
evalHorner
(
*
cit
);
}
e2
=
clock
();
std
::
cout
<<
"time for analytical eval "
<<
double
(
e0
-
s0
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
std
::
cout
<<
"time for bernstein eval "
<<
double
(
e1
-
s1
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
std
::
cout
<<
"time for horner eval "
<<
double
(
e2
-
s2
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
std
::
cout
<<
"now with high order polynom "
<<
std
::
endl
;
params
.
push_back
(
d
);
params
.
push_back
(
e
);
params
.
push_back
(
f
);
params
.
push_back
(
g
);
params
.
push_back
(
h
);
params
.
push_back
(
i
);
bezier_curve_t
cf2
(
params
.
begin
(),
params
.
end
());
s1
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf2
.
evalBernstein
(
*
cit
);
}
e1
=
clock
();
s2
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf2
.
evalHorner
(
*
cit
);
}
e2
=
clock
();
s0
=
clock
();
for
(
std
::
vector
<
double
>::
const_iterator
cit
=
values
.
begin
();
cit
!=
values
.
end
();
++
cit
)
{
cf2
(
*
cit
);
}
e0
=
clock
();
std
::
cout
<<
"time for analytical eval "
<<
double
(
e0
-
s0
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
std
::
cout
<<
"time for bernstein eval "
<<
double
(
e1
-
s1
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
std
::
cout
<<
"time for horner eval "
<<
double
(
e2
-
s2
)
/
CLOCKS_PER_SEC
<<
std
::
endl
;
}
void
BezierDerivativeCurveTest
(
bool
&
error
)
{
std
::
string
errMsg
(
"In test BezierDerivativeCurveTest ; unexpected result for x "
);
...
...
@@ -617,7 +714,7 @@ int main(int /*argc*/, char** /*argv[]*/)
{
std
::
cout
<<
"performing tests...
\n
"
;
bool
error
=
false
;
CubicFunctionTest
(
error
);
/*
CubicFunctionTest(error);
ExactCubicNoErrorTest(error);
ExactCubicPointsCrossedTest(error); // checks that given wayPoints are crossed
ExactCubicTwoPointsTest(error);
...
...
@@ -630,7 +727,8 @@ int main(int /*argc*/, char** /*argv[]*/)
EffectorSplineRotationWayPointRotationTest(error);
BezierCurveTest(error);
BezierDerivativeCurveTest(error);
BezierDerivativeCurveConstraintTest
(
error
);
BezierDerivativeCurveConstraintTest(error);*/
BezierCurveTestCompareHornerAndBernstein
(
error
);
if
(
error
)
{
std
::
cout
<<
"There were some errors
\n
"
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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