forked from vicrucann/CurveFitting
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
134 lines (106 loc) · 4.05 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#ifdef _WIN32
#include <Windows.h>
#endif
#include "math.h"
#include "assert.h"
#include <iostream>
#include <osg/Drawable>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/StateSet>
#include <osgViewer/Viewer>
#include <osg/LineWidth>
#include <osg/BlendFunc>
#include "libPathFitter/OsgPathFitter.h"
const int WIN_WIDTH = 1280;
const int WIN_HEIGHT = 960;
osg::Vec3Array* drawCurves(osg::Vec3Array* curves, int samples = 11)
{
osg::ref_ptr<osg::Vec3Array> sampled = new osg::Vec3Array;
assert(curves->size() % 4 == 0);
int nCurves = curves->size() / 4;
auto delta = 1.f / float(samples);
for (decltype(curves->size()) i=0; i<curves->size(); i=i+4){
auto b0 = curves->at(i),
b1 = curves->at(i+1),
b2 = curves->at(i+2),
b3 = curves->at(i+3);
for (int j=0; j<=samples; ++j){
auto t = delta * float(j),
t2 = t*t,
one_minus_t = 1.f - t,
one_minus_t2 = one_minus_t * one_minus_t;
auto Bt = b0 * one_minus_t2 * one_minus_t
+ b1 * 3.f * t * one_minus_t2
+ b2 * 3.f * t2 * one_minus_t
+ b3 * t2 * t;
sampled->push_back(Bt);
}
}
assert(sampled->size() == (samples+1)*nCurves);
return sampled.release();
}
osg::Vec3Array* createDataPoints()
{
osg::ref_ptr<osg::Vec3Array> curve = new osg::Vec3Array;
curve->push_back(osg::Vec3f(0,0,0));
curve->push_back(osg::Vec3f(2,0,12));
curve->push_back(osg::Vec3f(40,0,28));
curve->push_back(osg::Vec3f(40,0,4));
osg::ref_ptr<osg::Vec3Array> sampled = drawCurves(curve, 60);
return sampled.release();
}
osg::Node* createTestScene()
{
osg::ref_ptr<osg::Vec3Array> path = createDataPoints();
OsgPathFitter<osg::Vec3Array, osg::Vec3f, float> fitter;
fitter.init(*path);
/* threshold: prefer to set it automatically depending on size of bounding box
* in order to avoid under- and over-fitting. Here, we will set it fixed */
float tolerance = 1.f;
osg::ref_ptr<osg::Vec3Array> curves = fitter.fit(tolerance);
osg::ref_ptr<osg::Vec3Array> sampled = drawCurves(curves.get(), 15);
std::cout << "path.segments=" << path->size()/4 << std::endl;
std::cout << "curves.segments=" << curves->size()/4 << std::endl;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, sampled->size()));
geom->setVertexArray(sampled.get());
/* color data */
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(0.3,0.9,0,1));
osg::Vec4Array* colorsGT = new osg::Vec4Array;
colorsGT->push_back(osg::Vec4(1,0,0,1));
geom->setUseDisplayList(false);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::ref_ptr<osg::Geometry> geomGT = new osg::Geometry;
geomGT->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, path->size()));
geomGT->setUseDisplayList(false);
geomGT->setVertexArray(path.get());
geomGT->setColorArray(colorsGT, osg::Array::BIND_OVERALL);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
geode->addDrawable(geomGT.get());
osg::StateSet* state = geode->getOrCreateStateSet();
state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
state->setMode(GL_BLEND, osg::StateAttribute::ON);
state->setMode(GL_LINE_SMOOTH, osg::StateAttribute::ON);
osg::LineWidth* lw = new osg::LineWidth;
lw->setWidth(10.f);
state->setAttribute(lw, osg::StateAttribute::ON);
osg::BlendFunc* blendfunc = new osg::BlendFunc();
state->setAttributeAndModes(blendfunc, osg::StateAttribute::ON);
return geode.release();
}
int main(int, char**)
{
#ifdef _WIN32
::SetProcessDPIAware();
#endif
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Group> root = new osg::Group();
root->addChild(createTestScene());
viewer.setSceneData(root.get());
viewer.setUpViewInWindow(100,100,WIN_WIDTH, WIN_HEIGHT);
return viewer.run();
}