discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

converting to sperical coordinates

JB
Jordan Brown
Mon, Jan 7, 2019 7:05 PM

On 1/7/2019 9:00 AM, PhilipJ wrote:

Hi, thanks for the link.

I'm still trying to learn the language of openSCAD so could you explain:
in the module first line it says:
"module Line( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )"

what is "pts" ?
I assume it is the points for the line but how do I pass them into the
module through this one variable ?

As an example: how would I draw a line from 0,0,0 to 30,30,30 ?

Many thanks for your time

pts is an array of 3D points to connect.

The tersest answer to your question is

Line([[0,0,0],[30,30,30]]);

Reformatting a bit for readability:

Line([
[0,0,0],
[30,30,30]
]);

That will yield the default radius of 0.05 units.  You probably want
some other radius, so perhaps

Line([
[0,0,0],
[30,30,30]
], 5);

I'd recommend that you use positional arguments only in the most trivial
of cases, and that in more complex cases you use named arguments:

Line(r=5, pts=[
[0,0,0],
[30,30,30]
]);

The default for that module is to generate four-sided "cylinders".  You
can adjust that:

Line(r=5, fn=20, pts=[
[0,0,0],
[30,30,30]
]);

though I don't understand why there's an explicit fn parameter instead
of just using $fn.  I would remove the ", $fn=fn" from the cylinder call
at the end, and then any of these will work:

Line(r=5, $fn=20, pts=[
[0,0,0],
[30,30,30]
]);

$fn = 20;
Line(r=5, pts=[
[0,0,0],
[30,30,30]
]);

$fa = 10;
$fs = 0.1;
Line(r=5, pts=[
[0,0,0],
[30,30,30]
]);

I like that better because it integrates better with other OpenSCAD
constructs.

Similarly, I don't understand why there is an explicit color and
transparency options, rather than letting you control those using the
color() transformation.

Note that it's a list; you can connect multiple points, e.g.:

Line(r=5, pts=[
    [0,0,0],
    [30,30,30],
    [-30,30,30]
]);

On 1/7/2019 9:00 AM, PhilipJ wrote: > Hi, thanks for the link. > > I'm still trying to learn the language of openSCAD so could you explain: > in the module first line it says: > "module Line( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )" > > what is "pts" ? > I assume it is the points for the line but how do I pass them into the > module through this one variable ? > > As an example: how would I draw a line from 0,0,0 to 30,30,30 ? > > Many thanks for your time pts is an array of 3D points to connect. The tersest answer to your question is Line([[0,0,0],[30,30,30]]); Reformatting a bit for readability: Line([ [0,0,0], [30,30,30] ]); That will yield the default radius of 0.05 units.  You probably want some other radius, so perhaps Line([ [0,0,0], [30,30,30] ], 5); I'd recommend that you use positional arguments only in the most trivial of cases, and that in more complex cases you use named arguments: Line(r=5, pts=[ [0,0,0], [30,30,30] ]); The default for that module is to generate four-sided "cylinders".  You can adjust that: Line(r=5, fn=20, pts=[ [0,0,0], [30,30,30] ]); though I don't understand why there's an explicit fn parameter instead of just using $fn.  I would remove the ", $fn=fn" from the cylinder call at the end, and then any of these will work: Line(r=5, $fn=20, pts=[ [0,0,0], [30,30,30] ]); $fn = 20; Line(r=5, pts=[ [0,0,0], [30,30,30] ]); $fa = 10; $fs = 0.1; Line(r=5, pts=[ [0,0,0], [30,30,30] ]); I like that better because it integrates better with other OpenSCAD constructs. Similarly, I don't understand why there is an explicit color and transparency options, rather than letting you control those using the color() transformation. Note that it's a list; you can connect multiple points, e.g.: Line(r=5, pts=[     [0,0,0],     [30,30,30],     [-30,30,30] ]);
P
PhilipJ
Mon, Jan 7, 2019 7:33 PM

pts is an array of 3D points to connect.

The tersest answer to your question is

Line([[0,0,0],[30,30,30]]);

Reformatting a bit for readability:

Line([
[0,0,0],
[30,30,30]
]);

Thanks, that is a great and comprehensive explanation, I appreciate it :-)

regards
PhilipJ

--
Sent from: http://forum.openscad.org/

> pts is an array of 3D points to connect. > > The tersest answer to your question is > > Line([[0,0,0],[30,30,30]]); > > Reformatting a bit for readability: > > Line([ > [0,0,0], > [30,30,30] > ]); Thanks, that is a great and comprehensive explanation, I appreciate it :-) regards PhilipJ -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Mon, Jan 7, 2019 8:43 PM

$fn=100 is pretty big.

Using a smaller number would cut down rendering and preview time.

Thanks, I tried different values, 10 makes the rods look like hexagons, 30
was still a bit rough but rendered 4 rods in 11 seconds, still seems
awfully
slow.

If th rods are made of cylinders and spheres with no hull function then the
Render takes fractions of a second, but I'm still trying to resolve the
cartesian to spherical coods bit so I can rotate the cylinder to the
correct
angles to join up...

The long render times are not due to the hull but the union of the rods.
Better times result if the rods are just cylinders without the spherical
cap because the vertex count is smaller. The following code runs relatively
fast compared to the hull solution, however the rod joint is not as much
smooth.

$fn=30;

rod_dia=3;

rod([ 0, 0,0], [10,10,30], rod_dia);
rod([20, 0,0], [10,10,30], rod_dia);
rod([ 0,20,0], [10,10,30], rod_dia);
rod([20,20,0], [10,10,30], rod_dia);

module rod(p1,p2,d)
translate(p1)
rotFromTo([0,0,1], p2-p1)
cylinder(d=d, h=norm(p2-p1));

module rotFromTo(di,do)
if( norm(di-do)==0 || norm(di)==0 || norm(do)==0 )
children();
else
mirror(do/norm(do)+di/norm(di)) mirror(di) children();

The module rotFromTo does exactly what you were searching for: rotates the
cylinder from the upward direction ( [0,0,1] ) to the desired direction.

For another approach, take a look on

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Rotation_rule_help

BTW, you may want to subscribe to the mailing list in order to have a
broader audience to your messages. Some people, like me, usually don't read
the forum messages in the forum site but rather from their mail box.

Jan 07, 2019; 5:08pm [image: PhilipJ] <http://forum.openscad.org/template/NamlServlet.jtp?macro=user_nodes&user=2371> PhilipJ <http://forum.openscad.org/template/NamlServlet.jtp?macro=user_nodes&user=2371> > > $fn=100 is pretty big. > > > Using a smaller number would cut down rendering and preview time. > > Thanks, I tried different values, 10 makes the rods look like hexagons, 30 > was still a bit rough but rendered 4 rods in 11 seconds, still seems > awfully > slow. > > If th rods are made of cylinders and spheres with no hull function then the > Render takes fractions of a second, but I'm still trying to resolve the > cartesian to spherical coods bit so I can rotate the cylinder to the > correct > angles to join up... The long render times are not due to the hull but the union of the rods. Better times result if the rods are just cylinders without the spherical cap because the vertex count is smaller. The following code runs relatively fast compared to the hull solution, however the rod joint is not as much smooth. $fn=30; rod_dia=3; rod([ 0, 0,0], [10,10,30], rod_dia); rod([20, 0,0], [10,10,30], rod_dia); rod([ 0,20,0], [10,10,30], rod_dia); rod([20,20,0], [10,10,30], rod_dia); module rod(p1,p2,d) translate(p1) rotFromTo([0,0,1], p2-p1) cylinder(d=d, h=norm(p2-p1)); module rotFromTo(di,do) if( norm(di-do)==0 || norm(di)==0 || norm(do)==0 ) children(); else mirror(do/norm(do)+di/norm(di)) mirror(di) children(); The module rotFromTo does exactly what you were searching for: rotates the cylinder from the upward direction ( [0,0,1] ) to the desired direction. For another approach, take a look on https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Rotation_rule_help BTW, you may want to subscribe to the mailing list in order to have a broader audience to your messages. Some people, like me, usually don't read the forum messages in the forum site but rather from their mail box.
P
PhilipJ
Tue, Jan 8, 2019 10:39 AM

