discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Modelling a flexible strip

NH
nop head
Tue, Dec 26, 2017 4:51 PM

With that function your curve is nearly the same as mine and the energy is
only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have made
some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0, 0,
-139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

Would you mind to provide me the geometric data (endpoint coordinates
and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside yours
with my actual geometry. Your BzEnergy function returns 12 times the energy
for mine which is hard to believe because mine has a more distributed
curvature. A strip held against the screen follows mine, not yours, so I
think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com wrote:

Interesting. I will have to combine with my code and put them side by
side. If I put my length and dimension into your code the result looks a
lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <rcmpersiano@gmail.com

wrote:

Here is the code of my atempts to find the cubic with minimum energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is objective of
an iterative search. The search for the cubic with minimum energy is done
iteratively narrowing an interval (s1,s2) of balances that contains the
best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) )
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the cubic
energy against the balance parameter s has the shape of an U with an almost
horizontal bottom. This shows that the effect of medium-sized changes of
the optimal balance does not produce significant changes of the cubic
energy. In special, in your case of a strip going down from a fixed pole to
a moving table clamped point, the optimal balance will change slowly from
0.5 (when the two end points are level) to 1 (when the strip is fully
stretched). That means the balance of the cubic endpoint derivatives in the
optimal solution is slightly favorable to the fixed point if the strip is
never fully stretched. So, your assumption that "keeping the two inner
control points level" would do the trick is not confirmed by my results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple keeping
the two inner control points level with each other seems to produce a curve
that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the version
with the control points equidistant below the end points.

With that function your curve is nearly the same as mine and the energy is only 0.5% lower. ​ On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > You are right. The energy function was wrong. At some point, I have made > some change in it. > > The correct (I hope) energy function should be: > > function BzEnergy(b, n=8) = > let( bs = subdivBezier3(b, n) ) > [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] > *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); > > > With this function, the plot of the cubic energy as a function of the > balance s has a sharper minimum what is more reasonable. > > I will try your data and compare. > > > 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: > >> The starting point is: >> >> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >> -108.35]]; >> length=180; >> >> After I adjust the control points for length I get [[0, 0, 0], [0, 0, >> -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >> >> On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com> >> wrote: >> >>> Would you mind to provide me the geometric data (endpoint coordinates >>> and strip length) of this case? >>> >>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>> >>>> Whoops >>>> >>>> >>>> ​ >>>> >>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>> >>>>> Here is my curve in red and its control points in blue alongside yours >>>>> with my actual geometry. Your BzEnergy function returns 12 times the energy >>>>> for mine which is hard to believe because mine has a more distributed >>>>> curvature. A strip held against the screen follows mine, not yours, so I >>>>> think there must be a bug in your energy function. >>>>> >>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> wrote: >>>>> >>>>>> Interesting. I will have to combine with my code and put them side by >>>>>> side. If I put my length and dimension into your code the result looks a >>>>>> lot tighter and doesn't match what my real strip does. >>>>>> >>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano <rcmpersiano@gmail.com >>>>>> > wrote: >>>>>> >>>>>>> Here is the code of my atempts to find the cubic with minimum energy. >>>>>>> >>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>> order to reduce the cubic energy. >>>>>>> >>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>> function balance(bz,s) = >>>>>>> [ bz[0], >>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>> bz[3] ]; >>>>>>> >>>>>>> >>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>> AdjustBezier() and its energy is calculated. >>>>>>> >>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>> >>>>>>> >>>>>>> To find the balance that leads to the minimum energy is objective of >>>>>>> an iterative search. The search for the cubic with minimum energy is done >>>>>>> iteratively narrowing an interval (s1,s2) of balances that contains the >>>>>>> best balance. >>>>>>> >>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>> // and given tangent directions at its ends >>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>> bz[3] ], >>>>>>> s1 = eps, >>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>> echo(smin=s) >>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>> >>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>> let( s12 = (s1+s2)/2, >>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>> e1<e2 ? s1 : s2 >>>>>>> : >>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) ) >>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>> s3 >>>>>>> : >>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>> //echo(e3=e3) >>>>>>> abs(e3-e12)/e12<eps ? >>>>>>> s3 : >>>>>>> e3<e12 ? >>>>>>> s3<s12 ? >>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>> : >>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>> : >>>>>>> s3<s12 ? >>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>> : >>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>> >>>>>>> >>>>>>> The full code is annexed. >>>>>>> >>>>>>> In the experiments I have done with the code, the plot of the cubic >>>>>>> energy against the balance parameter s has the shape of an U with an almost >>>>>>> horizontal bottom. This shows that the effect of medium-sized changes of >>>>>>> the optimal balance does not produce significant changes of the cubic >>>>>>> energy. In special, in your case of a strip going down from a fixed pole to >>>>>>> a moving table clamped point, the optimal balance will change slowly from >>>>>>> 0.5 (when the two end points are level) to 1 (when the strip is fully >>>>>>> stretched). That means the balance of the cubic endpoint derivatives in the >>>>>>> optimal solution is slightly favorable to the fixed point if the strip is >>>>>>> never fully stretched. So, your assumption that "keeping the two inner >>>>>>> control points level" would do the trick is not confirmed by my results. >>>>>>> >>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>> >>>>>>>> I don't know if this has a mathematical validity but simple keeping >>>>>>>> the two inner control points level with each other seems to produce a curve >>>>>>>> that matches a strip held against the screen fairly well. >>>>>>>> ​ >>>>>>>> The length of the strip is only 9mm longer compared to the version >>>>>>>> with the control points equidistant below the end points. >>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> Discuss@lists.openscad.org >>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>> nscad.org >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
RP
Ronaldo Persiano
Tue, Dec 26, 2017 4:57 PM

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the energy is
only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have made
some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0, 0,
-139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

Would you mind to provide me the geometric data (endpoint coordinates
and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com wrote:

Interesting. I will have to combine with my code and put them side
by side. If I put my length and dimension into your code the result looks a
lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is objective
of an iterative search. The search for the cubic with minimum energy is
done iteratively narrowing an interval (s1,s2) of balances that contains
the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) )
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the cubic
energy against the balance parameter s has the shape of an U with an almost
horizontal bottom. This shows that the effect of medium-sized changes of
the optimal balance does not produce significant changes of the cubic
energy. In special, in your case of a strip going down from a fixed pole to
a moving table clamped point, the optimal balance will change slowly from
0.5 (when the two end points are level) to 1 (when the strip is fully
stretched). That means the balance of the cubic endpoint derivatives in the
optimal solution is slightly favorable to the fixed point if the strip is
never fully stretched. So, your assumption that "keeping the two inner
control points level" would do the trick is not confirmed by my results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the version
with the control points equidistant below the end points.

Yes. However the two inner Bezier points are not level when the table travels up. 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: > With that function your curve is nearly the same as mine and the energy is > only 0.5% lower. > > > ​ > > On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> > wrote: > >> You are right. The energy function was wrong. At some point, I have made >> some change in it. >> >> The correct (I hope) energy function should be: >> >> function BzEnergy(b, n=8) = >> let( bs = subdivBezier3(b, n) ) >> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >> >> >> With this function, the plot of the cubic energy as a function of the >> balance s has a sharper minimum what is more reasonable. >> >> I will try your data and compare. >> >> >> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >> >>> The starting point is: >>> >>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>> -108.35]]; >>> length=180; >>> >>> After I adjust the control points for length I get [[0, 0, 0], [0, 0, >>> -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>> >>> On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com> >>> wrote: >>> >>>> Would you mind to provide me the geometric data (endpoint coordinates >>>> and strip length) of this case? >>>> >>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>> >>>>> Whoops >>>>> >>>>> >>>>> ​ >>>>> >>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>>> >>>>>> Here is my curve in red and its control points in blue alongside >>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>> energy for mine which is hard to believe because mine has a more >>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>> yours, so I think there must be a bug in your energy function. >>>>>> >>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> wrote: >>>>>> >>>>>>> Interesting. I will have to combine with my code and put them side >>>>>>> by side. If I put my length and dimension into your code the result looks a >>>>>>> lot tighter and doesn't match what my real strip does. >>>>>>> >>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>> >>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>> energy. >>>>>>>> >>>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>> order to reduce the cubic energy. >>>>>>>> >>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>> function balance(bz,s) = >>>>>>>> [ bz[0], >>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>> bz[3] ]; >>>>>>>> >>>>>>>> >>>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>>> AdjustBezier() and its energy is calculated. >>>>>>>> >>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>> >>>>>>>> >>>>>>>> To find the balance that leads to the minimum energy is objective >>>>>>>> of an iterative search. The search for the cubic with minimum energy is >>>>>>>> done iteratively narrowing an interval (s1,s2) of balances that contains >>>>>>>> the best balance. >>>>>>>> >>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>> // and given tangent directions at its ends >>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>> bz[3] ], >>>>>>>> s1 = eps, >>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>> echo(smin=s) >>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>> >>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>> e1<e2 ? s1 : s2 >>>>>>>> : >>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) ) >>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>> s3 >>>>>>>> : >>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>> //echo(e3=e3) >>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>> s3 : >>>>>>>> e3<e12 ? >>>>>>>> s3<s12 ? >>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>> : >>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>> : >>>>>>>> s3<s12 ? >>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>> : >>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>> >>>>>>>> >>>>>>>> The full code is annexed. >>>>>>>> >>>>>>>> In the experiments I have done with the code, the plot of the cubic >>>>>>>> energy against the balance parameter s has the shape of an U with an almost >>>>>>>> horizontal bottom. This shows that the effect of medium-sized changes of >>>>>>>> the optimal balance does not produce significant changes of the cubic >>>>>>>> energy. In special, in your case of a strip going down from a fixed pole to >>>>>>>> a moving table clamped point, the optimal balance will change slowly from >>>>>>>> 0.5 (when the two end points are level) to 1 (when the strip is fully >>>>>>>> stretched). That means the balance of the cubic endpoint derivatives in the >>>>>>>> optimal solution is slightly favorable to the fixed point if the strip is >>>>>>>> never fully stretched. So, your assumption that "keeping the two inner >>>>>>>> control points level" would do the trick is not confirmed by my results. >>>>>>>> >>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>> >>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>> ​ >>>>>>>>> The length of the strip is only 9mm longer compared to the version >>>>>>>>> with the control points equidistant below the end points. >>>>>>>>> >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> Discuss@lists.openscad.org >>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>> nscad.org >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
RP
Ronaldo Persiano
Tue, Dec 26, 2017 5:06 PM

How far is my solution from the shape of the real strip?

Em 26 de dez de 2017 14:57, "Ronaldo Persiano" rcmpersiano@gmail.com
escreveu:

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the energy
is only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have made
some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0, 0,
-139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

Would you mind to provide me the geometric data (endpoint coordinates
and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com wrote:

Interesting. I will have to combine with my code and put them side
by side. If I put my length and dimension into your code the result looks a
lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is objective
of an iterative search. The search for the cubic with minimum energy is
done iteratively narrowing an interval (s1,s2) of balances that contains
the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) )
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the
cubic energy against the balance parameter s has the shape of an U with an
almost horizontal bottom. This shows that the effect of medium-sized
changes of the optimal balance does not produce significant changes of the
cubic energy. In special, in your case of a strip going down from a fixed
pole to a moving table clamped point, the optimal balance will change
slowly from 0.5 (when the two end points are level) to 1 (when the strip is
fully stretched). That means the balance of the cubic endpoint derivatives
in the optimal solution is slightly favorable to the fixed point if the
strip is never fully stretched. So, your assumption that "keeping the two
inner control points level" would do the trick is not confirmed by my
results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the
version with the control points equidistant below the end points.

How far is my solution from the shape of the real strip? Em 26 de dez de 2017 14:57, "Ronaldo Persiano" <rcmpersiano@gmail.com> escreveu: > Yes. However the two inner Bezier points are not level when the table > travels up. > > 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: > >> With that function your curve is nearly the same as mine and the energy >> is only 0.5% lower. >> >> >> ​ >> >> On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> >> wrote: >> >>> You are right. The energy function was wrong. At some point, I have made >>> some change in it. >>> >>> The correct (I hope) energy function should be: >>> >>> function BzEnergy(b, n=8) = >>> let( bs = subdivBezier3(b, n) ) >>> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >>> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >>> >>> >>> With this function, the plot of the cubic energy as a function of the >>> balance s has a sharper minimum what is more reasonable. >>> >>> I will try your data and compare. >>> >>> >>> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >>> >>>> The starting point is: >>>> >>>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>>> -108.35]]; >>>> length=180; >>>> >>>> After I adjust the control points for length I get [[0, 0, 0], [0, 0, >>>> -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>>> >>>> On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com> >>>> wrote: >>>> >>>>> Would you mind to provide me the geometric data (endpoint coordinates >>>>> and strip length) of this case? >>>>> >>>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>>> >>>>>> Whoops >>>>>> >>>>>> >>>>>> ​ >>>>>> >>>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>>>> >>>>>>> Here is my curve in red and its control points in blue alongside >>>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>>> energy for mine which is hard to believe because mine has a more >>>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>>> yours, so I think there must be a bug in your energy function. >>>>>>> >>>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> wrote: >>>>>>> >>>>>>>> Interesting. I will have to combine with my code and put them side >>>>>>>> by side. If I put my length and dimension into your code the result looks a >>>>>>>> lot tighter and doesn't match what my real strip does. >>>>>>>> >>>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>> >>>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>>> energy. >>>>>>>>> >>>>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>>> order to reduce the cubic energy. >>>>>>>>> >>>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>>> function balance(bz,s) = >>>>>>>>> [ bz[0], >>>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>>> bz[3] ]; >>>>>>>>> >>>>>>>>> >>>>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>>>> AdjustBezier() and its energy is calculated. >>>>>>>>> >>>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>>> >>>>>>>>> >>>>>>>>> To find the balance that leads to the minimum energy is objective >>>>>>>>> of an iterative search. The search for the cubic with minimum energy is >>>>>>>>> done iteratively narrowing an interval (s1,s2) of balances that contains >>>>>>>>> the best balance. >>>>>>>>> >>>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>>> // and given tangent directions at its ends >>>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>>> bz[3] ], >>>>>>>>> s1 = eps, >>>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>>> echo(smin=s) >>>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>>> >>>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>>> e1<e2 ? s1 : s2 >>>>>>>>> : >>>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) ) >>>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>>> s3 >>>>>>>>> : >>>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>>> //echo(e3=e3) >>>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>>> s3 : >>>>>>>>> e3<e12 ? >>>>>>>>> s3<s12 ? >>>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>>> : >>>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>>> : >>>>>>>>> s3<s12 ? >>>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>>> : >>>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>>> >>>>>>>>> >>>>>>>>> The full code is annexed. >>>>>>>>> >>>>>>>>> In the experiments I have done with the code, the plot of the >>>>>>>>> cubic energy against the balance parameter s has the shape of an U with an >>>>>>>>> almost horizontal bottom. This shows that the effect of medium-sized >>>>>>>>> changes of the optimal balance does not produce significant changes of the >>>>>>>>> cubic energy. In special, in your case of a strip going down from a fixed >>>>>>>>> pole to a moving table clamped point, the optimal balance will change >>>>>>>>> slowly from 0.5 (when the two end points are level) to 1 (when the strip is >>>>>>>>> fully stretched). That means the balance of the cubic endpoint derivatives >>>>>>>>> in the optimal solution is slightly favorable to the fixed point if the >>>>>>>>> strip is never fully stretched. So, your assumption that "keeping the two >>>>>>>>> inner control points level" would do the trick is not confirmed by my >>>>>>>>> results. >>>>>>>>> >>>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>> >>>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>>> ​ >>>>>>>>>> The length of the strip is only 9mm longer compared to the >>>>>>>>>> version with the control points equidistant below the end points. >>>>>>>>>> >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> Discuss@lists.openscad.org >>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>> nscad.org >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> Discuss@lists.openscad.org >>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >
NH
nop head
Tue, Dec 26, 2017 5:33 PM

With the new function they are so close it is hard to tell. They match
exactly when the ends are level, drift out about 3.5% on energy half way up
and then get close again at the top. If I was to call it I think yours is
the most accurate to the strip but mine is accurate enough at the end
points, which is only case that needs to be accurate for the BOM.
Particularly as the critical prediction is the length to get the correct
minimum Z. The minimum z is only 0.2mm different.

It is very odd that they converge exactly just before my end point and then
diverge rapidly again.

With this
h= 108*$t;
bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]];
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

They converge around about t = 0.945. Very odd.

On 26 December 2017 at 17:06, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

How far is my solution from the shape of the real strip?

Em 26 de dez de 2017 14:57, "Ronaldo Persiano" rcmpersiano@gmail.com
escreveu:

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the energy
is only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have
made some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0, 0,
-139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

Would you mind to provide me the geometric data (endpoint coordinates
and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com wrote:

Interesting. I will have to combine with my code and put them side
by side. If I put my length and dimension into your code the result looks a
lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is objective
of an iterative search. The search for the cubic with minimum energy is
done iteratively narrowing an interval (s1,s2) of balances that contains
the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) )
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the
cubic energy against the balance parameter s has the shape of an U with an
almost horizontal bottom. This shows that the effect of medium-sized
changes of the optimal balance does not produce significant changes of the
cubic energy. In special, in your case of a strip going down from a fixed
pole to a moving table clamped point, the optimal balance will change
slowly from 0.5 (when the two end points are level) to 1 (when the strip is
fully stretched). That means the balance of the cubic endpoint derivatives
in the optimal solution is slightly favorable to the fixed point if the
strip is never fully stretched. So, your assumption that "keeping the two
inner control points level" would do the trick is not confirmed by my
results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the
version with the control points equidistant below the end points.

With the new function they are so close it is hard to tell. They match exactly when the ends are level, drift out about 3.5% on energy half way up and then get close again at the top. If I was to call it I think yours is the most accurate to the strip but mine is accurate enough at the end points, which is only case that needs to be accurate for the BOM. Particularly as the critical prediction is the length to get the correct minimum Z. The minimum z is only 0.2mm different. It is very odd that they converge exactly just before my end point and then diverge rapidly again. With this h= 108*$t; bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]]; bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; They converge around about t = 0.945. Very odd. On 26 December 2017 at 17:06, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > How far is my solution from the shape of the real strip? > > Em 26 de dez de 2017 14:57, "Ronaldo Persiano" <rcmpersiano@gmail.com> > escreveu: > >> Yes. However the two inner Bezier points are not level when the table >> travels up. >> >> 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: >> >>> With that function your curve is nearly the same as mine and the energy >>> is only 0.5% lower. >>> >>> >>> ​ >>> >>> On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> >>> wrote: >>> >>>> You are right. The energy function was wrong. At some point, I have >>>> made some change in it. >>>> >>>> The correct (I hope) energy function should be: >>>> >>>> function BzEnergy(b, n=8) = >>>> let( bs = subdivBezier3(b, n) ) >>>> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >>>> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >>>> >>>> >>>> With this function, the plot of the cubic energy as a function of the >>>> balance s has a sharper minimum what is more reasonable. >>>> >>>> I will try your data and compare. >>>> >>>> >>>> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >>>> >>>>> The starting point is: >>>>> >>>>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>>>> -108.35]]; >>>>> length=180; >>>>> >>>>> After I adjust the control points for length I get [[0, 0, 0], [0, 0, >>>>> -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>>>> >>>>> On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com> >>>>> wrote: >>>>> >>>>>> Would you mind to provide me the geometric data (endpoint coordinates >>>>>> and strip length) of this case? >>>>>> >>>>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>> >>>>>>> Whoops >>>>>>> >>>>>>> >>>>>>> ​ >>>>>>> >>>>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>>>>> >>>>>>>> Here is my curve in red and its control points in blue alongside >>>>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>>>> energy for mine which is hard to believe because mine has a more >>>>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>>>> yours, so I think there must be a bug in your energy function. >>>>>>>> >>>>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> wrote: >>>>>>>> >>>>>>>>> Interesting. I will have to combine with my code and put them side >>>>>>>>> by side. If I put my length and dimension into your code the result looks a >>>>>>>>> lot tighter and doesn't match what my real strip does. >>>>>>>>> >>>>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>>> >>>>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>>>> energy. >>>>>>>>>> >>>>>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>>>> order to reduce the cubic energy. >>>>>>>>>> >>>>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>>>> function balance(bz,s) = >>>>>>>>>> [ bz[0], >>>>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>>>> bz[3] ]; >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>>>>> AdjustBezier() and its energy is calculated. >>>>>>>>>> >>>>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> To find the balance that leads to the minimum energy is objective >>>>>>>>>> of an iterative search. The search for the cubic with minimum energy is >>>>>>>>>> done iteratively narrowing an interval (s1,s2) of balances that contains >>>>>>>>>> the best balance. >>>>>>>>>> >>>>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>>>> // and given tangent directions at its ends >>>>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>>>> bz[3] ], >>>>>>>>>> s1 = eps, >>>>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>>>> echo(smin=s) >>>>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>>>> >>>>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>>>> e1<e2 ? s1 : s2 >>>>>>>>>> : >>>>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) ) >>>>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>>>> s3 >>>>>>>>>> : >>>>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>>>> //echo(e3=e3) >>>>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>>>> s3 : >>>>>>>>>> e3<e12 ? >>>>>>>>>> s3<s12 ? >>>>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>>>> : >>>>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>>>> : >>>>>>>>>> s3<s12 ? >>>>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>>>> : >>>>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> The full code is annexed. >>>>>>>>>> >>>>>>>>>> In the experiments I have done with the code, the plot of the >>>>>>>>>> cubic energy against the balance parameter s has the shape of an U with an >>>>>>>>>> almost horizontal bottom. This shows that the effect of medium-sized >>>>>>>>>> changes of the optimal balance does not produce significant changes of the >>>>>>>>>> cubic energy. In special, in your case of a strip going down from a fixed >>>>>>>>>> pole to a moving table clamped point, the optimal balance will change >>>>>>>>>> slowly from 0.5 (when the two end points are level) to 1 (when the strip is >>>>>>>>>> fully stretched). That means the balance of the cubic endpoint derivatives >>>>>>>>>> in the optimal solution is slightly favorable to the fixed point if the >>>>>>>>>> strip is never fully stretched. So, your assumption that "keeping the two >>>>>>>>>> inner control points level" would do the trick is not confirmed by my >>>>>>>>>> results. >>>>>>>>>> >>>>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>>> >>>>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>>>> ​ >>>>>>>>>>> The length of the strip is only 9mm longer compared to the >>>>>>>>>>> version with the control points equidistant below the end points. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> OpenSCAD mailing list >>>>>>>>>> Discuss@lists.openscad.org >>>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>>> nscad.org >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> Discuss@lists.openscad.org >>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>> nscad.org >>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> Discuss@lists.openscad.org >>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
RP
Ronaldo Persiano
Tue, Dec 26, 2017 5:59 PM

It is not odd to me. It was a coincidence that you get an almost level
inner control points at the table lower position with the given length you
have chosen. The factor that changes the bending energy for a given length
is the balance between the two endpoint derivative and not the inner point
positions. Along the table path from top to bottom the balance goes from
0.5 to 0.798 and that is what maters.

2017-12-26 15:33 GMT-02:00 nop head nop.head@gmail.com:

With the new function they are so close it is hard to tell. They match
exactly when the ends are level, drift out about 3.5% on energy half way up
and then get close again at the top. If I was to call it I think yours is
the most accurate to the strip but mine is accurate enough at the end
points, which is only case that needs to be accurate for the BOM.
Particularly as the critical prediction is the length to get the correct
minimum Z. The minimum z is only 0.2mm different.

It is very odd that they converge exactly just before my end point and
then diverge rapidly again.

With this
h= 108*$t;
bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]];
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

