# Drawing pen-data

I’m trying to draw data from a Wacom pen.

If I make each Datapoint a circle (radius proportional to pressure), it looks okay if I write slowly, but if I write at normal speed it starts to look like a bunch of circles rather than a smooth line.

What I’ve done is consider the set of points as the backbone, and between points k and k+1 I first get the midpoint, then I extend a positive and negative perpendicular (the length depending on the pressure). And construct a path from these points.

It is really ugly, but it kind of works:

``````    float x(int i) { return getWidth() * inkling.penData[i].x / 1920.f; };
float y(int i) { return getHeight() * inkling.penData[i].y / 1920.f; };

void drawStroke(Graphics& g, int start, int end) {
if (end-start < 5)
return;

using PointF = Point<float>;

std::vector<PointF> pts;
for(int i=start; i<=end; ++i)
pts.push_back(PointF(x(i),y(i)));

// smooth data
for(int i=1;            i < pts.size(); ++i) pts[i] = 0.5f * pts[i-1] + .5f * pts[i];
for(int i=pts.size()-2; i >= 0;         --i) pts[i] = 0.5f * pts[i+1] + .5f * pts[i];

std::vector<float> widths;
for(int i=start; i<=end; ++i)
widths.push_back(inkling.penData[i].pressure / 1023.f);

// smooth data
for(int i=1;            i < widths.size(); ++i) widths[i] = 0.5f * widths[i-1] + .5f * widths[i];
for(int i=widths.size()-2; i >= 0;         --i) widths[i] = 0.5f * widths[i+1] + .5f * widths[i];

std::vector<PointF> A, B;

for(int i=0; i < pts.size()-1; ++i) {
auto seg = pts[i+1] - pts[i];
auto normal = PointF(seg.y, -seg.x);
auto unitNormal = normal / normal.getDistanceFromOrigin();

auto center = pts[i] + .5f * seg;

float thickness = (widths[i] + widths[i+1]) / 2.f;
thickness *= 1.f;

A.push_back( center + thickness * unitNormal );
B.push_back( center - thickness * unitNormal );
}

Path path;

path.startNewSubPath(A[0]);
for(int i=1; i<A.size(); ++i)
path.lineTo(A[i]);
for(int i=B.size()-1; i>=0; --i)
path.lineTo(B[i]);
path.closeSubPath();

g.setColour(Colours::blue);
g.fillPath(path);
}

void paint (Graphics& g) override
{
g.setColour(Colour(255, 245, 200));
g.fillAll (Colour(255, 245, 200));

auto& D = inkling.penData;

int strokeStart = 0;
while(true) {
while(strokeStart < D.size() && D[strokeStart].pressure == 0.f)
++strokeStart;

if(strokeStart == D.size())
break;

int strokeEnd = strokeStart;
while(strokeEnd < D.size() && D[strokeEnd].pressure > 0.f)
++strokeEnd;
--strokeEnd;

drawStroke(g, strokeStart, strokeEnd);

strokeStart = strokeEnd+1;
};
``````

…produces…

Can anyone see a better way of doing it?

My thinking is that it must be really inefficient, I bet it would be much more efficient to generate a triangle strip. But that could end up being pages of GL code.

I like the idea of drawing to an embedded HTML 5 canvas, then I can leverage D3 and friends, and get GL at a fraction of the code complexity. The main problem is: how to communicate between JavaScript and C++. Can anyone see a way through?

π

I find the subject of html5 integration very interesting !

I also have few javascript code i’d like to make communicate with my C source :
D3.js is really nice to draw interactive data graphics,
SlickGrid is a nice fast editable gridview,
and drawing Gantt Charts with JqGantt is really cool.

maybe trough *.json serialization lib or just some *.json data files you could accomplish some communication?

But Function Calling from JS code to C seems difficult to me (mean call a C function in JS).
I also wonder about JS code execution speed compared to C code

Keep Me tuned with your work on HTML5 canvas!
Regards,
Jerome

I’d take a look at V8 or SpiderMonkey for JavaScript integration.