discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Modelling a flexible strip

RP
Ronaldo Persiano
Wed, Dec 27, 2017 6:40 PM

For the purpose of the Frenet sweep only, you may use:

function subdivBezier3_2(p, n=4) =
n<=0 ?
[for(i=[0:len(p)-1])
i%3==0 ?
p[i] :
i%3==1 ?
(p[i]+(2p[i-1]/3 + p[i+2]/3))/2 :
(p[i]+(p[i-2]/3 + 2
p[i+1]/3))/2 ]
:
let( seq = [for(i=[0:3:len(p)-4], s=_subdivB(p,i)) s ] )
subdivBezier3_2( concat( [ p[0] ], seq ), n-1);

​It eliminates collinearities but its output will not be appropriate
to BzEnergy() digestion.

2017-12-27 14:23 GMT-02:00 Ronaldo Persiano rcmpersiano@gmail.com:

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.

For the purpose of the Frenet sweep only, you may use: function subdivBezier3_2(p, n=4) = n<=0 ? [for(i=[0:len(p)-1]) i%3==0 ? p[i] : i%3==1 ? (p[i]+(2*p[i-1]/3 + p[i+2]/3))/2 : (p[i]+(p[i-2]/3 + 2*p[i+1]/3))/2 ] : let( seq = [for(i=[0:3:len(p)-4], s=_subdivB(p,i)) s ] ) subdivBezier3_2( concat( [ p[0] ], seq ), n-1); ​It eliminates collinearities but its output will not be appropriate to BzEnergy() digestion. 2017-12-27 14:23 GMT-02:00 Ronaldo Persiano <rcmpersiano@gmail.com>: > 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. >> >>
RP
Ronaldo Persiano
Wed, Dec 27, 2017 9:45 PM

As I have supposed the instability was produced by BestBz(). I had to
tighten the stopping clause in _bestS to get a better stability. I can't
assure this method is foolproof; it may go wild when the tangent directions
and endpoints induce a loop or inflexions to the arc. Besides, to avoid
stack overflow I limited arbitrarily the maximum number of recursions calls.

function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) =
let( s12 = (s1+s2)/2,
e12 = BalancedEnergy(bz, s12, l, eps),
s3  = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps),
e3 = BalancedEnergy(bz, s3, l, eps) )
//echo(s1=s1,s3=s3,s12=s12,s2=s2,e1=e1,e3=e3,e12=e12,e2=e2,n=n)
(abs(e3-e12)/e12<eps && abs(s3-s12)<eps) || n==0 ? // * main change *
s3//e3<e12 ? s3 : s12
:
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);

2017-12-26 18:58 GMT-02:00 nop head nop.head@gmail.com:

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

https://youtu.be/6t8Taul_4Rw

As I have supposed the instability was produced by BestBz(). I had to tighten the stopping clause in _bestS to get a better stability. I can't assure this method is foolproof; it may go wild when the tangent directions and endpoints induce a loop or inflexions to the arc. Besides, to avoid stack overflow I limited arbitrarily the maximum number of recursions calls. function _bestS(bz, l, s1, s2, e1, e2, eps=1e-3, n=15) = let( s12 = (s1+s2)/2, e12 = BalancedEnergy(bz, s12, l, eps), s3 = max(min(parabMin(s1,s12,s2,e1,e12,e2),1-eps),eps), e3 = BalancedEnergy(bz, s3, l, eps) ) //echo(s1=s1,s3=s3,s12=s12,s2=s2,e1=e1,e3=e3,e12=e12,e2=e2,n=n) (abs(e3-e12)/e12<eps && abs(s3-s12)<eps) || n==0 ? // * main change * s3//e3<e12 ? s3 : s12 : 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); 2017-12-26 18:58 GMT-02:00 nop head <nop.head@gmail.com>: > > I made a video and that seems to show some numerical instability. > > https://youtu.be/6t8Taul_4Rw > > >
RP
Ronaldo Persiano
Thu, Dec 28, 2017 4:40 PM

2017-12-27 19:45 GMT-02:00 Ronaldo Persiano rcmpersiano@gmail.com:

I can't assure this method is foolproof; it may go wild when the tangent
directions and endpoints induce a loop or inflexions to the arc.

​That is really true. I found a case where the energy curve as a function
​of the balance s has 3 local minima.

bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 9.721, 32,14], [0, 79.721, 32,14]];
length=180;

For each minimum there is a stable cubic solution as shown bellow.

The blue curve has the smallest energy for a balance s=0.78. The yellow one
has the greatest energy for a balance s=0.04. The green curve was the one
found by my code with a balance s=0.39 and a total energy 10 times of the
blue curve and 74% of the yellow one. All three curves are local minima of
the energy function and I doubt that any of them is a good approximation of
an elastica.

2017-12-27 19:45 GMT-02:00 Ronaldo Persiano <rcmpersiano@gmail.com>: > I can't assure this method is foolproof; it may go wild when the tangent > directions and endpoints induce a loop or inflexions to the arc. > ​That is really true. I found a case where the energy curve as a function ​of the balance s has 3 local minima. bzcp=[[0, 0, 0], [0, 0, -125.85], [0, 9.721, 32,14], [0, 79.721, 32,14]]; length=180; For each minimum there is a stable cubic solution as shown bellow. The blue curve has the smallest energy for a balance s=0.78. The yellow one has the greatest energy for a balance s=0.04. The green curve was the one found by my code with a balance s=0.39 and a total energy 10 times of the blue curve and 74% of the yellow one. All three curves are local minima of the energy function and I doubt that any of them is a good approximation of an elastica. ​