Si I have found the solution to my conversion problem, it was in the help
text under rotate (if only I'd read it properly!!).

Thus if "a" is fixed to zero, and "b" and "c" are manipulated
appropriately, this is the spherical coordinate system.
So, to construct a cylinder from the origin to some other point (x,y,z):

x= 10; y = 10; z = 10; // point coordinates of end of cylinder

length = norm([x,y,z]);  // radial distance
b = acos(z/length); // inclination angle
c = atan2(y,x);    // azimuthal angle

rotate([0, b, c])
cylinder(h=length, r=0.5);
%cube([x,y,z]); // corner of cube should coincide with end of cylinder

All my attempts used atan2() for both angles, this uses acos for one of
them, I don't know what the difference is but this one works for all four
quadrant angles.

Thanks to everyone who took time to offer suggestions, now moving on to the
geodesic dome :-)
PhilipJ

--
Sent from: http://forum.openscad.org/

Si I have found the solution to my conversion problem, it was in the help text under rotate (if only I'd read it properly!!). >> Thus if "a" is fixed to zero, and "b" and "c" are manipulated >> appropriately, this is the spherical coordinate system. >> So, to construct a cylinder from the origin to some other point (x,y,z): >> x= 10; y = 10; z = 10; // point coordinates of end of cylinder >> length = norm([x,y,z]); // radial distance >> b = acos(z/length); // inclination angle >> c = atan2(y,x); // azimuthal angle >> >> rotate([0, b, c]) >> cylinder(h=length, r=0.5); >> %cube([x,y,z]); // corner of cube should coincide with end of cylinder All my attempts used atan2() for both angles, this uses acos for one of them, I don't know what the difference is but this one works for all four quadrant angles. Thanks to everyone who took time to offer suggestions, now moving on to the geodesic dome :-) PhilipJ -- Sent from: http://forum.openscad.org/
R
runsun
Tue, Jan 8, 2019 10:04 PM

JordanBrown answered it in details. One more "pt" to add: that Line(pts...)
function is able to take multiple points:

Line( pts= [ [2,3,4],[5,6,7],[1,2,3] ... ] );

So you can throw in hundreds or even thousands of pts and it will draw like
a cham. This efficiency is something the hull() can't achieve.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

JordanBrown answered it in details. One more "pt" to add: that *Line(pts...)* function is able to take multiple points: Line( pts= [ [2,3,4],[5,6,7],[1,2,3] ... ] ); So you can throw in hundreds or even thousands of pts and it will draw like a cham. This efficiency is something the hull() can't achieve. ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Wed, Jan 9, 2019 11:31 AM

Em ter, 8 de jan de 2019 às 22:05, runsun runsun@gmail.com escreveu:

Line( pts= [ [2,3,4],[5,6,7],[1,2,3] ... ] );

So you can throw in hundreds or even thousands of pts and it will draw like
a cham.* This efficiency is something the hull() can't achieve.*

runsun,

I disagree. The hull() operation (at least in this case of convex sets) is
very fast compared to the union of the rods. I have done some tests to show
it.

  1. define the rods and the Phillip's tent frame as:

$fn=30;
translate([ 0, 0,0]) rotFromTo([0,0,1],-([ 0, 0,0] - [10,10,30]))
rod(rod_dia);
//translate([20, 0,0]) rotFromTo([0,0,1],-([20, 0,0] - [10,10,30]))
rod(rod_dia);
//translate([ 0,20,0]) rotFromTo([0,0,1],-([ 0,20,0] - [10,10,30]))
rod(rod_dia);
//translate([20,20,0]) rotFromTo([0,0,1],-([20,20,0] - [10,10,30]))
rod(rod_dia);

module rod(d)
hull() {
sphere(d/2);
translate([0,0,norm([ 0, 0,0] - [10,10,30])]) sphere(d/2);
}

Now, the rods are fixed length and vertical. Render this code with a clean
cache. The hulled rod will be in the cache. Render again dropping the
comments in the main code. The last running time will be spent just in the
union. In my computer, it is (surprisingly) greater then the render time of
the original code.

  1. In the original code, instead of the hulled rods draw just a sphere at
    the top end. The render time will again show the union render time. In my
    computer, it is again (and very surprisingly) greater then the render time
    of the original code.

Conclusion: the render time of the hull() operation is negligible compared
to the union operation. Even the union of 4 disjoint sphere spends more
render time than the hull() of them.

Em ter, 8 de jan de 2019 às 22:05, runsun <runsun@gmail.com> escreveu: > Line( pts= [ [2,3,4],[5,6,7],[1,2,3] ... ] ); > > So you can throw in hundreds or even thousands of pts and it will draw like > a cham.* This efficiency is something the hull() can't achieve.* > runsun, I disagree. The hull() operation (at least in this case of convex sets) is very fast compared to the union of the rods. I have done some tests to show it. 1) define the rods and the Phillip's tent frame as: $fn=30; translate([ 0, 0,0]) rotFromTo([0,0,1],-([ 0, 0,0] - [10,10,30])) rod(rod_dia); //translate([20, 0,0]) rotFromTo([0,0,1],-([20, 0,0] - [10,10,30])) rod(rod_dia); //translate([ 0,20,0]) rotFromTo([0,0,1],-([ 0,20,0] - [10,10,30])) rod(rod_dia); //translate([20,20,0]) rotFromTo([0,0,1],-([20,20,0] - [10,10,30])) rod(rod_dia); module rod(d) hull() { sphere(d/2); translate([0,0,norm([ 0, 0,0] - [10,10,30])]) sphere(d/2); } Now, the rods are fixed length and vertical. Render this code with a clean cache. The hulled rod will be in the cache. Render again dropping the comments in the main code. The last running time will be spent just in the union. In my computer, it is (surprisingly) greater then the render time of the original code. 2) In the original code, instead of the hulled rods draw just a sphere at the top end. The render time will again show the union render time. In my computer, it is again (and very surprisingly) greater then the render time of the original code. Conclusion: the render time of the hull() operation is negligible compared to the union operation. Even the union of 4 disjoint sphere spends more render time than the hull() of them.
R
runsun
Wed, Jan 9, 2019 11:57 PM

@Ronaldo,  Thx. I did mention "hundreds or thousands of points". Have you
tested that many points?


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

@Ronaldo, Thx. I did mention "hundreds or thousands of points". Have you tested that many points? ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
R
runsun
Thu, Jan 10, 2019 12:14 AM

Have to correct myself on this --- in the past I did preview, never did
render. With some preliminary tests now, rendering on "hundreds/thousands of
pts" with either Line() or rod() seems impossible (takes too long), so it's
hard to state which is faster in my tests.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

Have to correct myself on this --- in the past I did preview, never did render. With some preliminary tests now, rendering on "hundreds/thousands of pts" with either Line() or rod() seems impossible (takes too long), so it's hard to state which is faster in my tests. ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Jan 10, 2019 4:39 PM

Em qui, 10 de jan de 2019 às 00:15, runsun runsun@gmail.com escreveu:

Have to correct myself on this --- in the past I did preview, never did
render. With some preliminary tests now, rendering on "hundreds/thousands
of
pts" with either Line() or rod() seems impossible (takes too long), so it's
hard to state which is faster in my tests.

I use my version of Line only in preview mode for debugging geometry. To
avoid any accidental render of lines, I check $preview inside of Line and
inhibit the drawing if false.

Em qui, 10 de jan de 2019 às 00:15, runsun <runsun@gmail.com> escreveu: > Have to correct myself on this --- in the past I did preview, never did > render. With some preliminary tests now, rendering on "hundreds/thousands > of > pts" with either Line() or rod() seems impossible (takes too long), so it's > hard to state which is faster in my tests. > I use my version of Line only in preview mode for debugging geometry. To avoid any accidental render of lines, I check $preview inside of Line and inhibit the drawing if false.