They converge around about t = 0.945. Very odd.

On 26 December 2017 at 17:06, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

How far is my solution from the shape of the real strip?

Em 26 de dez de 2017 14:57, "Ronaldo Persiano" rcmpersiano@gmail.com
escreveu:

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the energy
is only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have
made some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0,
0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com

wrote:

Would you mind to provide me the geometric data (endpoint
coordinates and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com wrote:

Interesting. I will have to combine with my code and put them
side by side. If I put my length and dimension into your code the result
looks a lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is
objective of an iterative search. The search for the cubic with minimum
energy is done iteratively narrowing an interval (s1,s2) of balances that
contains the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) )
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the
cubic energy against the balance parameter s has the shape of an U with an
almost horizontal bottom. This shows that the effect of medium-sized
changes of the optimal balance does not produce significant changes of the
cubic energy. In special, in your case of a strip going down from a fixed
pole to a moving table clamped point, the optimal balance will change
slowly from 0.5 (when the two end points are level) to 1 (when the strip is
fully stretched). That means the balance of the cubic endpoint derivatives
in the optimal solution is slightly favorable to the fixed point if the
strip is never fully stretched. So, your assumption that "keeping the two
inner control points level" would do the trick is not confirmed by my
results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the
version with the control points equidistant below the end points.

It is not odd to me. It was a coincidence that you get an almost level inner control points at the table lower position with the given length you have chosen. The factor that changes the bending energy for a given length is the balance between the two endpoint derivative and not the inner point positions. Along the table path from top to bottom the balance goes from 0.5 to 0.798 and that is what maters. 2017-12-26 15:33 GMT-02:00 nop head <nop.head@gmail.com>: > With the new function they are so close it is hard to tell. They match > exactly when the ends are level, drift out about 3.5% on energy half way up > and then get close again at the top. If I was to call it I think yours is > the most accurate to the strip but mine is accurate enough at the end > points, which is only case that needs to be accurate for the BOM. > Particularly as the critical prediction is the length to get the correct > minimum Z. The minimum z is only 0.2mm different. > > It is very odd that they converge exactly just before my end point and > then diverge rapidly again. > > With this > h= 108*$t; > bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]]; > bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; > > They converge around about t = 0.945. Very odd. > > > > On 26 December 2017 at 17:06, Ronaldo Persiano <rcmpersiano@gmail.com> > wrote: > >> How far is my solution from the shape of the real strip? >> >> Em 26 de dez de 2017 14:57, "Ronaldo Persiano" <rcmpersiano@gmail.com> >> escreveu: >> >>> Yes. However the two inner Bezier points are not level when the table >>> travels up. >>> >>> 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: >>> >>>> With that function your curve is nearly the same as mine and the energy >>>> is only 0.5% lower. >>>> >>>> >>>> ​ >>>> >>>> On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> >>>> wrote: >>>> >>>>> You are right. The energy function was wrong. At some point, I have >>>>> made some change in it. >>>>> >>>>> The correct (I hope) energy function should be: >>>>> >>>>> function BzEnergy(b, n=8) = >>>>> let( bs = subdivBezier3(b, n) ) >>>>> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >>>>> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >>>>> >>>>> >>>>> With this function, the plot of the cubic energy as a function of the >>>>> balance s has a sharper minimum what is more reasonable. >>>>> >>>>> I will try your data and compare. >>>>> >>>>> >>>>> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >>>>> >>>>>> The starting point is: >>>>>> >>>>>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>>>>> -108.35]]; >>>>>> length=180; >>>>>> >>>>>> After I adjust the control points for length I get [[0, 0, 0], [0, >>>>>> 0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>>>>> >>>>>> On 26 December 2017 at 16:15, Ronaldo Persiano <rcmpersiano@gmail.com >>>>>> > wrote: >>>>>> >>>>>>> Would you mind to provide me the geometric data (endpoint >>>>>>> coordinates and strip length) of this case? >>>>>>> >>>>>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>> >>>>>>>> Whoops >>>>>>>> >>>>>>>> >>>>>>>> ​ >>>>>>>> >>>>>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>>>>>> >>>>>>>>> Here is my curve in red and its control points in blue alongside >>>>>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>>>>> energy for mine which is hard to believe because mine has a more >>>>>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>>>>> yours, so I think there must be a bug in your energy function. >>>>>>>>> >>>>>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> wrote: >>>>>>>>> >>>>>>>>>> Interesting. I will have to combine with my code and put them >>>>>>>>>> side by side. If I put my length and dimension into your code the result >>>>>>>>>> looks a lot tighter and doesn't match what my real strip does. >>>>>>>>>> >>>>>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>>>> >>>>>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>>>>> energy. >>>>>>>>>>> >>>>>>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>>>>> order to reduce the cubic energy. >>>>>>>>>>> >>>>>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>>>>> function balance(bz,s) = >>>>>>>>>>> [ bz[0], >>>>>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>>>>> bz[3] ]; >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>>>>>> AdjustBezier() and its energy is calculated. >>>>>>>>>>> >>>>>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> To find the balance that leads to the minimum energy is >>>>>>>>>>> objective of an iterative search. The search for the cubic with minimum >>>>>>>>>>> energy is done iteratively narrowing an interval (s1,s2) of balances that >>>>>>>>>>> contains the best balance. >>>>>>>>>>> >>>>>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>>>>> // and given tangent directions at its ends >>>>>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>>>>> bz[3] ], >>>>>>>>>>> s1 = eps, >>>>>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>>>>> echo(smin=s) >>>>>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>>>>> >>>>>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>>>>> e1<e2 ? s1 : s2 >>>>>>>>>>> : >>>>>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) ) >>>>>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>>>>> s3 >>>>>>>>>>> : >>>>>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>>>>> //echo(e3=e3) >>>>>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>>>>> s3 : >>>>>>>>>>> e3<e12 ? >>>>>>>>>>> s3<s12 ? >>>>>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>>>>> : >>>>>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>>>>> : >>>>>>>>>>> s3<s12 ? >>>>>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>>>>> : >>>>>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> The full code is annexed. >>>>>>>>>>> >>>>>>>>>>> In the experiments I have done with the code, the plot of the >>>>>>>>>>> cubic energy against the balance parameter s has the shape of an U with an >>>>>>>>>>> almost horizontal bottom. This shows that the effect of medium-sized >>>>>>>>>>> changes of the optimal balance does not produce significant changes of the >>>>>>>>>>> cubic energy. In special, in your case of a strip going down from a fixed >>>>>>>>>>> pole to a moving table clamped point, the optimal balance will change >>>>>>>>>>> slowly from 0.5 (when the two end points are level) to 1 (when the strip is >>>>>>>>>>> fully stretched). That means the balance of the cubic endpoint derivatives >>>>>>>>>>> in the optimal solution is slightly favorable to the fixed point if the >>>>>>>>>>> strip is never fully stretched. So, your assumption that "keeping the two >>>>>>>>>>> inner control points level" would do the trick is not confirmed by my >>>>>>>>>>> results. >>>>>>>>>>> >>>>>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>>>> >>>>>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>>>>> ​ >>>>>>>>>>>> The length of the strip is only 9mm longer compared to the >>>>>>>>>>>> version with the control points equidistant below the end points. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> OpenSCAD mailing list >>>>>>>>>>> Discuss@lists.openscad.org >>>>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>>>> nscad.org >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> Discuss@lists.openscad.org >>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>> nscad.org >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> Discuss@lists.openscad.org >>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>> nscad.org >>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> Discuss@lists.openscad.org >>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
NH
nop head
Tue, Dec 26, 2017 8:58 PM

Although your s value covers that range your control points are never far
from level and the curves are never much different in shape or minimum z
over the full movement. What I find odd is both versions exactly match at
three points. No surprise they match in the middle.

For my code to work I need to start with the control points level because I
adjust them as follows

function adjust_bezier(v, r) = let(extension = (v[1] - v[0]) * (r - 1))
[v[0], v[1] + extension, v[2] + extension, v[3]];

Your code works with my control points. If I give it control points that
have equal endpoint lengths like your original code then it produces a
slightly different result that actually has higher energy at the end point
than mine.

E.g.
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85 + h], [0, 79.721, h]];
bzcp2=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

It gives a slightly lower energy result staring with bzcp2 when h = 108.
Probably a numerical accuracy issue.

I made a video and that seems to show some numerical instability.

https://youtu.be/6t8Taul_4Rw

On 26 December 2017 at 17:59, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

It is not odd to me. It was a coincidence that you get an almost level
inner control points at the table lower position with the given length you
have chosen. The factor that changes the bending energy for a given length
is the balance between the two endpoint derivative and not the inner point
positions. Along the table path from top to bottom the balance goes from
0.5 to 0.798 and that is what maters.

2017-12-26 15:33 GMT-02:00 nop head nop.head@gmail.com:

With the new function they are so close it is hard to tell. They match
exactly when the ends are level, drift out about 3.5% on energy half way up
and then get close again at the top. If I was to call it I think yours is
the most accurate to the strip but mine is accurate enough at the end
points, which is only case that needs to be accurate for the BOM.
Particularly as the critical prediction is the length to get the correct
minimum Z. The minimum z is only 0.2mm different.

It is very odd that they converge exactly just before my end point and
then diverge rapidly again.

With this
h= 108*$t;
bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]];
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

They converge around about t = 0.945. Very odd.

On 26 December 2017 at 17:06, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

How far is my solution from the shape of the real strip?

Em 26 de dez de 2017 14:57, "Ronaldo Persiano" rcmpersiano@gmail.com
escreveu:

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the
energy is only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right. The energy function was wrong. At some point, I have
made some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of the
balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0,
0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Would you mind to provide me the geometric data (endpoint
coordinates and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com
wrote:

Interesting. I will have to combine with my code and put them
side by side. If I put my length and dimension into your code the result
looks a lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the desired
length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length by
AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is
objective of an iterative search. The search for the cubic with minimum
energy is done iteratively narrowing an interval (s1,s2) of balances that
contains the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps)
)
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the
cubic energy against the balance parameter s has the shape of an U with an
almost horizontal bottom. This shows that the effect of medium-sized
changes of the optimal balance does not produce significant changes of the
cubic energy. In special, in your case of a strip going down from a fixed
pole to a moving table clamped point, the optimal balance will change
slowly from 0.5 (when the two end points are level) to 1 (when the strip is
fully stretched). That means the balance of the cubic endpoint derivatives
in the optimal solution is slightly favorable to the fixed point if the
strip is never fully stretched. So, your assumption that "keeping the two
inner control points level" would do the trick is not confirmed by my
results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the
version with the control points equidistant below the end points.

Although your s value covers that range your control points are never far from level and the curves are never much different in shape or minimum z over the full movement. What I find odd is both versions exactly match at three points. No surprise they match in the middle. For my code to work I need to start with the control points level because I adjust them as follows function adjust_bezier(v, r) = let(extension = (v[1] - v[0]) * (r - 1)) [v[0], v[1] + extension, v[2] + extension, v[3]]; Your code works with my control points. If I give it control points that have equal endpoint lengths like your original code then it produces a slightly different result that actually has higher energy at the end point than mine. E.g. bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85 + h], [0, 79.721, h]]; bzcp2=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; It gives a slightly lower energy result staring with bzcp2 when h = 108. Probably a numerical accuracy issue. I made a video and that seems to show some numerical instability. https://youtu.be/6t8Taul_4Rw On 26 December 2017 at 17:59, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > It is not odd to me. It was a coincidence that you get an almost level > inner control points at the table lower position with the given length you > have chosen. The factor that changes the bending energy for a given length > is the balance between the two endpoint derivative and not the inner point > positions. Along the table path from top to bottom the balance goes from > 0.5 to 0.798 and that is what maters. > > 2017-12-26 15:33 GMT-02:00 nop head <nop.head@gmail.com>: > >> With the new function they are so close it is hard to tell. They match >> exactly when the ends are level, drift out about 3.5% on energy half way up >> and then get close again at the top. If I was to call it I think yours is >> the most accurate to the strip but mine is accurate enough at the end >> points, which is only case that needs to be accurate for the BOM. >> Particularly as the critical prediction is the length to get the correct >> minimum Z. The minimum z is only 0.2mm different. >> >> It is very odd that they converge exactly just before my end point and >> then diverge rapidly again. >> >> With this >> h= 108*$t; >> bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]]; >> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; >> >> They converge around about t = 0.945. Very odd. >> >> >> >> On 26 December 2017 at 17:06, Ronaldo Persiano <rcmpersiano@gmail.com> >> wrote: >> >>> How far is my solution from the shape of the real strip? >>> >>> Em 26 de dez de 2017 14:57, "Ronaldo Persiano" <rcmpersiano@gmail.com> >>> escreveu: >>> >>>> Yes. However the two inner Bezier points are not level when the table >>>> travels up. >>>> >>>> 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: >>>> >>>>> With that function your curve is nearly the same as mine and the >>>>> energy is only 0.5% lower. >>>>> >>>>> >>>>> ​ >>>>> >>>>> On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com> >>>>> wrote: >>>>> >>>>>> You are right. The energy function was wrong. At some point, I have >>>>>> made some change in it. >>>>>> >>>>>> The correct (I hope) energy function should be: >>>>>> >>>>>> function BzEnergy(b, n=8) = >>>>>> let( bs = subdivBezier3(b, n) ) >>>>>> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >>>>>> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >>>>>> >>>>>> >>>>>> With this function, the plot of the cubic energy as a function of the >>>>>> balance s has a sharper minimum what is more reasonable. >>>>>> >>>>>> I will try your data and compare. >>>>>> >>>>>> >>>>>> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>> >>>>>>> The starting point is: >>>>>>> >>>>>>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>>>>>> -108.35]]; >>>>>>> length=180; >>>>>>> >>>>>>> After I adjust the control points for length I get [[0, 0, 0], [0, >>>>>>> 0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>>>>>> >>>>>>> On 26 December 2017 at 16:15, Ronaldo Persiano < >>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>> >>>>>>>> Would you mind to provide me the geometric data (endpoint >>>>>>>> coordinates and strip length) of this case? >>>>>>>> >>>>>>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>> >>>>>>>>> Whoops >>>>>>>>> >>>>>>>>> >>>>>>>>> ​ >>>>>>>>> >>>>>>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> wrote: >>>>>>>>> >>>>>>>>>> Here is my curve in red and its control points in blue alongside >>>>>>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>>>>>> energy for mine which is hard to believe because mine has a more >>>>>>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>>>>>> yours, so I think there must be a bug in your energy function. >>>>>>>>>> >>>>>>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Interesting. I will have to combine with my code and put them >>>>>>>>>>> side by side. If I put my length and dimension into your code the result >>>>>>>>>>> looks a lot tighter and doesn't match what my real strip does. >>>>>>>>>>> >>>>>>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>>>>> >>>>>>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>>>>>> energy. >>>>>>>>>>>> >>>>>>>>>>>> First note that AdjustBezier() finds the cubic with the desired >>>>>>>>>>>> length keeping the balance between the norms of the cubic endpoint >>>>>>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>>>>>> order to reduce the cubic energy. >>>>>>>>>>>> >>>>>>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>>>>>> function balance(bz,s) = >>>>>>>>>>>> [ bz[0], >>>>>>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>>>>>> bz[3] ]; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> For each balance, the cubic is adjusted to the target length by >>>>>>>>>>>> AdjustBezier() and its energy is calculated. >>>>>>>>>>>> >>>>>>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> To find the balance that leads to the minimum energy is >>>>>>>>>>>> objective of an iterative search. The search for the cubic with minimum >>>>>>>>>>>> energy is done iteratively narrowing an interval (s1,s2) of balances that >>>>>>>>>>>> contains the best balance. >>>>>>>>>>>> >>>>>>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>>>>>> // and given tangent directions at its ends >>>>>>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>>>>>> bz[3] ], >>>>>>>>>>>> s1 = eps, >>>>>>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>>>>>> echo(smin=s) >>>>>>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>>>>>> >>>>>>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>>>>>> e1<e2 ? s1 : s2 >>>>>>>>>>>> : >>>>>>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) >>>>>>>>>>>> ) >>>>>>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>>>>>> s3 >>>>>>>>>>>> : >>>>>>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>>>>>> //echo(e3=e3) >>>>>>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>>>>>> s3 : >>>>>>>>>>>> e3<e12 ? >>>>>>>>>>>> s3<s12 ? >>>>>>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>>>>>> : >>>>>>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>>>>>> : >>>>>>>>>>>> s3<s12 ? >>>>>>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>>>>>> : >>>>>>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The full code is annexed. >>>>>>>>>>>> >>>>>>>>>>>> In the experiments I have done with the code, the plot of the >>>>>>>>>>>> cubic energy against the balance parameter s has the shape of an U with an >>>>>>>>>>>> almost horizontal bottom. This shows that the effect of medium-sized >>>>>>>>>>>> changes of the optimal balance does not produce significant changes of the >>>>>>>>>>>> cubic energy. In special, in your case of a strip going down from a fixed >>>>>>>>>>>> pole to a moving table clamped point, the optimal balance will change >>>>>>>>>>>> slowly from 0.5 (when the two end points are level) to 1 (when the strip is >>>>>>>>>>>> fully stretched). That means the balance of the cubic endpoint derivatives >>>>>>>>>>>> in the optimal solution is slightly favorable to the fixed point if the >>>>>>>>>>>> strip is never fully stretched. So, your assumption that "keeping the two >>>>>>>>>>>> inner control points level" would do the trick is not confirmed by my >>>>>>>>>>>> results. >>>>>>>>>>>> >>>>>>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>>>>> >>>>>>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>>>>>> ​ >>>>>>>>>>>>> The length of the strip is only 9mm longer compared to the >>>>>>>>>>>>> version with the control points equidistant below the end points. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> OpenSCAD mailing list >>>>>>>>>>>> Discuss@lists.openscad.org >>>>>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>>>>> nscad.org >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> Discuss@lists.openscad.org >>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>> nscad.org >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> Discuss@lists.openscad.org >>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>> nscad.org >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> Discuss@lists.openscad.org >>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>> nscad.org >>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> Discuss@lists.openscad.org >>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>>> >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
NH
nop head
Wed, Dec 27, 2017 10:34 AM

