Skip to content

Instantly share code, notes, and snippets.

@folkertdev
Last active August 29, 2015 14:27
Show Gist options
  • Save folkertdev/7851c39241d1557a26dd to your computer and use it in GitHub Desktop.
Save folkertdev/7851c39241d1557a26dd to your computer and use it in GitHub Desktop.
An improvement idea for the Freestyle resample method. Improvements include inline vector operations, next(it) for pairwise iteration and a for instead of while loop.
# pairwise is defined in utils.py and a very handy function
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip(a, b)
def resample(stroke, sampling=5.0):
new_vertices = []
for a, b in pairwise(stroke):
new_vertices.append(a)
distance = (b.point - a.point).length
if distance <= sampling:
continue
# calculate how many times the segment ab needs to be split
splits = int(round(distance / sampling, 0))
step = sampling / distance
for i in range(1, splits):
t = i * step
# linearly interpolates the attributes of a and b
newvert = StrokeVertex(a, b, t)
new_vertices.append(newvert)
stroke.vertices = new_vertices
int Stroke::Resample(float iSampling)
{
if (iSampling == 0)
return 0;
if (iSampling >= _sampling)
return 0;
_sampling = iSampling;
vertex_container newVertices;
StrokeVertex *newVertex = NULL;
StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
for (StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(), next(it);
it != itend && ++next != itend; it = next) {
newVertices.push_back(&(*it));
real distance = ((next)->getPoint() - (it)->getPoint()).norm();
if (distance <= _sampling) {
continue;
}
int splits = (int) distance / _sampling;
float step = _sampling / distance;
for (int i = 1; i < splits; i++) {
newVertex = new StrokeVertex(&(*it), &(*next), i * step);
newVertices.push_back(newVertex);
}
}
newVertices.push_back(_Vertices.back());
_Vertices.clear();
_Vertices = newVertices;
newVertices.clear();
return 0;
}
int Stroke::Resample(float iSampling)
{
//cerr << "old size :" << strokeVerticesSize() << endl;
if (iSampling == 0)
return 0;
if (iSampling >= _sampling)
return 0;
_sampling = iSampling;
// Resample...
//real curvilinearLength = 0.0f;
vertex_container newVertices;
real t = 0.0f;
const real limit = 0.99;
StrokeVertex *newVertex = NULL;
StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin();
StrokeInternal::StrokeVertexIterator next = it;
++next;
StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
while ((it != itend) && (next != itend)) {
newVertices.push_back(&(*it));
Vec2r a((it)->getPoint());
Vec2r b((next)->getPoint());
Vec2r vec_tmp(b - a);
real norm_var = vec_tmp.norm();
if (norm_var <= _sampling) {
//curvilinearLength += norm_var;
++it;
++next;
continue;
}
//curvilinearLength += _sampling;
t = _sampling / norm_var;
while (t < limit) {
newVertex = new StrokeVertex(&(*it), &(*next), t);
//newVertex->setCurvilinearAbscissa(curvilinearLength);
newVertices.push_back(newVertex);
t = t + _sampling / norm_var;
}
++it;
++next;
}
// add last:
if ((it != itend) && (next == itend))
newVertices.push_back(&(*it));
_Vertices.clear();
_Vertices = newVertices;
newVertices.clear();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment