bezier-utils-test.h revision e69f7d715a3db7f1fff1c8334714c8fab63852ab
#include <cxxtest/TestSuite.h>
#include <glib.h>
#include <sstream>
/* mental disclaims all responsibility for this evil idea for testing
static functions. The main disadvantages are that we retain the
#define's and `using' directives of the included file. */
#include "bezier-utils.cpp"
/* (Returns false if NaN encountered.) */
static bool range_approx_equal(double const a[], double const b[], unsigned const len) {
for (unsigned i = 0; i < len; ++i) {
if (!( fabs( a[i] - b[i] ) < 1e-4 )) {
return false;
}
}
return true;
}
{
return ( NR_DF_TEST_CLOSE(a[X], b[X], eps) &&
NR_DF_TEST_CLOSE(a[Y], b[Y], eps) );
}
static inline double square(double const x) {
return x * x;
}
/** Determine whether the found control points are the same as previously found on some developer's
machine. Doesn't call utest__fail, just writes a message to stdout for diagnostic purposes:
the most important test is that the root-mean-square of errors in the estimation are low rather
than that the control points found are the same.
**/
{
unsigned diff_mask = 0;
for (unsigned i = 0; i < 4; ++i) {
for (unsigned d = 0; d < 2; ++d) {
}
}
}
if ( diff_mask != 0 ) {
msg << "Got different control points from previously-coded (diffs=0x" << std::hex << diff_mask << "\n";
msg << " Previous:";
for (unsigned i = 0; i < 4; ++i) {
}
msg << "\n";
msg << " Found: ";
for (unsigned i = 0; i < 4; ++i) {
}
msg << "\n";
}
}
double const exp_rms_error)
{
double sum_errsq = 0.0;
for (unsigned i = 0; i < n; ++i) {
}
/* The fitter code appears to have improved [or the floating point calculations differ
on this machine from the machine where exp_rms_error was calculated]. */
char msg[200];
sprintf(msg, "N.B. rms_error regression requirement can be decreased: have rms_error=%g.", rms_error); // localizing ok
}
}
static Point const c[4];
static double const t[24];
static unsigned const n;
Point d[24];
{
/* Feed it some points that can be fit exactly with a single bezier segment, and see how
well it manages. */
for (unsigned i = 0; i < n; ++i) {
}
}
virtual ~BezierUtilsTest() {}
{
Point(0., 0.),
};
Point(0., 0.),
};
struct tst {
unsigned src_ix0;
unsigned src_len;
unsigned exp_dest_ix0;
unsigned exp_dest_len;
} const test_data[] = {
/* src start ix, src len, exp_dest start ix, exp dest len */
{0, 0, 0, 0},
{2, 1, 1, 1},
{0, 1, 0, 1},
{0, 2, 0, 1},
{0, 3, 0, 2},
{1, 3, 0, 3},
{0, 5, 0, 3},
{0, 6, 0, 4},
{0, 7, 0, 4}
};
for (unsigned i = 0 ; i < G_N_ELEMENTS(test_data) ; ++i) {
t.src_len,
dest) );
exp_dest + t.exp_dest_ix0,
t.exp_dest_len);
}
}
void testBezierPt1()
{
double const t[] = {0.5, 0.25, 0.3, 0.6};
for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) {
}
}
void testBezierPt2()
{
double const t[] = {0.5, 0.25, 0.3, 0.6};
for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) {
}
}
void testBezierPt3()
{
double const t[] = {0.5, 0.25, 0.3, 0.6};
for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) {
< 1e-4 );
}
}
void testComputeMaxErrorRatio()
{
struct Err_tst {
double u;
double err;
} const err_tst[] = {
{c[0], 0.0, 0.0},
{c[3], 1.0, 0.0},
};
double u[G_N_ELEMENTS(err_tst)];
for (unsigned i = 0; i < G_N_ELEMENTS(err_tst); ++i) {
d[i] = t.pt;
u[i] = t.u;
}
unsigned max_ix = ~0u;
}
void testChordLengthParameterize()
{
/* n == 2 */
{
double u[G_N_ELEMENTS(d)];
chord_length_parameterize(d, u, G_N_ELEMENTS(d));
}
/* Straight line. */
{
unsigned const n = G_N_ELEMENTS(exp_u);
Point d[n];
double u[n];
for (unsigned i = 0; i < n; ++i) {
}
chord_length_parameterize(d, u, n);
}
}
void testGenerateBezier()
{
/* We're being unfair here in using our t[] rather than best t[] for est_b: we
may over-estimate RMS of errors. */
}
void testSpBezierFitCubicFull()
{
int splitpoints[2];
};
/* We're being unfair here in using our t[] rather than best t[] for est_b: we
may over-estimate RMS of errors. */
}
void testSpBezierFitCubic()
{
};
#if 1 /* A change has been made to right_tangent. I believe that usually this change
will result in better fitting, but it won't do as well for this example where
we happen to be feeding a t=0.999 point to the fitter. */
TS_WARN("TODO: Update this test case for revised right_tangent implementation.");
/* In particular, have a test case to show whether the new implementation
really is likely to be better on average. */
#else
/* We're being unfair here in using our t[] rather than best t[] for est_b: we
may over-estimate RMS of errors. */
#endif
}
};
// This is not very neat, but since we know this header is only included by the generated CxxTest file it shouldn't give any problems
double const BezierUtilsTest::t[24] = {
0.0, .001, .03, .05, .09, .13, .18, .25, .29, .33, .39, .44,
.51, .57, .62, .69, .75, .81, .91, .93, .97, .98, .999, 1.0};
Point(8., 0.),
Point const BezierUtilsTest::tHat1(unit_vector( BezierUtilsTest::src_b[1] - BezierUtilsTest::src_b[0] ));
Point const BezierUtilsTest::tHat2(unit_vector( BezierUtilsTest::src_b[2] - BezierUtilsTest::src_b[3] ));
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :