
1234

Does anybody here know how to model a flexible strip with rigidly held ends? I.e. the maths to generate the curve. It's a bit like modelling a catenary, but instead of being defined by gravity and tension, the main force is the strip trying to be straight and not bent.
I crudely modelled the polypropylene strips I used in Mendel90 using arcs but I need a more accurate model for my new machine.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Administrator

> On Dec 1, 2017, at 10:20 AM, nop head < [hidden email]> wrote:
>
> Does anybody here know how to model a flexible strip with rigidly held ends? I.e. the maths to generate the curve. It's a bit like modelling a catenary, but instead of being defined by gravity and tension, the main force is the strip trying to be straight and not bent.
>
This sounds very much like what Beziér curves were originally meant to be used for.
Marius
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Thanks for the pointers. I think what I need is a minimum energy spline with a fixed length.
Playing with a Bezier spline using this tool https://www.desmos.com/calculator/cahqdxeshd , I get something that looks about right using four control points. The end points are obviously where my ends are. The next points in seem to define tangents to the curve at is ends. These can be on a line through the mounting plane. I.e. through the planes the ends are clamped to. To get the length correct I can move those two points equally away from the ends points until it is long enough. Since there seems to be no easy way to calculate the length of a Bezier curve I would need to compute it by recursive splitting the curve until it converges. Then do a search moving the two points.
I have no idea if a Bezier spline is minimum energy or not.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


I had this nugget from another project.
module to draw a simple 4 point Bez curve.
function for piecewise length estimation.
Simple enought to add a recursive function to fit control points for the
length of your pleasure.
Bezier_Length_Constrained.scad
< http://forum.openscad.org/file/t1678/Bezier_Length_Constrained.scad>
function AdjustBezier(v,l, precision = 0.001)=
l<norm(v[0]v[3])?let(e=echo("Cant be that short, sorry"))
[v[0],v[0] ,v[3] ,v[3]]:
let(
current_lenght=len3bz(v),
error=l/current_lenght,
new_v=[v[0],v[0]+(v[1]v[0])*error,v[3]+(v[2]v[3])*error,v[3]]
)
abs(1error)>precision?AdjustBezier(new_v,l):v;
function len3bz(v, precision = 0.001, t = 0, acc = 0) = t > 1 ? acc :
len3bz(v, precision, t + precision, acc + norm(bez2(t, v)  bez2(t +
precision, v)));
function bez2(t, v) = (len(v) > 2) ? bez2(t, [
for (i = [0: len(v)  2]) v[i] * (1  t) + v[i + 1] * (t)
]): v[0] * (1  t) + v[1] * (t);
module ShowControl(v) { // translate(t(v[0])) sphere(v[0][3]);
for (i = [1: len(v)  1]) {
// vg translate(t(v[i])) sphere(v[i][3]);
hull() {
translate(t(v[i])) sphere(0.5);
translate(t(v[i  1])) sphere(0.5);
}
}
}
module ShowBezier(v,step=0.05) { // translate(t(v[0])) sphere(v[0][3]);
for (i = [step:step: 1]) {
// vg translate(t(v[i])) sphere(v[i][3]);
hull() {
translate(t(bez2(i, v) ))sphere(1);
translate(t(bez2(istep, v))) sphere(1);
}
}
}
function t(v) = [v.x, v.y, v.z];
MyBezier=[[0,0,0],[0,0,10],[50,0,50],[50,10,50]];
Newlengh=75;
ShowControl(MyBezier) ;
ShowBezier(MyBezier) ;
echo(len3bz(MyBezier));
MyNewBezier=AdjustBezier(MyBezier,Newlengh) ;
color("red"){
ShowControl(MyNewBezier) ;
ShowBezier(MyNewBezier) ;
echo(len3bz(MyNewBezier));}

Sent from: http://forum.openscad.org/_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Thanks for that. Seems to do exactly what I proposed.
I found it did stop one point short when displaying the curve due to using floating point in the for loop. I fixed it as follows
module ShowBezier(v,steps=20) { // translate(t(v[0])) sphere(v[0][3]); for (i = [1 : steps]) { // vg translate(t(v[i])) sphere(v[i][3]); hull() { translate(t(bez2(i / steps, v) ))sphere(1); translate(t(bez2((i  1) / steps, v))) sphere(1); } } }
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Having worked my way through the code to understand it there are two things that puzzle me.
Why is len3bz named with a 3? It looks like it would work on any Bezier curve, not just cubic ones?
What is the t() function for. It seems like a NOP for 3d points and the code works without it. Is it a leftover from some 4D code?
Thanks again, it does just what I needed. The curves it produces look plausible. I am holiday at moment but when I get back I will attempt to bend a strip over a 2D print of the curve and see if it matches.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Without going deep in the code, there is something that seems inappropriate. Given the two extreme points of cubic Bezier and the two first derivative direction at those points, I would expect an infinite number of solutions to the fixed length arc problem except in very particular cases. It seems that Torleif's code chooses a particular solution where the ratio of the norms of the two derivatives of the final solution is the same as the corresponding ratio of the starting curve. So, the solution found by the method depends not only on the two extreme points and their tangents. But those are the only available data of the nophead's initial problem.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


nophead
Yes there was a bug with drawing the last segment.
I solved it some where but apparently not where i grabbed this code ;)
Yes AdjustBezier is the only new thing here the other stuff is just
leftovers for showcase.
Yepp the t() strips out other data that i used to store in the vector
radius, color, local scaling etc.
Yepp there are better analytical bezier math . I use the recursive because
1. i understand that 2. it handles 2 to n control points without change.
No its not minimal energy witch get obviously when cramming a long strip in
a tight space.
It doesnt out bulge out right to maintain a smooth curvature.
Ronaldo yes the solution depends on the relative length of the /control
handles/.
some other store the middle control points as a relative vector to endpoints
[start,controlstart,controlend,end]
But i just use points
So given a bezier [p0,p1,p2,p3]
As i understand the problem:
The two endpoints are fixed. The initial direction at each end is fixed.
Thus each control point, p1 and p2, live along a vector formed p0 and p1
respectively p2 and p3.
Forming the /control handles/.
Adjusting the handles length change the overall length of the curve.
Both can be changed separately
but in AdjustBezier they are both multiplied by the same length error term
to converge on the desired length.
If its desired to force a uniform look both handles can be normalized
before AdjustBezier
Good Luck
function NormalizeBezierControl(v)=
[v[0],v[0]+UnitNormal (v[1]v[0]) ,v[3]+UnitNormal (v[2]v[3]) ,v[3]];
function UnitNormal (v)=v/max(norm(v),1e32);// div by zero safe

Sent from: http://forum.openscad.org/_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Yes it is certainly different from minimum energy when the ends are close together and parallel, e.g. both pointing down gives a tall thin U but it would actually look like the cross section of a light bulb.
In the case I am modelling the ends are not close together so perhaps it will be accurate enough. Now that I know I am looking for a minimum energy I have found lots of papers about it. Most need to be paid for though.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Yes it is a bit tight, which is why I modelled it. The problem is it needs to not hit the shelf below that covers the electronics. It only cycles once per build so I think I will get away with it. I have used ribbons on X and Y that move millions of times in a build.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


On 20171205 23:01, nop head wrote:
> Yes it is a bit tight, which is why I modelled it. The problem is it
> needs to not hit the shelf below that covers the electronics. It only
> cycles once per build so I think I will get away with it. I have used
> ribbons on X and Y that move millions of times in a build.
Nice video, although the cable deformation is somewhat unrealistic.
If knowing the true shape was critical, it would require nonlinear
finite element analysis. Someone mentioned a catenary, but this cable is
much stiffer than a catenary (essentially no bending stiffness). The
problem is quite similar to analyzing flexible risers used on the
offshore industry. Nonnegligible bending stiffness, large deformations,
boundary conditions at the ends.
Still the simplified approximation was quite ok for a demo.
Carsten Arnholm
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Yes I suspect the bend radius would be a bit bigger in real life, closer to an arc. The cable is ribbon, so not stiff at all but I bend it around a 0.8mm thick polypropylene strip to distribute the bending. It is the strip I am trying to model. It works like a cable chain for ribbon but is a lot more compact and cheaper. Without it ribbon tends to bend too much at the attachment points.
The model needs to predict the length to make the strip as that goes on the BOM. The length should be as long as possible without hitting the bottom as it would buckle if it did. Using Bezier my guess is it is a bit shorter than it could be. If it is not too much that will be OK but if it is grossly wrong then the strip is tighter than it needs to be so is not good for cable life.
When I get home I will mock it up and see if it is accurate enough. If not I will try to work out a minimum energy solution using finite elements. It is after all drawn with 100 finite elements so I can easily calculate the bend at each joint. The tricky bit is moving the joints to minimise the energy.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


I have been struggling with this problem for a while. I will not go into the details of the energy minimizing problem here and will just address the problem of finding the Bezier arc with a given length, given its end points and its tangent directions at the endpoints. The function AdjustBezier() provided by Torleif is inefficient for this task requiring a lot of adjustment.
The main idea of Torleif solution is to adjust the Bezier arc endpoints derivatives until the required length is attained. The adjustment is done by:
[ p[0], p[0]+(p[1]p[0])*r, p[3]+(p[2]p[3])*r , p[3] ];
where p is the incoming Bezier control points and r is the adjustment parameter. So, the problem is to find the parameter r such that:
len3bz(adjust(p,r)) == length
where len3bz() is the function that estimates a Bezier arc length.
I have observed that the length of the Bezier arc is fairly linear with respect to the parameter r and the following code explores it:
function AdjustBezier(p, l, eps=0.001, r1=10, r2=12, l1, l2)= let( l1 = l1!=undef? l1: len3bz(adjust1(p,r1), eps), l2 = l2!=undef? l2: len3bz(adjust1(p,r2), eps) ) let( r = r1 + (ll1)*(r2r1)/(l2l1) ) AdjustBezier(p, l, eps, r, r1, undef, l1) AdjustBezier(p, l, eps, r, r2, undef, l2);
This function requires very few steps compared with Torleif's one which is very lengthy when the solution is almost stretched.
Next, I have considered the time consuming function len3bz(). I approached this by Bezier subdivision instead of a fixed sample of Bezier evaluations. The resulting code is a bit longer but it is more efficient.
function len3bz(bz, eps=0.001) = let( l1 = polygonalLength(bz, ceil(log(eps))), l2 = polygonalLength([for(i=[0:3:len(bz)1]) bz[i]], ceil(log(eps))) ) l1l2<eps ? (l1+l2)/2 : len3bz(subdivBezier3(bz, 1), eps); function polygonalLength(p) = let( l = [for(i=[1:len(p)1]) norm(p[i]p[i1]) ] ) l*[for(i=[0:len(l)1]) 1]; function subdivBezier3(p, n=3) = subdivBezier3( concat([for(i=[0:3:len(p)4], function _subdivB(p, from=0) = * [p[from], p[from+1], p[from+2], p[from+3] ];
I have addressed the problem of finding the minimum energy Bezier arc too. I have a version that is reasonable fast now requiring between 1 to 2 sec for each step of an animation similar to nophead's one. I don't believe that material is of broad interest but anyone interested in it may contact me by PM.
BTW, I think nophead could reduce the polypropylene strip strain by giving it a little slope in the table end instead of driving it vertically.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Hi Ronaldo,
Thanks for your input. I tried dropping in your changes to my code but didn't see any noticeable speed improvement. I think this is because I had already made the length function faster by only using 100 segments instead of 1000. I also calculate the target length to give the minimum z that is allowed by adjusting the control points until it droops the correct amount. My code currently takes 20 seconds because I added the ribbon cable and sweep each wire separately because they take different paths at the fold. I also model the veroboard terminations including tracks, breaks and solder menisci! I think the time for the Bezier calculation is swamped by 20 sweeps. I used FrenetSerret for the strip because it has two vertical sections that the minimum angle solution doesn't like. I used minimum angle for the cable because FrenetSerret goes wild when the at the fold. Yes I think you are correct saying the optimum starting angle is not straight down but I am not sure if that is worth changing. I still need to see how accurate it is against a real strip.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

1234
