Advanced Outline Draw Tool support

Hi!
Before start to develop the code to give support to creation of Advanced Outlines using Draw Tool I need some feed back from your side.

For those who has not listened about Advanced Outline, here is the link of its wiki page: synfig.org/wiki/Advanced_Outline_Layer

When using the Draw tool the computer takes a list of position (x,y) and width (w) from the Input Device. To control how those list of points are translated into the outline or region, you have one parameter (Smooth) that controls that. Basically higher Smooth values takes less points and the curve is more smooth, flatting hand irregularities. For the regular Outlines the width is attached to the vertex, so there is not much to decide about width, because once the vertex positions are defined by the Smooth parameter the widths are just the values on those points.

But with the Advanced Outline the situation changes. The widths control points can be placed freely (there is not restriction on its position) so there is a degree of freedom available.

Let’s see how can we compute those width control points:
Say we have a list of widths (wi) and positions on the plane (pi). Say that I subdivide the widths on intervals (w1, w10), (w11, w20) , etc. Same with the positions (p1, p10), (p11, p20), etc. Then I compute a width point control that is the average of each group of widths W1=average(w1, w10) etc. Then I place the width control point at the middle position of the same group (say it is the position p6 for the first group). One Draw Tool parameter controls the number of widths to group each time.
That’s one approaching of the calculation of the width points. But there are others…
Imagine that I just discard one width value from each 10 and place the width control point where the non discarded one is. Then, the number of discarded points (or %) is the Draw Tool parameter.

Other approaching is to make the width average of the width values considering the distance between one position and other. For example, imagine that the ten positions grouped in the first case are not regularly placed on the canvas. Say that p1 is far away and p2 to p10 are so close. It is clear that the resulting line will have the length between p1 and p10 but you have to agree with me that the width w1 is more important than the other widths w2 to w10, right? or not?

I would like to know your opinion about how should I handle the widths considering the best user performance and satisfaction.

Thanks for reading!!
-G

Hi Genete,

That’s an interesting yet difficult question, indeed!

I think your first sugggestion can be good, if you add one width point at first and last points to complement the average points.

Or a good solution would be to add points depending on pressure variations!
That is if you make a long stroke with constant pressure (starting for instance at 50% and finish at 55%), make one width point at begining (50%) and one at end (55%).

If there are variations above a defined value (set in tool option), like pressure difference of 10%, add a point, no matter where it is.
(for instance in a stroke like previous one, add a point where/if pressure reach 60%, then 70%, or 40%, then 30% … )
THIS would be awesome tablet-pressure-controlled width :wink:

Thanks for the reply Animtim

Please define “pressure variations”. The maximum/minimum value along the average? The average weight of all the stroke or by groups of width control points? How can the user can control how much width points has to be established? Based on a variation % around the average? based on a stroke length or stroke percentage?

:mrgreen:

I’m sorry for the flood of questions but the problem needs much more detailed explanation of how to proceed.

-G

I’ve edited previous post, maybe you’ll see better what I mean.
If not I’ll try to explain better.

Basically, you create one width point at the stroke start, with the exact value from pressure. Then if pressure varies from a certain %, add a point there with this value.
And add another width point at the end of the stroke with exact value from pressure again.

Then if you draw with almost constant pressure, you’ve few width points.
If you do lots of pressure changes, you’ve lots of points.

I hope that’s clear enough. Tell me if it’s not! :wink:

Another example:
-Line is set to 10pix
-tool is set to 20% “smooth width” (or whatever we can call it)
Do a stroke, pressure info from tablet is: 55;54;53;52;52;52;52;51;50;38;37;37;33;32;32;31;30;26;26;26;48;53;53;60
(of course there are much more values in a real stroke, that’s just to explain)
Then interpret it as: create one width point 55% of 10pix at start, then when pressure varies 20% or more from first point add a width point with this value (here a point at 33% of 10pix) then from this point another variation of 20% or more create a point (here another at 53%), at the place of the line where the value is recorded. Then a final point at the end at 60% of 10pix.

Also now I think we would need two parameters in tool option for this:
-The one I describe above
-a 2nd parameter that define a minimum stroke length before to add a new width point. This could help control the number of width points if the first value is very small.

I’ve been thinking about how to proceed to translate the (position, width) pairs to the advanced outline and I think that I’ve “invented” a strong method.
This is a quick overview (it will be detailed explained in one wiki page):

Given N positions (x,y) and N widths (w) obtain K widthpoints (wp) along the bline using a user provided parameter called maximum error (e).
P(i)=(xi, yi) where i is [1,N]
W(i)= wi where i is [1,N]
WP(i)=withpoint-i where i is [1,K]

Procedure:

  1. Calculate distances: Calculate the cummulative distances for each position (x,y)
    D(i)=di where di=sum(k=1, k=i, magnitude(P(k)-P(k-1)) width d0=0.0
  2. Given two already consecutive calculated widthpoints WP(i) and WP (i+1). Take a subgroup of W,P where P(j) is between WP(i)position and WP(i+1).position. Let’s consider that the subgroup is from j=j1 to j=j2
  3. Calculate the average squared error of the pairs W, P compared to the interopolated width curve (with its user selected smoothness) between WP(i) and WP(i+1). Compare that cuadratic error with e^2. If squared error is smaller then stop procedure.
  4. If quadratic error is bigger then:
    4.1) Find one W,P pair on the interval j1, j2 (call it j*). At that j* calculate a new WP*. It must match that the sum of the cuadratic error between the pairs of W,P for (j1, j*) and the pairs of W,P for (j*,j2) compared with its interpolated curve from WP(i) and WP* and the interpolated curve from W* and WP(i+1) is minimum.
    4.2) Spawn two recursive procedures one for each side starting at step 3)

I believe that this procedure should converge for something useful and reliable. If the recursive calculation and the minimum squared error procedure takes to long I think that I can replace the calculation of j* just where the absolute error is maximum in that point instead of minimize the sum of the quadratic errors of the piece of curves.

Please if you don’t understand the procedure, be patience, I’ll do a more detailed document as soon as possible.
Thanks for reading!
-G

en.wikipedia.org/wiki/Least_squares