Z
Zacariaz
Tue, Sep 25, 2018 11:35 PM
I am new here and frankly I haven't got the slightest clue how this system
works, so I'm just gonna post my question, and if I'm doing something wrong,
I apologize in advance.
In short, I feel like I got the hang of openscad, even though it is still
fairly new to me. I have however stumbled upon a problem that is beyond me,
trying to make a model of the twisted torus, and well, I have succeeded,
sort of, but I'm think there must be a better way, as this is not at all
viable.
twistedTorus( 25, 50 );
#translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:1:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
Also I apologize for all the curly bracket, but I like to keep things in
order, inconvenient though it may be. ;)
The issue should be evident. The model is only a facsimile, and a bad one at
that. It is very resource intensive to render even in it's current form and
if you want to step it up a notch to something useful, you've got to find a
better way, which is why I'm asking here, how to attach this problem.
You could say that what I need is rotate_extrude_with_a_twist(), but I don't
see how.
Best regards.
--
Sent from: http://forum.openscad.org/
I am new here and frankly I haven't got the slightest clue how this system
works, so I'm just gonna post my question, and if I'm doing something wrong,
I apologize in advance.
In short, I feel like I got the hang of openscad, even though it is still
fairly new to me. I have however stumbled upon a problem that is beyond me,
trying to make a model of the twisted torus, and well, I have succeeded,
sort of, but I'm think there must be a better way, as this is not at all
viable.
twistedTorus( 25, 50 );
#translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:1:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
Also I apologize for all the curly bracket, but I like to keep things in
order, inconvenient though it may be. ;)
The issue should be evident. The model is only a facsimile, and a bad one at
that. It is very resource intensive to render even in it's current form and
if you want to step it up a notch to something useful, you've got to find a
better way, which is why I'm asking here, how to attach this problem.
You could say that what I need is rotate_extrude_with_a_twist(), but I don't
see how.
Best regards.
--
Sent from: http://forum.openscad.org/
ER
Ezra Reynolds
Wed, Sep 26, 2018 12:24 AM
The quick answer is that you are mixing 2D (square, circle) and 3D.
OpenScad treats 2D shapes as having a slight thickness for rendering
purposes, but when creating an actual model the model will be blank
because a square or circle does not exist in 3D space.
Adding a linear_extrude (1) (or some other thickness) will give the
torus-slice a thickness, which is then (SLOWLY) added together to make a
shape. I say "SLOWLY" because it is going to be resource-intensive;
OpenScad is slow on boolean operations, and it always performs a
top-level union; so you have at least 360 boolean operations it has to
calculate.
This could be sped up by having fewer, but thicker, slices. The true
wizards here can come up with some variant that uses list comprehension
to generate a polyhedron that will render in blazing speed, but that is
outside my skill.
Side note, the matching brace style is known as Allman style or BSD
style. I prefer this style myself, although brace style is one of the
Great Religious Flame War topics among programmers.
Here is your code, with a slice size of 10 (affects both the loop and
the linear_extrude). Renders in decent time on my machine. The finer
resolution you go the slower it will be.
twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:10:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
linear_extrude(10) difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
On 2018-09-25 7:35 PM, Zacariaz wrote:
twistedTorus( 25, 50 );
#translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:1:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
Also I apologize for all the curly bracket, but I like to keep things in
order, inconvenient though it may be.;)
The issue should be evident. The model is only a facsimile, and a bad one at
that. It is very resource intensive to render even in it's current form and
if you want to step it up a notch to something useful, you've got to find a
better way, which is why I'm asking here, how to attach this problem.
You could say that what I need is rotate_extrude_with_a_twist(), but I don't
see how.
The quick answer is that you are mixing 2D (square, circle) and 3D.
OpenScad treats 2D shapes as having a slight thickness for rendering
purposes, but when creating an actual model the model will be blank
because a square or circle does not exist in 3D space.
Adding a linear_extrude (1) (or some other thickness) will give the
torus-slice a thickness, which is then (SLOWLY) added together to make a
shape. I say "SLOWLY" because it is going to be resource-intensive;
OpenScad is slow on boolean operations, and it always performs a
top-level union; so you have at least 360 boolean operations it has to
calculate.
This could be sped up by having fewer, but thicker, slices. The true
wizards here can come up with some variant that uses list comprehension
to generate a polyhedron that will render in blazing speed, but that is
outside my skill.
Side note, the matching brace style is known as Allman style or BSD
style. I prefer this style myself, although brace style is one of the
Great Religious Flame War topics among programmers.
-------------------------------
Here is your code, with a slice size of 10 (affects both the loop and
the linear_extrude). Renders in decent time on my machine. The finer
resolution you go the slower it will be.
------------------------
twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:10:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
linear_extrude(10) difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
------------------------------
On 2018-09-25 7:35 PM, Zacariaz wrote:
> twistedTorus( 25, 50 );
> #translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
>
> module twistedTorus( r1, r2, t )
> {
> for( i = [0:1:360] )
> {
> rotate( [90, 0, i] )
> {
> translate( [r2, 0, 0] )
> {
> rotate( [0, 0, i] )
> {
> difference()
> {
> circle( r1 );
> translate( [0, -r1, 0] ) square( [r1, 2*r1] );
> }
> }
> }
> }
> }
> }
>
> Also I apologize for all the curly bracket, but I like to keep things in
> order, inconvenient though it may be.;)
> The issue should be evident. The model is only a facsimile, and a bad one at
> that. It is very resource intensive to render even in it's current form and
> if you want to step it up a notch to something useful, you've got to find a
> better way, which is why I'm asking here, how to attach this problem.
>
> You could say that what I need is rotate_extrude_with_a_twist(), but I don't
> see how.
P
Parkinbot
Wed, Sep 26, 2018 6:55 AM
A moebius strip is a good exercise to explore and compare basic and advanced
OpenScad programming techniques.
There are many examples out there (in Thingiverse) where people define a
moebius with polyhedron in a more or less direct way. Also have a look at
these.
The approach I am showing here uses a more general library, which is a very
mighty instrument for many other applications.
Two basic techniques you can use for such a thing are explained in
https://www.thingiverse.com/thing:900137/files where you also find the
Naca_sweep lib used in the following code. As it would be a special case for
sweep() to connect a moebius structure into a ring with some (e.g. 0.5)
windings my code uses the trick to union two half moebius rings. Thus it
creates an affine representation of the two halfrings and lets the library
function sweep() do all the "hard" work.
The lib contains the definitions of sweep() as well as the affine
counterparts of translate() and rotate() Rx_(), and so on.
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
sweep(moebius(twist=1.5));
sweep(moebius(twist=1.5, start=180, end=360));
function moebius(r=100, start=0, step=1, end = 180, twist=0.5) =
[for(i=[start:step:end])
Rz_(i,
Tx_(r,
Rx_(90,
Rz_(i*twist, square())
)))];
function square(x=50, y=10) =
[[-x/2, -y/2, 0],
[-x/2, y/2, 0],
[x/2, y/2, 0],
[x/2, -y/2, 0]];
--
Sent from: http://forum.openscad.org/
A moebius strip is a good exercise to explore and compare basic and advanced
OpenScad programming techniques.
There are many examples out there (in Thingiverse) where people define a
moebius with polyhedron in a more or less direct way. Also have a look at
these.
The approach I am showing here uses a more general library, which is a very
mighty instrument for many other applications.
Two basic techniques you can use for such a thing are explained in
https://www.thingiverse.com/thing:900137/files where you also find the
Naca_sweep lib used in the following code. As it would be a special case for
sweep() to connect a moebius structure into a ring with some (e.g. 0.5)
windings my code uses the trick to union two half moebius rings. Thus it
creates an affine representation of the two halfrings and lets the library
function sweep() do all the "hard" work.
The lib contains the definitions of sweep() as well as the affine
counterparts of translate() and rotate() Rx_(), and so on.
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
sweep(moebius(twist=1.5));
sweep(moebius(twist=1.5, start=180, end=360));
function moebius(r=100, start=0, step=1, end = 180, twist=0.5) =
[for(i=[start:step:end])
Rz_(i,
Tx_(r,
Rx_(90,
Rz_(i*twist, square())
)))];
function square(x=50, y=10) =
[[-x/2, -y/2, 0],
[-x/2, y/2, 0],
[x/2, y/2, 0],
[x/2, -y/2, 0]];
--
Sent from: http://forum.openscad.org/
P
Parkinbot
Thu, Oct 4, 2018 7:03 AM
Ok, the full solution is:
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
twistedTorus( 25, 50 );
#translate( [-100, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
{
sweep(moebius(r1=100, r2=50, twist=1));
sweep(moebius(r1=100, r2=50, twist=1, start=180, end=360, N=N));
}
function moebius(r1=100, r2=50, start=0, end = 180, N=30, twist=0.5) =
[for(j=[0:N]) let(i= start+j*(end-start)/N)
Rz_(i,
Tx_(-r1,
Rx_(90,
Rz_(i*twist, halfcirc(r2))
)))];
function halfcirc(r=50, N=30) = [for(i=[0:N]) let(w=180/Ni) r[sin(w),
cos(w), 0]];
--
Sent from: http://forum.openscad.org/
Ok, the full solution is:
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
twistedTorus( 25, 50 );
#translate( [-100, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
{
sweep(moebius(r1=100, r2=50, twist=1));
sweep(moebius(r1=100, r2=50, twist=1, start=180, end=360, N=N));
}
function moebius(r1=100, r2=50, start=0, end = 180, N=30, twist=0.5) =
[for(j=[0:N]) let(i= start+j*(end-start)/N)
Rz_(i,
Tx_(-r1,
Rx_(90,
Rz_(i*twist, halfcirc(r2))
)))];
function halfcirc(r=50, N=30) = [for(i=[0:N]) let(w=180/N*i) r*[sin(w),
cos(w), 0]];
--
Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Fri, Oct 5, 2018 10:09 PM
Pakinbot,
Your sweep.scad alleviates all the burden of defining the faces of the
polyhedron enveloping the section vertices. It is very general and allows
that lofts may be build provided that the user computes all the section
positions and orientation in the space. For simple cases of tubular forms -
that is, all sections are equal - as the present case of twisted torus, the
user computation of the section positions could be avoided by a generic
process good enough for most cases. The strategy of that generic process is
to define the section positions in the planes "orthogonal to the sweep
path" translated to each path point. That is the strategy behind Oskar
Linde sweep.scad found in the list-comprehension-demos.
I guess that a code that computes the section positions for this case would
answer the needs of lots of modeling cases. As an example, the twisted
torus model might have the following simple expression:
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
twistedTorus( 25, 50 );
translate( [-50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
{
path1 = halfcirc(r2, N);
path2 = Rz_(180, path1);
sect = Rz_(-90, halfcirc(r1));
half1 = sweep_sections(path1, sect, 180);
half2 = sweep_sections(path2, sect, 180);
sweep(half1);
sweep(half2);
}
function halfcirc(r=50, N=30) =
[for(i=[0:N]) let(w=180/Ni) r[sin(w),cos(w), 0]];
where sweep_sections is the generic function that generates the list of
sections in position.
Loosely based on the Linde's sweep ideas, I have coded sweep_sections as:
// list of total rotations from p[0] to each p[i]
function totRots(n,lrot, Rz=identity(), M=[identity()]) =
len(M)>n ?
M :
totRots( n, lrot, Rz, concat(M, [lrot[len(M)-1]*M[len(M)-1]*Rz] ));
function sweep_sections(path, section, twist) =
let(p = path,
np = len(p),
Rz = rotZ(twist/(np-1)), // matriz of twist rotation between steps
// tangents to the path p
tgts = [[0,0,1],
-3p[0] + 4p[1] - p[2],
for(i=[1:np-2]) p[i+1]-p[i-1],
3p[np-1] - 4p[np-2] + p[np-3]
],
// rotation between two steps
lrot = [for(i=[0:np-1])frotFromTo(tgts[i], tgts[i+1])],
// list of total rotations from p[0] to each p[i]
rots = [for(i=0, Mi=identity(); i<=len(lrot); Mi= lrot[i]MiRz,
i=i+1) Mi] ) // same as totRots(len(p), lrot, Rz)
[for(i=[0:len(p)-1]) transl(transf(section,rots[i+1]),p[i])];
I have resorted to the "C-like for" in its code for simplicity but the
recursive function totRots may be used instead.
The definition above requires a number of useful helper functions I have in
my libraries:
// reflection matrix of direction v
function fmirror(v) =
norm(v)==0 ? [[1,0,0],[0,1,0],[0,0,1]] :
let(u = v/norm(v))
[ [1,0,0] - 2*u[0]u, [0,1,0] - 2u[1]u, [0,0,1] - 2u[2]*u ];
// rotation matrix of the minimum rotation
// bringing di to do
function frotFromTo(di,do) =
norm(di-do)==0 || norm(di)==0 || norm(do)==0 ?
[[1,0,0],[0,1,0],[0,0,1]] :
fmirror(do/norm(do)+di/norm(di)) * fmirror(di);
function identity() = [[1,0,0],[0,1,0],[0,0,1]];
// translation of a sequence of points
function transl(pts, d) = [for(pt=pts) pt+d];
// Z rotation matrix
function rotZ(ang) = let(c=cos(ang), s=sin(ang))
[[c,s,0],[-s,c,0],[0,0,1]];
// transform of a list of points by a 3x3 matrix
function transf(pts,M) = [for(pt=pts) M*pt];
Pakinbot,
Your sweep.scad alleviates all the burden of defining the faces of the
polyhedron enveloping the section vertices. It is very general and allows
that lofts may be build provided that the user computes all the section
positions and orientation in the space. For simple cases of tubular forms -
that is, all sections are equal - as the present case of twisted torus, the
user computation of the section positions could be avoided by a generic
process good enough for most cases. The strategy of that generic process is
to define the section positions in the planes "orthogonal to the sweep
path" translated to each path point. That is the strategy behind Oskar
Linde sweep.scad found in the list-comprehension-demos.
I guess that a code that computes the section positions for this case would
answer the needs of lots of modeling cases. As an example, the twisted
torus model might have the following simple expression:
use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files
twistedTorus( 25, 50 );
translate( [-50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
{
path1 = halfcirc(r2, N);
path2 = Rz_(180, path1);
sect = Rz_(-90, halfcirc(r1));
half1 = sweep_sections(path1, sect, 180);
half2 = sweep_sections(path2, sect, 180);
sweep(half1);
sweep(half2);
}
function halfcirc(r=50, N=30) =
[for(i=[0:N]) let(w=180/N*i) r*[sin(w),cos(w), 0]];
where sweep_sections is the generic function that generates the list of
sections in position.
Loosely based on the Linde's sweep ideas, I have coded sweep_sections as:
// list of total rotations from p[0] to each p[i]
function totRots(n,lrot, Rz=identity(), M=[identity()]) =
len(M)>n ?
M :
totRots( n, lrot, Rz, concat(M, [lrot[len(M)-1]*M[len(M)-1]*Rz] ));
function sweep_sections(path, section, twist) =
let(p = path,
np = len(p),
Rz = rotZ(twist/(np-1)), // matriz of twist rotation between steps
// tangents to the path p
tgts = [[0,0,1],
-3*p[0] + 4*p[1] - p[2],
for(i=[1:np-2]) p[i+1]-p[i-1],
3*p[np-1] - 4*p[np-2] + p[np-3]
],
// rotation between two steps
lrot = [for(i=[0:np-1])frotFromTo(tgts[i], tgts[i+1])],
// list of total rotations from p[0] to each p[i]
rots = [for(i=0, Mi=identity(); i<=len(lrot); Mi= lrot[i]*Mi*Rz,
i=i+1) Mi] ) // same as totRots(len(p), lrot, Rz)
[for(i=[0:len(p)-1]) transl(transf(section,rots[i+1]),p[i])];
I have resorted to the "C-like for" in its code for simplicity but the
recursive function totRots may be used instead.
The definition above requires a number of useful helper functions I have in
my libraries:
// reflection matrix of direction v
function fmirror(v) =
norm(v)==0 ? [[1,0,0],[0,1,0],[0,0,1]] :
let(u = v/norm(v))
[ [1,0,0] - 2*u[0]*u, [0,1,0] - 2*u[1]*u, [0,0,1] - 2*u[2]*u ];
// rotation matrix of the minimum rotation
// bringing di to do
function frotFromTo(di,do) =
norm(di-do)==0 || norm(di)==0 || norm(do)==0 ?
[[1,0,0],[0,1,0],[0,0,1]] :
fmirror(do/norm(do)+di/norm(di)) * fmirror(di);
function identity() = [[1,0,0],[0,1,0],[0,0,1]];
// translation of a sequence of points
function transl(pts, d) = [for(pt=pts) pt+d];
// Z rotation matrix
function rotZ(ang) = let(c=cos(ang), s=sin(ang))
[[c,s,0],[-s,c,0],[0,0,1]];
// transform of a list of points by a 3x3 matrix
function transf(pts,M) = [for(pt=pts) M*pt];
>
P
Parkinbot
Sat, Oct 6, 2018 8:09 AM
For simple cases of tubular forms -
that is, all sections are equal - as the present case of twisted torus,
the
user computation of the section positions could be avoided by a generic
process good enough for most cases.
This is true and the orthogonal approach can make things easy in certain
cases. But is a somehow oriented half circle (which is a one-liner) still a
simple case?
When I played around with the "original" sweep mentioned by you, I found it
quite difficult to define the right transformation paths and I still find it
a bit callenging.
Therefore I prefer the most general solution as it has a very easy logic:
- define a (optionally parametrized) 2D-shape in XY-plane
- map the shape to the desired path using affine operations an iteration
variable
To a man who has hammer the whole world looks like a nail.
For the discussed twisted half circle torus my sweep indeed supports a
"close" parameter that can be used to close tori with integral twists making
the half tori union obsolete.
twistedTorus( 25, 50 );
#translate( [-100.1, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
sweep(moebius(r1=100, r2=50, end= 360, twist=1), close = true);
--
Sent from: http://forum.openscad.org/
Ronaldo wrote
> For simple cases of tubular forms -
> that is, all sections are equal - as the present case of twisted torus,
> the
> user computation of the section positions could be avoided by a generic
> process good enough for most cases.
This is true and the orthogonal approach can make things easy in certain
cases. But is a somehow oriented half circle (which is a one-liner) still a
simple case?
When I played around with the "original" sweep mentioned by you, I found it
quite difficult to define the right transformation paths and I still find it
a bit callenging.
Therefore I prefer the most general solution as it has a very easy logic:
1. define a (optionally parametrized) 2D-shape in XY-plane
2. map the shape to the desired path using affine operations an iteration
variable
To a man who has hammer the whole world looks like a nail.
For the discussed twisted half circle torus my sweep indeed supports a
"close" parameter that can be used to close tori with integral twists making
the half tori union obsolete.
twistedTorus( 25, 50 );
#translate( [-100.1, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus(r1,r2,N=30)
sweep(moebius(r1=100, r2=50, end= 360, twist=1), close = true);
--
Sent from: http://forum.openscad.org/
Z
Zacariaz
Sat, Oct 6, 2018 11:30 PM
So I've finally put together a working module. It is by no means perfect, but
it'll do for my needs I think. In any case it's about the best I can achieve
at this point.
/*
r1: radius 1
r2: radius 2
ca: circle angle, i.e. 180 for a half circle and 360 for a full circle
seg: number of segments
*/
function flatten(l) = [ for (a = l) for (b = a) b ] ;
module twistedTorus( r1, r2, ca, seg )
{
s2 = round(2*(r1+r2)3.14/(2r1*3.14)*seg);
p = flatten(
[
for( ta = [0:360/s2:359] )
[
[
-sin(ta)*r2,
cos(ta)r2,
0
],
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)(cos(i)r1+r2),
cos(ta)(cos(i)*r1+r2),
sin(i)*r1
]
]
]);
f1 =
[
for( i = [0:len(p)-1])
[
i,
(i+1)%len(p),
(i+seg/(360/ca)+2)%len(p),
]
];
f2 =
[
for( i = [0:len(p)-1])
[
(i+1)%len(p),
(i+seg/(360/ca)+3)%len(p),
(i+seg/(360/ca)+2)%len(p)
]
];
polyhedron( points = p, faces = concat(f1,f2) );
}
twistedTorus(25.4/4, 25.4/2, 180, 60);
--
Sent from: http://forum.openscad.org/
So I've finally put together a working module. It is by no means perfect, but
it'll do for my needs I think. In any case it's about the best I can achieve
at this point.
/*
r1: radius 1
r2: radius 2
ca: circle angle, i.e. 180 for a half circle and 360 for a full circle
seg: number of segments
*/
function flatten(l) = [ for (a = l) for (b = a) b ] ;
module twistedTorus( r1, r2, ca, seg )
{
s2 = round(2*(r1+r2)*3.14/(2*r1*3.14)*seg);
p = flatten(
[
for( ta = [0:360/s2:359] )
[
[
-sin(ta)*r2,
cos(ta)*r2,
0
],
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
]
]);
f1 =
[
for( i = [0:len(p)-1])
[
i,
(i+1)%len(p),
(i+seg/(360/ca)+2)%len(p),
]
];
f2 =
[
for( i = [0:len(p)-1])
[
(i+1)%len(p),
(i+seg/(360/ca)+3)%len(p),
(i+seg/(360/ca)+2)%len(p)
]
];
polyhedron( points = p, faces = concat(f1,f2) );
}
twistedTorus(25.4/4, 25.4/2, 180, 60);
--
Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Mon, Oct 8, 2018 11:39 PM
Nice done. Just 3 cents:
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
c) the computation of the polyhedron vertices could be simply:
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)r1+r2),
cos(ta)(cos(i)*r1+r2),
sin(i)*r1
]
];
Nice done. Just 3 cents:
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
c) the computation of the polyhedron vertices could be simply:
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
];
Z
Zacariaz
Tue, Oct 9, 2018 2:52 PM
Nice done. Just 3 cents:
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
c) the computation of the polyhedron vertices could be simply:
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)r1+r2),
cos(ta)(cos(i)*r1+r2),
sin(i)*r1
]
];
As for your first point, good to know. Don't know how I've missed it, but in
this case it doesn't actually matter as it cancels out. It was more for
explanatory purposes.
Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
When working with integers, there really is not issue, because you can
always just say
for( [begin:step:end-1] )
to get the actual range you're looking for, but if your step is not and
integer, in this case 360/s, you need to go to extremes ot make it work,
like
for( [0:360/s:360-360/s] )
which can course problems due to floating point "errors", and don't even get
me started on the case that the loop doesn't start at 0, in which case
you'll have to ensure that you start at a multiple of 360/s, which is pretty
much impossible, when working with floating point values.
I actually did plan to ask what to do in such situations, because it goes
without saying that sometimes 360 iterations just isn't enough to achieve
the desired resolution, so to speak.
Personally I'm used to the C syntax and would much rather have written
for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
resolution.
and I don't see how to achieve the same effect with openscad syntax, without
going to extremes.
Lastly, what about the center point? I know it isn't strictly needed when
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
Or am I missing something?
And also thanks. To be honest, I can't help to be a little bit proud of
myself. Regardless, I do plan to try again from scratch, to see if I can't
do a better job of it.
--
Sent from: http://forum.openscad.org/
Ronaldo wrote
> Nice done. Just 3 cents:
> a) there is a predefined variable PI in the language;
> b) it is usually advisable to avoid a float as increment of a for;
> c) the computation of the polyhedron vertices could be simply:
>
> p =
> [
> for( ta = [0:360/s2:359] )
> for( i = [ta:360/seg:ca+ta] )
> [
> -sin(ta)*(cos(i)*r1+r2),
> cos(ta)*(cos(i)*r1+r2),
> sin(i)*r1
> ]
> ];
As for your first point, good to know. Don't know how I've missed it, but in
this case it doesn't actually matter as it cancels out. It was more for
explanatory purposes.
Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
When working with integers, there really is not issue, because you can
always just say
for( [begin:step:end-1] )
to get the actual range you're looking for, but if your step is not and
integer, in this case 360/s, you need to go to extremes ot make it work,
like
for( [0:360/s:360-360/s] )
which can course problems due to floating point "errors", and don't even get
me started on the case that the loop doesn't start at 0, in which case
you'll have to ensure that you start at a multiple of 360/s, which is pretty
much impossible, when working with floating point values.
I actually did plan to ask what to do in such situations, because it goes
without saying that sometimes 360 iterations just isn't enough to achieve
the desired resolution, so to speak.
Personally I'm used to the C syntax and would much rather have written
for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
resolution.
and I don't see how to achieve the same effect with openscad syntax, without
going to extremes.
Lastly, what about the center point? I know it isn't strictly needed when
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
Or am I missing something?
And also thanks. To be honest, I can't help to be a little bit proud of
myself. Regardless, I do plan to try again from scratch, to see if I can't
do a better job of it.
--
Sent from: http://forum.openscad.org/
TV
Tim V. Shaporev
Tue, Oct 9, 2018 4:11 PM
How many steps do you want in a loop?
for (i=[0:N-1]) [ cos(360*i/N),
or
for (i=[1:N]) [ cos(360*(i-1)/N),
something like that...
On 10/9/2018 5:52 PM, Zacariaz wrote:
Nice done. Just 3 cents:
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
c) the computation of the polyhedron vertices could be simply:
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)r1+r2),
cos(ta)(cos(i)*r1+r2),
sin(i)*r1
]
];
As for your first point, good to know. Don't know how I've missed it, but in
this case it doesn't actually matter as it cancels out. It was more for
explanatory purposes.
Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
When working with integers, there really is not issue, because you can
always just say
for( [begin:step:end-1] )
to get the actual range you're looking for, but if your step is not and
integer, in this case 360/s, you need to go to extremes ot make it work,
like
for( [0:360/s:360-360/s] )
which can course problems due to floating point "errors", and don't even get
me started on the case that the loop doesn't start at 0, in which case
you'll have to ensure that you start at a multiple of 360/s, which is pretty
much impossible, when working with floating point values.
I actually did plan to ask what to do in such situations, because it goes
without saying that sometimes 360 iterations just isn't enough to achieve
the desired resolution, so to speak.
Personally I'm used to the C syntax and would much rather have written
for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
resolution.
and I don't see how to achieve the same effect with openscad syntax, without
going to extremes.
Lastly, what about the center point? I know it isn't strictly needed when
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
Or am I missing something?
And also thanks. To be honest, I can't help to be a little bit proud of
myself. Regardless, I do plan to try again from scratch, to see if I can't
do a better job of it.
--
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
.
How many steps do you want in a loop?
for (i=[0:N-1]) [ cos(360*i/N),
or
for (i=[1:N]) [ cos(360*(i-1)/N),
something like that...
On 10/9/2018 5:52 PM, Zacariaz wrote:
> Ronaldo wrote
>> Nice done. Just 3 cents:
>> a) there is a predefined variable PI in the language;
>> b) it is usually advisable to avoid a float as increment of a for;
>> c) the computation of the polyhedron vertices could be simply:
>>
>> p =
>> [
>> for( ta = [0:360/s2:359] )
>> for( i = [ta:360/seg:ca+ta] )
>> [
>> -sin(ta)*(cos(i)*r1+r2),
>> cos(ta)*(cos(i)*r1+r2),
>> sin(i)*r1
>> ]
>> ];
>
> As for your first point, good to know. Don't know how I've missed it, but in
> this case it doesn't actually matter as it cancels out. It was more for
> explanatory purposes.
>
> Secondly I get what you're saying, and believe you me I've ha a lot of
> trouble getting the for loops in openscad to behave. The first for loop
> defining p pretty much explain the issue.
> When working with integers, there really is not issue, because you can
> always just say
> for( [begin:step:end-1] )
> to get the actual range you're looking for, but if your step is not and
> integer, in this case 360/s, you need to go to extremes ot make it work,
> like
> for( [0:360/s:360-360/s] )
> which can course problems due to floating point "errors", and don't even get
> me started on the case that the loop doesn't start at 0, in which case
> you'll have to ensure that you start at a multiple of 360/s, which is pretty
> much impossible, when working with floating point values.
> I actually did plan to ask what to do in such situations, because it goes
> without saying that sometimes 360 iterations just isn't enough to achieve
> the desired resolution, so to speak.
> Personally I'm used to the C syntax and would much rather have written
> for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
> resolution.
> and I don't see how to achieve the same effect with openscad syntax, without
> going to extremes.
>
> Lastly, what about the center point? I know it isn't strictly needed when
> splitting the torus in 2, but I do believe it increases the quality, and it
> certainly is need if you wish to split it into 3 or more, or simply use some
> arbitrary angle.
> Or am I missing something?
>
> And also thanks. To be honest, I can't help to be a little bit proud of
> myself. Regardless, I do plan to try again from scratch, to see if I can't
> do a better job of it.
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
> .
>