I ended up fudging this a bit but it basically makes a knot that mobius
(only 1 edge) as is this will handily print with a layer height of 0.25mm an looks really nice with higher $fn, leave it at 4 to see the mobius strip like effect, prints fine with PETg, you will need very good fans to print with PLA it does look trivial but I posted it here as the physical end product looks so nice and it did take a fair bit of tweaking... Enjoy! snip! function knotAng(a,s) = [(sin(a)+(2*sin(2*a)))*s, (cos(a)(2*cos(2*a)))*s, sin(3*a)*(s*1.5)]; // from wiki // Find the unitary vector with direction v. Fails if v=[0,0,0]. function unit(v) = norm(v)>0 ? v/norm(v) : undef; // Find the transpose of a rectangular matrix function transpose(m) = // m is any rectangular matrix of objects [ for(j=[0:len(m[0])1]) [ for(i=[0:len(m)1]) m[i][j] ] ]; // The identity matrix with dimension n function identity(n) = [for(i=[0:n1]) [for(j=[0:n1]) i==j ? 1 : 0] ]; // computes the rotation with minimum angle that brings a to b // the code fails if a and b are opposed to each other function rotate_from_to(a,b) = let( axis = unit(cross(a,b)) ) axis*axis >= 0.99 ? transpose([unit(b), axis, cross(axis, unit(b))]) * [unit(a), axis, cross(axis, unit(a))] : identity(3); STEP=4; SCALE=14; // of overall knot $fn=4; // use to select number of faces in the path profile //union() // needed ? for (a=[0:STEP:360]) { v = knotAng(a,SCALE)  knotAng(a+STEP,SCALE); v2 = knotAng(a+STEP,SCALE)  knotAng(a+STEP+STEP,SCALE); hull() { translate(knotAng(a,SCALE)) multmatrix(rotate_from_to([0,0,1],v)) rotate(a*1.25) // fudge cylinder(r=SCALE/2,h=0.1,center=true); translate(knotAng(a+STEP,SCALE)) multmatrix(rotate_from_to([0,0,1],v2)) rotate((a*1.25)+STEP) // fudge cylinder(r=SCALE/2,h=0.1,center=true); } } translate([0,0,1.35*(SCALE*1.5)]) cylinder(r=3*SCALE,h=2,$fn=128); _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
thank you for sharing, I'm going to print up a few! On Sun, Apr 9, 2017 at 5:03 AM, Mr C Camacho <[hidden email]> wrote: I ended up fudging this a bit but it basically makes a knot that mobius (only 1 edge) _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Administrator

Nice.
$fn needs to be multiple of 4. Shame, as $fn=3 looks great apart from the misalignment...
Admin  PM me if you need anything,
or if I've done something stupid... Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! 
Does work with fn=3 you have to change the fudge multiple tho
For three sides it would be 1.33333 It needs changing in two places It could be calculated if $fn was assigned from a "settings" variable called SIDES Where the multiple would be 1+(1/SIDES) .... off the top of my head... Three sides does look very effective but you will have to rotate the whole knot on the x and y axis slightly for it to sit on the base Hope this helps Chris On 10 April 2017 01:55:31 BST, MichaelAtOz <oz.at.[hidden email]> wrote: Nice.  Sent from my Android device with K9 Mail. Please excuse my brevity. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by MichaelAtOz
okay he's for n sides while retaining its mobius quality  I *will* stop
playing with this now! snip STEP=4; // fine in most cases SCALE=14; // of overall knot // three SIDES will need the whole model rotating to sit flat on base SIDES=3; // number of sides in the profile 3 to 16 (unless printed very large 16 should be plenty for printing) $fn=SIDES; // use to select number of faces in the path profile // calculates position in path a=angle s=scale function knotAng(a,s) = [(sin(a)+(2*sin(2*a)))*s, (cos(a)(2*cos(2*a)))*s, sin(3*a)*(s*1.5)]; // from wiki // Find the unitary vector with direction v. Fails if v=[0,0,0]. function unit(v) = norm(v)>0 ? v/norm(v) : undef; // Find the transpose of a rectangular matrix function transpose(m) = // m is any rectangular matrix of objects [ for(j=[0:len(m[0])1]) [ for(i=[0:len(m)1]) m[i][j] ] ]; // The identity matrix with dimension n function identity(n) = [for(i=[0:n1]) [for(j=[0:n1]) i==j ? 1 : 0] ]; // computes the rotation with minimum angle that brings a to b // the code fails if a and b are opposed to each other function rotate_from_to(a,b) = let( axis = unit(cross(a,b)) ) axis*axis >= 0.99 ? transpose([unit(b), axis, cross(axis, unit(b))]) * [unit(a), axis, cross(axis, unit(a))] : identity(3); for (a=[0:STEP:360]) { v = knotAng(a,SCALE)  knotAng(a+STEP,SCALE); v2 = knotAng(a+STEP,SCALE)  knotAng(a+STEP+STEP,SCALE); hull() { translate(knotAng(a,SCALE)) multmatrix(rotate_from_to([0,0,1],v)) rotate(a*(1+(1.0/SIDES))) // fudge cylinder(r=SCALE/2,h=0.1,center=true); translate(knotAng(a+STEP,SCALE)) multmatrix(rotate_from_to([0,0,1],v2)) rotate((a*(1+(1.0/SIDES)))+STEP) // fudge cylinder(r=SCALE/2,h=0.1,center=true); } } //base translate([0,0,1.35*(SCALE*1.5)]) cylinder(r=3*SCALE,h=2,$fn=128); On 10/04/17 01:55, MichaelAtOz wrote: > Nice. > $fn needs to be multiple of 4. > Shame, as $fn=3 looks great apart from the misalignment... > > > >  > Admin  PM me if you need anything, or if I've done something stupid... > > Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. > > The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! >  > View this message in context: http://forum.openscad.org/simpleCelticknottp21141p21152.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > [hidden email] > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Nice design! I have already spent a lot of enjoyable time sweeping knots around a torus. I found a small glitch in the matching between subsequent hulls: which can be avoided with rotate((a+STEP)*1.25) rotate(a*(1.25)+STEP) // fudge _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
nice catch, thats defo a coding error! fortunately its tiny enough
to be well outside the resolution of most 3d printers....
On 10/04/17 19:32, Ronaldo Persiano
wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Ronaldo
On 10/04/17 19:32, Ronaldo Persiano wrote: > sweeping knots around a torus. how do you mean? sounds interesting... _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Yes, it is indeed. You may want to take a look on it in wikipedia. The particular knot you have made is a knot(2,3): In general in a knot(p,q), p is the number of turns the cord does around the torus and q the number of times the cord goes through the torus hole. I don't know how to change your definition of the knot path to include p and q. I have used another definition: where: d is the cord section radius R is the torus major radius r is the torus minor radius The control of the sweep twist is important to get a nice form. Your fudge does exactly that. In the image above I have used another twist value such that one face of the swept cord is facing the torus surface along all the path. Certainly there no Moebius strip with that twist. If you are interested on that I can provide you my changes to your code with the twist control. 
Personally I'd love to see p,q integrated into this code. I had a go but couldn't work it out.
The other problem I have with the existing code  is that the entire path doesn't align when it loops round to the start. I.e. except for a quad, the start and end faces are not twisted so as to align. Try $fn=5. 
I posted (here) a newer version where any value of SIDES creates the
correct twist @Ronaldo I'd like to see it too, could you post it here for everyone ? On 11/04/17 04:55, Neon22 wrote: > Personally I'd love to see p,q integrated into this code. I had a go but > couldn't work it out. > The other problem I have with the existing code  is that the entire path > doesn't align when it loops round to the start. I.e. except for a quad, the > start and end faces are not twisted so as to align. Try $fn=5. > > > > >  > View this message in context: http://forum.openscad.org/simpleCelticknottp21141p21183.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > [hidden email] > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
I've managed to implement the P/Q formula inside the knot script and
while it works, I can't replicate the original 2/3 knot that the original script did. That said I have made a very nice braided ring type object... _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by codifies
20170411 5:16 GMT03:00 Mr C Camacho <[hidden email]>: @Ronaldo I'd like to see it too, could you post it here for everyone ? Sorry for the delay in answering you. I have been struggling with trigonometric stuff trying to understand the specific parametrization of the knot 2,3 you have used in your celtic knot. It produces a far better shape the the parametrization I have been using. The effort was rewarding... at least for me. :) I will consider here the celtic knot parametrization (CKP) in the following form without the scale parameters (they can be applied in the calling code): function knot1(a) = // CKP parametrization for knot 2,3 [(sin(a)+(2*sin(2*a))), (cos(a)(2*cos(2*a))), sin(3*a)]; and I will compare it with the traditional parametrization for knots p,q: function knot2(a,p,q,R,r) = [ (r*cos(q*a) + R)*cos(p*a), (r*cos(q*a) + R)*sin(p*a), r*sin(q*a) ]; This parametrization may be rewritten to be clear that it is a knot on a circular torus: function knot3(a,p,q,R,r) = let( t = [(r*cos(q*a) + R), 0, r*sin(q*a) ] ) // circle in XZ [ [ cos(p*a), sin(p*a), 0], [sin(p*a), cos(p*a), 0], // rotation in Z of p*a degrees [0,0,1] ] * t; This parametrization is a rotation in Z with an angle p*a of a point 't' that also depends on 'a'. The expression of point t is itself a parametrization of a circle of radius 'r' on the XZ plane centered at the point [ R,0,0 ]. For 0<= a <= 360, the parametrization t does q turns on the circle and the rotation does p turns around Z axis. The net result will be a p,q knot on the surface of a circular torus with major radius 'R' and minor radius 'r'. The following image shows the knot 2,3 (also known as trefoil) computed with knot3(): In the image, a partial torus appears transparent and its transversal section highlighted in red. Note that the knot cord section center is on the torus surface. However, the shape of the knot generated by knot1() is far better specially in the section it goes thought the torus hole. Observe that the torus section of knot1() parametrization is not a circle anymore. If we get a good parametrization of this section we may rewrite knot1() in the form: function knot1a(a) = let( t = section_parametrization(3*a) ) [ [ cos(2*a), sin(2*a), 0], [sin(2*a), cos(2*a), 0], // rotation in Z of 2*a degrees [0,0,1] ] * t; and then substitute p for 2 and q for 3 to get a general knot p,q with the good shape of knot1(). Here is where the trigonometric stuffs are handy. After many failed trials I have found the proper parametrization behind knot1(). function knot1b(a) = let( t = [ sin(3*a), cos(3*a)  2, sin(3*a) ] ) // section parametrization [ [ cos(2*a), sin(2*a), 0], [ sin(2*a), cos(2*a), 0], // rotation in z of 2*a degrees [0,0,1] ] * t; This formulation is exactly equivalent to knot1() but it is now evident the p,q numbers in it. If we compare knot1b() with knot3 it is also evident that the section parametrization here is not a vertical section of the torus anymore. In fact, if we sweep just the section t, we get: The torus transversal section is a slanted ellipsis! Now, introducing p, q, R and r in the knot1b() we get our general form of knot1(): function knot4(a,p,q,R,r) = let( t = [ sin(q*a+alpha), cos(q*a+beta)  R, r*sin(q*a) ] ) // elliptical slanted section [ [ cos(p*a), sin(p*a), 0], [ sin(p*a), cos(p*a), 0], // rotation in z of p*a degrees [0,0,1] ] * t; With this formulation we may explore other knots like the cinquefoil (3,5) and its "dual" 5,3 : Along of my multiple attempts to find knot4() expressions I have discovered new possibilities to define interesting parametrizations of p,q knots, like for instance the following interwoven basket: This is a knot 5,8 we get with simple changes in knot4() introducing two more shape parameters: function knot5(a,p,q,R,r,alpha,beta) = let( t = [ sin(q*a+alpha), cos(q*a+beta)  R, r*sin(q*a) ] ) // elliptical slanted transversal section [ [ cos(p*a), sin(p*a), 0], [ sin(p*a), cos(p*a), 0], // rotation in z of p*a degrees [0,0,1] ] * t; The phase parameters alpha and beta are angles that produce very different torus shapes. In the last basketlike knot I have used alpha=beta=60. In the following, we have p=7, q=11, alpha=80 and beta=50 with a different look This same technique may be introduced in the definition of the circular knot3(): function knot6(a,p,q,R,r) = let( t = [(r*cos(q*a+alpha) + R), 0, r*sin(q*a) ] ) // circle in xz [ [ cos(p*a), sin(p*a), 0], [sin(p*a), cos(p*a), 0], // rotation in z of p*a degrees [0,0,1] ] * t; to achieve other basket shapes: with the same parameters (7,11,80,50). All this open up infinite possibilities to shape torus knots: just define a suitable expression of t in knot5() ! That was a rather long message. I will leave the sweep aspects to another time. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Administrator

OK, I give up.
I can see how it gets a face pointing to the centre. How are you calling knot() to get a shape to hull in the right direction, such as a three sided cylinder. And I'm getting results that appear as if r was negligable, looking from the top its a circle.
Admin  PM me if you need anything,
or if I've done something stupid... Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! 
Michael, where you may use almost any of my knot functions instead of knot4(). Chose the values of p, q, alpha and beta at your will.To make my discussion clearer I have dropped all scales from knotAng(). To apply the my knot functions to @codifies code you should recode knotAng() as: p = 7; q = 11; alpha = 80; beta =50; function knotAng(a,s) = [[s,0,0],[0,s,0],[0,0,s*1.5]]*knot4(a,p,q,2,1); "I can see how it gets a face pointing to the centre." 20170413 0:10 GMT03:00 MichaelAtOz <[hidden email]>: OK, I give up. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Free forum by Nabble  Scala forum  Edit this page 