I think subdivBezier3 may have a bug in it. It seems to produce a path that
has segments with zero curvature. I.e. subtracting adjacent tangents
produces zero. E.g.

path = subdivBezier3(bezier, 4);
for(i = [1 : len(path) -2])
echo(path[i+1]-path[2] - (path[i]-path[i-1]));

ECHO: [0, 0.31141, 0.258989]

ECHO: [0, 0.31141, 0.258989]

ECHO: [0, 0.272484, 0.272173]

ECHO: [0, 0, -3.55271e-015]

ECHO: [0, 0.272484, 0.272173]

ECHO: [0, 0.233558, 0.285357]

ECHO: [0, 0, 0]

ECHO: [0, 0.233558, 0.285357]

ECHO: [0, 0.194631, 0.29854]

ECHO: [0, 0, 0]

ECHO: [0, 0.194631, 0.29854]

ECHO: [0, 0.155705, 0.311724]

ECHO: [0, 0, 7.10543e-015]

ECHO: [0, 0.155705, 0.311724]

ECHO: [0, 0.116779, 0.324907]

ECHO: [0, 3.55271e-015, -7.10543e-015]

ECHO: [0, 0.116779, 0.324907]

ECHO: [0, 0.0778525, 0.338091]

ECHO: [0, 3.55271e-015, 0]

ECHO: [0, 0.0778525, 0.338091]

ECHO: [0, 0.0389263, 0.351274]

ECHO: [0, 7.10543e-015, 0]

ECHO: [0, 0.0389263, 0.351274]

ECHO: [0, 0, 0.364458]

ECHO: [0, 0, 0]

ECHO: [0, 0, 0.364458]

ECHO: [0, -0.0389263, 0.377642]

ECHO: [0, 7.10543e-015, 0]

ECHO: [0, -0.0389263, 0.377642]

ECHO: [0, -0.0778525, 0.390825]

ECHO: [0, 0, -7.10543e-015]

ECHO: [0, -0.0778525, 0.390825]

ECHO: [0, -0.116779, 0.404009]

ECHO: [0, 7.10543e-015, 0]

ECHO: [0, -0.116779, 0.404009]

ECHO: [0, -0.155705, 0.417192]

ECHO: [0, -1.42109e-014, 1.77636e-015]

ECHO: [0, -0.155705, 0.417192]

ECHO: [0, -0.194631, 0.430376]

ECHO: [0, 0, 1.77636e-015]

ECHO: [0, -0.194631, 0.430376]

ECHO: [0, -0.233558, 0.44356]

ECHO: [0, 0, 0]

ECHO: [0, -0.233558, 0.44356]

ECHO: [0, -0.272484, 0.456743]

ECHO: [0, 0, -7.10543e-015]

ECHO: [0, -0.272484, 0.456743]

ECHO: [0, -0.31141, 0.469927]

ECHO: [0, -0.31141, 0.469927]

There shouldn't be any zero curvature sections in this curve.

On 26 December 2017 at 20:58, nop head nop.head@gmail.com wrote:

Although your s value covers that range your control points are never far
from level and the curves are never much different in shape or minimum z
over the full movement. What I find odd is both versions exactly match at
three points. No surprise they match in the middle.

For my code to work I need to start with the control points level because
I adjust them as follows

function adjust_bezier(v, r) = let(extension = (v[1] - v[0]) * (r - 1))
[v[0], v[1] + extension, v[2] + extension, v[3]];

Your code works with my control points. If I give it control points that
have equal endpoint lengths like your original code then it produces a
slightly different result that actually has higher energy at the end point
than mine.

E.g.
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85 + h], [0, 79.721,
h]];
bzcp2=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

It gives a slightly lower energy result staring with bzcp2 when h = 108.
Probably a numerical accuracy issue.

I made a video and that seems to show some numerical instability.

https://youtu.be/6t8Taul_4Rw

On 26 December 2017 at 17:59, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

It is not odd to me. It was a coincidence that you get an almost level
inner control points at the table lower position with the given length you
have chosen. The factor that changes the bending energy for a given length
is the balance between the two endpoint derivative and not the inner point
positions. Along the table path from top to bottom the balance goes from
0.5 to 0.798 and that is what maters.

2017-12-26 15:33 GMT-02:00 nop head nop.head@gmail.com:

With the new function they are so close it is hard to tell. They match
exactly when the ends are level, drift out about 3.5% on energy half way up
and then get close again at the top. If I was to call it I think yours is
the most accurate to the strip but mine is accurate enough at the end
points, which is only case that needs to be accurate for the BOM.
Particularly as the critical prediction is the length to get the correct
minimum Z. The minimum z is only 0.2mm different.

It is very odd that they converge exactly just before my end point and
then diverge rapidly again.

With this
h= 108*$t;
bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]];
bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]];

They converge around about t = 0.945. Very odd.

On 26 December 2017 at 17:06, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

How far is my solution from the shape of the real strip?

Em 26 de dez de 2017 14:57, "Ronaldo Persiano" rcmpersiano@gmail.com
escreveu:

Yes. However the two inner Bezier points are not level when the table
travels up.

2017-12-26 14:51 GMT-02:00 nop head nop.head@gmail.com:

With that function your curve is nearly the same as mine and the
energy is only 0.5% lower.

On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com

wrote:

You are right. The energy function was wrong. At some point, I have
made some change in it.

The correct (I hope) energy function should be:

function BzEnergy(b, n=8) =
let( bs = subdivBezier3(b, n) )
[for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)]
*[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1);

With this function, the plot of the cubic energy as a function of
the balance s has a sharper minimum what is more reasonable.

I will try your data and compare.

2017-12-26 14:21 GMT-02:00 nop head nop.head@gmail.com:

The starting point is:

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721,
-108.35]];
length=180;

After I adjust the control points for length I get  [[0, 0, 0], [0,
0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]]

On 26 December 2017 at 16:15, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Would you mind to provide me the geometric data (endpoint
coordinates and strip length) of this case?

2017-12-26 13:32 GMT-02:00 nop head nop.head@gmail.com:

Whoops

On 26 December 2017 at 15:31, nop head nop.head@gmail.com
wrote:

Here is my curve in red and its control points in blue alongside
yours with my actual geometry. Your BzEnergy function returns 12 times the
energy for mine which is hard to believe because mine has a more
distributed curvature. A strip held against the screen follows mine, not
yours, so I think there must be a bug in your energy function.

On 26 December 2017 at 14:17, nop head nop.head@gmail.com
wrote:

Interesting. I will have to combine with my code and put them
side by side. If I put my length and dimension into your code the result
looks a lot tighter and doesn't match what my real strip does.

On 25 December 2017 at 17:31, Ronaldo Persiano <
rcmpersiano@gmail.com> wrote:

Here is the code of my atempts to find the cubic with minimum
energy.

First note that AdjustBezier() finds the cubic with the
desired length keeping the balance between the norms of the cubic endpoint
derivatives. The strategy I used in the code was to change this balance in
order to reduce the cubic energy.

// for any cubic bz, it holds bz == balance(bz, 0.5)
function balance(bz,s) =
[ bz[0],
bz[0] + 2s(bz[1]-bz[0]),
bz[3] + 2*(1-s)*(bz[2]-bz[3]),
bz[3] ];

For each balance, the cubic is adjusted to the target length
by AdjustBezier() and its energy is calculated.

function BalancedEnergy(bz, s, l, eps) =
BzEnergy(AdjustBezier(balance(bz,s), l, eps));

To find the balance that leads to the minimum energy is
objective of an iterative search. The search for the cubic with minimum
energy is done iteratively narrowing an interval (s1,s2) of balances that
contains the best balance.

// Minimum energy Bezier arc with a given length l
// and given tangent directions at its ends
function BestBz(bz, l, eps=1e-3) =
let( bz2 = [  bz[0], // normalize end derivatives
bz[0]+unit(bz[1]-bz[0]),
bz[3]+unit(bz[2]-bz[3]),
bz[3] ],
s1  = eps,
en1 = BalancedEnergy(bz, s1, l, eps),
en2 = BalancedEnergy(bz, 1-s1, l, eps),
s  = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) )
echo(smin=s)
AdjustBezier(balance(bz2,s), l);

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps))
//echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12)
abs(e12-(e1+e2)/2)/e12< eps ?
e1<e2 ? s1 : s2
:
let( s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps)
)
//echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n)
abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ?
s3
:
let( e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(e3=e3)
abs(e3-e12)/e12<eps ?
s3 :
e3<e12 ?
s3<s12 ?
_bestS(bz,l,s1,s12,e1,e12,eps,n-1)
:
_bestS(bz,l,s12,s2,e12,e2,eps,n-1)
:
s3<s12 ?
_bestS(bz,l,s3,s2,e3,e2,eps,n-1)
:
_bestS(bz,l,s1,s3,e1,e3,eps,n-1);

The full code is annexed.

In the experiments I have done with the code, the plot of the
cubic energy against the balance parameter s has the shape of an U with an
almost horizontal bottom. This shows that the effect of medium-sized
changes of the optimal balance does not produce significant changes of the
cubic energy. In special, in your case of a strip going down from a fixed
pole to a moving table clamped point, the optimal balance will change
slowly from 0.5 (when the two end points are level) to 1 (when the strip is
fully stretched). That means the balance of the cubic endpoint derivatives
in the optimal solution is slightly favorable to the fixed point if the
strip is never fully stretched. So, your assumption that "keeping the two
inner control points level" would do the trick is not confirmed by my
results.

2017-12-23 10:44 GMT-02:00 nop head nop.head@gmail.com:

I don't know if this has a mathematical validity but simple
keeping the two inner control points level with each other seems to produce
a curve that matches a strip held against the screen fairly well.

The length of the strip is only 9mm longer compared to the
version with the control points equidistant below the end points.

I think subdivBezier3 may have a bug in it. It seems to produce a path that has segments with zero curvature. I.e. subtracting adjacent tangents produces zero. E.g. path = subdivBezier3(bezier, 4); for(i = [1 : len(path) -2]) echo(path[i+1]-path[2] - (path[i]-path[i-1])); ECHO: [0, 0.31141, 0.258989] ECHO: [0, 0.31141, 0.258989] ECHO: [0, 0.272484, 0.272173] ECHO: [0, 0, -3.55271e-015] ECHO: [0, 0.272484, 0.272173] ECHO: [0, 0.233558, 0.285357] ECHO: [0, 0, 0] ECHO: [0, 0.233558, 0.285357] ECHO: [0, 0.194631, 0.29854] ECHO: [0, 0, 0] ECHO: [0, 0.194631, 0.29854] ECHO: [0, 0.155705, 0.311724] ECHO: [0, 0, 7.10543e-015] ECHO: [0, 0.155705, 0.311724] ECHO: [0, 0.116779, 0.324907] ECHO: [0, 3.55271e-015, -7.10543e-015] ECHO: [0, 0.116779, 0.324907] ECHO: [0, 0.0778525, 0.338091] ECHO: [0, 3.55271e-015, 0] ECHO: [0, 0.0778525, 0.338091] ECHO: [0, 0.0389263, 0.351274] ECHO: [0, 7.10543e-015, 0] ECHO: [0, 0.0389263, 0.351274] ECHO: [0, 0, 0.364458] ECHO: [0, 0, 0] ECHO: [0, 0, 0.364458] ECHO: [0, -0.0389263, 0.377642] ECHO: [0, 7.10543e-015, 0] ECHO: [0, -0.0389263, 0.377642] ECHO: [0, -0.0778525, 0.390825] ECHO: [0, 0, -7.10543e-015] ECHO: [0, -0.0778525, 0.390825] ECHO: [0, -0.116779, 0.404009] ECHO: [0, 7.10543e-015, 0] ECHO: [0, -0.116779, 0.404009] ECHO: [0, -0.155705, 0.417192] ECHO: [0, -1.42109e-014, 1.77636e-015] ECHO: [0, -0.155705, 0.417192] ECHO: [0, -0.194631, 0.430376] ECHO: [0, 0, 1.77636e-015] ECHO: [0, -0.194631, 0.430376] ECHO: [0, -0.233558, 0.44356] ECHO: [0, 0, 0] ECHO: [0, -0.233558, 0.44356] ECHO: [0, -0.272484, 0.456743] ECHO: [0, 0, -7.10543e-015] ECHO: [0, -0.272484, 0.456743] ECHO: [0, -0.31141, 0.469927] ECHO: [0, -0.31141, 0.469927] There shouldn't be any zero curvature sections in this curve. On 26 December 2017 at 20:58, nop head <nop.head@gmail.com> wrote: > Although your s value covers that range your control points are never far > from level and the curves are never much different in shape or minimum z > over the full movement. What I find odd is both versions exactly match at > three points. No surprise they match in the middle. > > For my code to work I need to start with the control points level because > I adjust them as follows > > function adjust_bezier(v, r) = let(extension = (v[1] - v[0]) * (r - 1)) > [v[0], v[1] + extension, v[2] + extension, v[3]]; > > Your code works with my control points. If I give it control points that > have equal endpoint lengths like your original code then it produces a > slightly different result that actually has higher energy at the end point > than mine. > > E.g. > bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85 + h], [0, 79.721, > h]]; > bzcp2=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; > > It gives a slightly lower energy result staring with bzcp2 when h = 108. > Probably a numerical accuracy issue. > > I made a video and that seems to show some numerical instability. > > https://youtu.be/6t8Taul_4Rw > > On 26 December 2017 at 17:59, Ronaldo Persiano <rcmpersiano@gmail.com> > wrote: > >> It is not odd to me. It was a coincidence that you get an almost level >> inner control points at the table lower position with the given length you >> have chosen. The factor that changes the bending energy for a given length >> is the balance between the two endpoint derivative and not the inner point >> positions. Along the table path from top to bottom the balance goes from >> 0.5 to 0.798 and that is what maters. >> >> 2017-12-26 15:33 GMT-02:00 nop head <nop.head@gmail.com>: >> >>> With the new function they are so close it is hard to tell. They match >>> exactly when the ends are level, drift out about 3.5% on energy half way up >>> and then get close again at the top. If I was to call it I think yours is >>> the most accurate to the strip but mine is accurate enough at the end >>> points, which is only case that needs to be accurate for the BOM. >>> Particularly as the critical prediction is the length to get the correct >>> minimum Z. The minimum z is only 0.2mm different. >>> >>> It is very odd that they converge exactly just before my end point and >>> then diverge rapidly again. >>> >>> With this >>> h= 108*$t; >>> bzcp=[[0,0,0],[0,0,-50],[78,0,-50-h],[78,0,-h]]; >>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, h]]; >>> >>> They converge around about t = 0.945. Very odd. >>> >>> >>> >>> On 26 December 2017 at 17:06, Ronaldo Persiano <rcmpersiano@gmail.com> >>> wrote: >>> >>>> How far is my solution from the shape of the real strip? >>>> >>>> Em 26 de dez de 2017 14:57, "Ronaldo Persiano" <rcmpersiano@gmail.com> >>>> escreveu: >>>> >>>>> Yes. However the two inner Bezier points are not level when the table >>>>> travels up. >>>>> >>>>> 2017-12-26 14:51 GMT-02:00 nop head <nop.head@gmail.com>: >>>>> >>>>>> With that function your curve is nearly the same as mine and the >>>>>> energy is only 0.5% lower. >>>>>> >>>>>> >>>>>> ​ >>>>>> >>>>>> On 26 December 2017 at 16:47, Ronaldo Persiano <rcmpersiano@gmail.com >>>>>> > wrote: >>>>>> >>>>>>> You are right. The energy function was wrong. At some point, I have >>>>>>> made some change in it. >>>>>>> >>>>>>> The correct (I hope) energy function should be: >>>>>>> >>>>>>> function BzEnergy(b, n=8) = >>>>>>> let( bs = subdivBezier3(b, n) ) >>>>>>> [for(i=[0:3:len(bs)-1]) pow(curvature(bs,i),2)] >>>>>>> *[for(i=[0:3:len(bs)-1]) 1]/pow(2,n-1); >>>>>>> >>>>>>> >>>>>>> With this function, the plot of the cubic energy as a function of >>>>>>> the balance s has a sharper minimum what is more reasonable. >>>>>>> >>>>>>> I will try your data and compare. >>>>>>> >>>>>>> >>>>>>> 2017-12-26 14:21 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>> >>>>>>>> The starting point is: >>>>>>>> >>>>>>>> bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 79.721, -125.85], [0, 79.721, >>>>>>>> -108.35]]; >>>>>>>> length=180; >>>>>>>> >>>>>>>> After I adjust the control points for length I get [[0, 0, 0], [0, >>>>>>>> 0, -139.685], [0, 79.721, -139.685], [0, 79.721, -108.35]] >>>>>>>> >>>>>>>> On 26 December 2017 at 16:15, Ronaldo Persiano < >>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>> >>>>>>>>> Would you mind to provide me the geometric data (endpoint >>>>>>>>> coordinates and strip length) of this case? >>>>>>>>> >>>>>>>>> 2017-12-26 13:32 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>> >>>>>>>>>> Whoops >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> ​ >>>>>>>>>> >>>>>>>>>> On 26 December 2017 at 15:31, nop head <nop.head@gmail.com> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Here is my curve in red and its control points in blue alongside >>>>>>>>>>> yours with my actual geometry. Your BzEnergy function returns 12 times the >>>>>>>>>>> energy for mine which is hard to believe because mine has a more >>>>>>>>>>> distributed curvature. A strip held against the screen follows mine, not >>>>>>>>>>> yours, so I think there must be a bug in your energy function. >>>>>>>>>>> >>>>>>>>>>> On 26 December 2017 at 14:17, nop head <nop.head@gmail.com> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Interesting. I will have to combine with my code and put them >>>>>>>>>>>> side by side. If I put my length and dimension into your code the result >>>>>>>>>>>> looks a lot tighter and doesn't match what my real strip does. >>>>>>>>>>>> >>>>>>>>>>>> On 25 December 2017 at 17:31, Ronaldo Persiano < >>>>>>>>>>>> rcmpersiano@gmail.com> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Here is the code of my atempts to find the cubic with minimum >>>>>>>>>>>>> energy. >>>>>>>>>>>>> >>>>>>>>>>>>> First note that AdjustBezier() finds the cubic with the >>>>>>>>>>>>> desired length keeping the balance between the norms of the cubic endpoint >>>>>>>>>>>>> derivatives. The strategy I used in the code was to change this balance in >>>>>>>>>>>>> order to reduce the cubic energy. >>>>>>>>>>>>> >>>>>>>>>>>>> // for any cubic bz, it holds bz == balance(bz, 0.5) >>>>>>>>>>>>> function balance(bz,s) = >>>>>>>>>>>>> [ bz[0], >>>>>>>>>>>>> bz[0] + 2*s*(bz[1]-bz[0]), >>>>>>>>>>>>> bz[3] + 2*(1-s)*(bz[2]-bz[3]), >>>>>>>>>>>>> bz[3] ]; >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> For each balance, the cubic is adjusted to the target length >>>>>>>>>>>>> by AdjustBezier() and its energy is calculated. >>>>>>>>>>>>> >>>>>>>>>>>>> function BalancedEnergy(bz, s, l, eps) = >>>>>>>>>>>>> BzEnergy(AdjustBezier(balance(bz,s), l, eps)); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> To find the balance that leads to the minimum energy is >>>>>>>>>>>>> objective of an iterative search. The search for the cubic with minimum >>>>>>>>>>>>> energy is done iteratively narrowing an interval (s1,s2) of balances that >>>>>>>>>>>>> contains the best balance. >>>>>>>>>>>>> >>>>>>>>>>>>> // Minimum energy Bezier arc with a given length l >>>>>>>>>>>>> // and given tangent directions at its ends >>>>>>>>>>>>> function BestBz(bz, l, eps=1e-3) = >>>>>>>>>>>>> let( bz2 = [ bz[0], // normalize end derivatives >>>>>>>>>>>>> bz[0]+unit(bz[1]-bz[0]), >>>>>>>>>>>>> bz[3]+unit(bz[2]-bz[3]), >>>>>>>>>>>>> bz[3] ], >>>>>>>>>>>>> s1 = eps, >>>>>>>>>>>>> en1 = BalancedEnergy(bz, s1, l, eps), >>>>>>>>>>>>> en2 = BalancedEnergy(bz, 1-s1, l, eps), >>>>>>>>>>>>> s = _bestS(bz2, l, s1, 1-s1, en1, en2, eps) ) >>>>>>>>>>>>> echo(smin=s) >>>>>>>>>>>>> AdjustBezier(balance(bz2,s), l); >>>>>>>>>>>>> >>>>>>>>>>>>> function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = >>>>>>>>>>>>> let( s12 = (s1+s2)/2, >>>>>>>>>>>>> e12 = BalancedEnergy(bz, s12, l, eps)) >>>>>>>>>>>>> //echo("in",s1=s1,s2=s2,s12=s12,e1=e1,e2=e2,e12=e12) >>>>>>>>>>>>> abs(e12-(e1+e2)/2)/e12< eps ? >>>>>>>>>>>>> e1<e2 ? s1 : s2 >>>>>>>>>>>>> : >>>>>>>>>>>>> let( s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps) >>>>>>>>>>>>> ) >>>>>>>>>>>>> //echo(s1=s1,s3=s3,s2=s2,e1=e1,e12=e12,e2=e2,n=n) >>>>>>>>>>>>> abs(s3-s1)<eps || abs(s3-s2)<eps || n==0 ? >>>>>>>>>>>>> s3 >>>>>>>>>>>>> : >>>>>>>>>>>>> let( e3 = BalancedEnergy(bz, s3, l, eps) ) >>>>>>>>>>>>> //echo(e3=e3) >>>>>>>>>>>>> abs(e3-e12)/e12<eps ? >>>>>>>>>>>>> s3 : >>>>>>>>>>>>> e3<e12 ? >>>>>>>>>>>>> s3<s12 ? >>>>>>>>>>>>> _bestS(bz,l,s1,s12,e1,e12,eps,n-1) >>>>>>>>>>>>> : >>>>>>>>>>>>> _bestS(bz,l,s12,s2,e12,e2,eps,n-1) >>>>>>>>>>>>> : >>>>>>>>>>>>> s3<s12 ? >>>>>>>>>>>>> _bestS(bz,l,s3,s2,e3,e2,eps,n-1) >>>>>>>>>>>>> : >>>>>>>>>>>>> _bestS(bz,l,s1,s3,e1,e3,eps,n-1); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> The full code is annexed. >>>>>>>>>>>>> >>>>>>>>>>>>> In the experiments I have done with the code, the plot of the >>>>>>>>>>>>> cubic energy against the balance parameter s has the shape of an U with an >>>>>>>>>>>>> almost horizontal bottom. This shows that the effect of medium-sized >>>>>>>>>>>>> changes of the optimal balance does not produce significant changes of the >>>>>>>>>>>>> cubic energy. In special, in your case of a strip going down from a fixed >>>>>>>>>>>>> pole to a moving table clamped point, the optimal balance will change >>>>>>>>>>>>> slowly from 0.5 (when the two end points are level) to 1 (when the strip is >>>>>>>>>>>>> fully stretched). That means the balance of the cubic endpoint derivatives >>>>>>>>>>>>> in the optimal solution is slightly favorable to the fixed point if the >>>>>>>>>>>>> strip is never fully stretched. So, your assumption that "keeping the two >>>>>>>>>>>>> inner control points level" would do the trick is not confirmed by my >>>>>>>>>>>>> results. >>>>>>>>>>>>> >>>>>>>>>>>>> 2017-12-23 10:44 GMT-02:00 nop head <nop.head@gmail.com>: >>>>>>>>>>>>> >>>>>>>>>>>>>> I don't know if this has a mathematical validity but simple >>>>>>>>>>>>>> keeping the two inner control points level with each other seems to produce >>>>>>>>>>>>>> a curve that matches a strip held against the screen fairly well. >>>>>>>>>>>>>> ​ >>>>>>>>>>>>>> The length of the strip is only 9mm longer compared to the >>>>>>>>>>>>>> version with the control points equidistant below the end points. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> OpenSCAD mailing list >>>>>>>>>>>>> Discuss@lists.openscad.org >>>>>>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>>>>>> nscad.org >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> OpenSCAD mailing list >>>>>>>>>> Discuss@lists.openscad.org >>>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>>> nscad.org >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> Discuss@lists.openscad.org >>>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>>> nscad.org >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> Discuss@lists.openscad.org >>>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>>> nscad.org >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> Discuss@lists.openscad.org >>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.ope >>>>>>> nscad.org >>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> Discuss@lists.openscad.org >>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >
RP
Ronaldo Persiano
Wed, Dec 27, 2017 2:33 PM

There is a small typo in your last code. Anyway, the output of

subdivBezier3() should be fully understood in order to compute the
curvature correctly.


color("green")
ShowBezier(bzcp,t=0.5);
ShowPolygonal(bzcp,t=0.7);
sbz = subdivBezier3(bzcp,n=2);
for(i=[0:len(sbz)-1])
translate(sbz[i])
if(i%3) color("red") sphere(1.5);
else color("blue")  sphere(1.5);

​The dots are the points of the sequence generated by ​

subdivBezier3(). The four dots between (and including) two subsequent blue
dots are the control points of the arc going from one to the other. The
curvature at each blue dot may be computed either by considering the two
subsequent red dots or the two previous ones. If you take a blue dot, one
before and one after, a zero curvature would result because those three
points are always colinear. I don't see any bug there.

The numerical instability may be in the _bestS() code, the method of
finding the energy minimizing curve. I am looking for a bug there.

2017-12-27 8:34 GMT-02:00 nop head nop.head@gmail.com:

I think
​​
subdivBezier3 may have a bug in it. It seems to produce a path that has
segments with zero curvature. I.e. subtracting adjacent tangents produces
zero. E.g.

path =
​​
subdivBezier3(bezier, 4);
for(i = [1 : len(path) -2])
echo(path[i+1]-path[2] - (path[i]-path[i-1]));

There is a small typo in your last code. Anyway, the output of ​ subdivBezier3() should be fully understood in order to compute the curvature correctly. ​ color("green") ShowBezier(bzcp,t=0.5); ShowPolygonal(bzcp,t=0.7); sbz = subdivBezier3(bzcp,n=2); for(i=[0:len(sbz)-1]) translate(sbz[i]) if(i%3) color("red") sphere(1.5); else color("blue") sphere(1.5); ​The dots are the points of the sequence generated by ​ ​ subdivBezier3(). The four dots between (and including) two subsequent blue dots are the control points of the arc going from one to the other. The curvature at each blue dot may be computed either by considering the two subsequent red dots or the two previous ones. If you take a blue dot, one before and one after, a zero curvature would result because those three points are always colinear. I don't see any bug there. The numerical instability may be in the _bestS() code, the method of finding the energy minimizing curve. I am looking for a bug there. ​ 2017-12-27 8:34 GMT-02:00 nop head <nop.head@gmail.com>: > I think > ​​ > subdivBezier3 may have a bug in it. It seems to produce a path that has > segments with zero curvature. I.e. subtracting adjacent tangents produces > zero. E.g. > > path = > ​​ > subdivBezier3(bezier, 4); > for(i = [1 : len(path) -2]) > echo(path[i+1]-path[2] - (path[i]-path[i-1])); > >
NH
nop head
Wed, Dec 27, 2017 3:52 PM

Yes there is an erroneous 2 in my code but the output I posted was correct.

The confusing thing is you draw the Bezier curve with the results from
subdivBezier3 but its output isn't a Bezier curve. To speed up drawing I
passed it to my Frenet sweep and it choked.

On 27 December 2017 at 14:33, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

There is a small typo in your last code. Anyway, the output of

subdivBezier3() should be fully understood in order to compute the
curvature correctly.


color("green")
ShowBezier(bzcp,t=0.5);
ShowPolygonal(bzcp,t=0.7);
sbz = subdivBezier3(bzcp,n=2);
for(i=[0:len(sbz)-1])
translate(sbz[i])
if(i%3) color("red") sphere(1.5);
else color("blue")  sphere(1.5);

​The dots are the points of the sequence generated by ​

subdivBezier3(). The four dots between (and including) two subsequent blue
dots are the control points of the arc going from one to the other. The
curvature at each blue dot may be computed either by considering the two
subsequent red dots or the two previous ones. If you take a blue dot, one
before and one after, a zero curvature would result because those three
points are always colinear. I don't see any bug there.

The numerical instability may be in the _bestS() code, the method of
finding the energy minimizing curve. I am looking for a bug there.

2017-12-27 8:34 GMT-02:00 nop head nop.head@gmail.com:

I think
​​
subdivBezier3 may have a bug in it. It seems to produce a path that has
segments with zero curvature. I.e. subtracting adjacent tangents produces
zero. E.g.

path =
​​
subdivBezier3(bezier, 4);
for(i = [1 : len(path) -2])
echo(path[i+1]-path[2] - (path[i]-path[i-1]));

Yes there is an erroneous 2 in my code but the output I posted was correct. The confusing thing is you draw the Bezier curve with the results from subdivBezier3 but its output isn't a Bezier curve. To speed up drawing I passed it to my Frenet sweep and it choked. On 27 December 2017 at 14:33, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > There is a small typo in your last code. Anyway, the output of > ​ > subdivBezier3() should be fully understood in order to compute the > curvature correctly. > > ​ > color("green") > ShowBezier(bzcp,t=0.5); > ShowPolygonal(bzcp,t=0.7); > sbz = subdivBezier3(bzcp,n=2); > for(i=[0:len(sbz)-1]) > translate(sbz[i]) > if(i%3) color("red") sphere(1.5); > else color("blue") sphere(1.5); > > > ​The dots are the points of the sequence generated by ​ > ​ > subdivBezier3(). The four dots between (and including) two subsequent blue > dots are the control points of the arc going from one to the other. The > curvature at each blue dot may be computed either by considering the two > subsequent red dots or the two previous ones. If you take a blue dot, one > before and one after, a zero curvature would result because those three > points are always colinear. I don't see any bug there. > > The numerical instability may be in the _bestS() code, the method of > finding the energy minimizing curve. I am looking for a bug there. > > ​ > > 2017-12-27 8:34 GMT-02:00 nop head <nop.head@gmail.com>: > >> I think >> ​​ >> subdivBezier3 may have a bug in it. It seems to produce a path that has >> segments with zero curvature. I.e. subtracting adjacent tangents produces >> zero. E.g. >> >> path = >> ​​ >> subdivBezier3(bezier, 4); >> for(i = [1 : len(path) -2]) >> echo(path[i+1]-path[2] - (path[i]-path[i-1])); >> >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
RP
Ronaldo Persiano
Wed, Dec 27, 2017 4:23 PM

The result of subdivBezier3() is not a sequence of points in the curve. It
is a sequence of control points of partial arcs of the incoming curve. So,
just a third of its points are actually on the curve. You will have
troubles computing Frenet frame for the sequence because there are many
sub-sequences of 3 co-linear points in it. The sequence generated by
subdivBezier3(bz,n)
is a polygonal that approximates the curve. The greater the value of n the
better is the approximation. The sequence length grows exponentially with
n, though. It is faster to subdivide than to evaluate an equal number of
points points in the curve and the convergence rate is better.

2017-12-27 13:52 GMT-02:00 nop head nop.head@gmail.com:

Yes there is an erroneous 2 in my code but the output I posted was correct.

The confusing thing is you draw the Bezier curve with the results from
subdivBezier3 but its output isn't a Bezier curve. To speed up drawing I
passed it to my Frenet sweep and it choked.

On 27 December 2017 at 14:33, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

There is a small typo in your last code. Anyway, the output of

subdivBezier3() should be fully understood in order to compute the
curvature correctly.


color("green")
ShowBezier(bzcp,t=0.5);
ShowPolygonal(bzcp,t=0.7);
sbz = subdivBezier3(bzcp,n=2);
for(i=[0:len(sbz)-1])
translate(sbz[i])
if(i%3) color("red") sphere(1.5);
else color("blue")  sphere(1.5);

​The dots are the points of the sequence generated by ​

subdivBezier3(). The four dots between (and including) two subsequent
blue dots are the control points of the arc going from one to the other.
The curvature at each blue dot may be computed either by considering the
two subsequent red dots or the two previous ones. If you take a blue dot,
one before and one after, a zero curvature would result because those three
points are always colinear. I don't see any bug there.

The numerical instability may be in the _bestS() code, the method of
finding the energy minimizing curve. I am looking for a bug there.

2017-12-27 8:34 GMT-02:00 nop head nop.head@gmail.com:

I think
​​
subdivBezier3 may have a bug in it. It seems to produce a path that has
segments with zero curvature. I.e. subtracting adjacent tangents produces
zero. E.g.

path =
​​
subdivBezier3(bezier, 4);
for(i = [1 : len(path) -2])
echo(path[i+1]-path[2] - (path[i]-path[i-1]));

The result of subdivBezier3() is not a sequence of points in the curve. It is a sequence of control points of partial arcs of the incoming curve. So, just a third of its points are actually on the curve. You will have troubles computing Frenet frame for the sequence because there are many sub-sequences of 3 co-linear points in it. The sequence generated by subdivBezier3(bz,n) is a polygonal that approximates the curve. The greater the value of n the better is the approximation. The sequence length grows exponentially with n, though. It is faster to subdivide than to evaluate an equal number of points points in the curve and the convergence rate is better. 2017-12-27 13:52 GMT-02:00 nop head <nop.head@gmail.com>: > Yes there is an erroneous 2 in my code but the output I posted was correct. > > The confusing thing is you draw the Bezier curve with the results from > subdivBezier3 but its output isn't a Bezier curve. To speed up drawing I > passed it to my Frenet sweep and it choked. > > > > On 27 December 2017 at 14:33, Ronaldo Persiano <rcmpersiano@gmail.com> > wrote: > >> There is a small typo in your last code. Anyway, the output of >> ​ >> subdivBezier3() should be fully understood in order to compute the >> curvature correctly. >> >> ​ >> color("green") >> ShowBezier(bzcp,t=0.5); >> ShowPolygonal(bzcp,t=0.7); >> sbz = subdivBezier3(bzcp,n=2); >> for(i=[0:len(sbz)-1]) >> translate(sbz[i]) >> if(i%3) color("red") sphere(1.5); >> else color("blue") sphere(1.5); >> >> >> ​The dots are the points of the sequence generated by ​ >> ​ >> subdivBezier3(). The four dots between (and including) two subsequent >> blue dots are the control points of the arc going from one to the other. >> The curvature at each blue dot may be computed either by considering the >> two subsequent red dots or the two previous ones. If you take a blue dot, >> one before and one after, a zero curvature would result because those three >> points are always colinear. I don't see any bug there. >> >> The numerical instability may be in the _bestS() code, the method of >> finding the energy minimizing curve. I am looking for a bug there. >> >> ​ >> >> 2017-12-27 8:34 GMT-02:00 nop head <nop.head@gmail.com>: >> >>> I think >>> ​​ >>> subdivBezier3 may have a bug in it. It seems to produce a path that has >>> segments with zero curvature. I.e. subtracting adjacent tangents produces >>> zero. E.g. >>> >>> path = >>> ​​ >>> subdivBezier3(bezier, 4); >>> for(i = [1 : len(path) -2]) >>> echo(path[i+1]-path[2] - (path[i]-path[i-1])); >>> >>> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >