Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am using Cylinder to produce wide flat disks (in Mathematica 8). This works just fine except that the circular base of such a cylinder turns out to be really just a 40-gon which is simply too coarse an approximation to a circle for what I have in mind. Is there a way to convince Mathematica to use say a 200-gon as a circular base for a cylinder?

Here is an example of the kind of picture that I am trying to create. Zoom in to see how coarse the cylinders' curved surfaces pan out.

Graphics3D[{Cylinder[{{0, 0, 0}, 0.0011 {0.`, 0.`, -0.9510565162951536`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, 0.`, 0.9510565162951536`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.85065080835204`, 0.`, -0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.85065080835204`, 0.`, 0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.6881909602355868`, -0.5`, -0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.6881909602355868`, 0.5`, -0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.6881909602355868`, -0.5`, 0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.6881909602355868`, 0.5`, 0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.2628655560595668`, -0.8090169943749475`, \
-0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.2628655560595668`, 
      0.8090169943749475`, -0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.2628655560595668`, -0.8090169943749475`, 
      0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.2628655560595668`, 0.8090169943749475`, 
      0.42532540417601994`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, 0.`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, 0.`, 1.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.42532540417602`, 0.3090169943749474`, 
      0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.7236067977499789`, 0.5257311121191336`, 
      0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.16245984811645317`, 0.5`, 0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.2628655560595668`, 0.8090169943749473`, 
      0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.27639320225002106`, 0.8506508083520399`, 
      0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.42532540417602`, -0.3090169943749474`, 
      0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.7236067977499789`, -0.5257311121191336`, 
      0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.85065080835204`, 0.`, 0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.16245984811645317`, -0.5`, 0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.27639320225002106`, -0.8506508083520399`, 
      0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.2628655560595668`, -0.8090169943749473`, 
      0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.5257311121191336`, 0.`, 0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.8944271909999159`, 0.`, 0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.6881909602355868`, -0.5`, 0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.6881909602355868`, 0.5`, 0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.7236067977499789`, -0.5257311121191336`, \
-0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.42532540417602`, -0.3090169943749474`, \
-0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, 0.`, -1.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.2628655560595668`, -0.8090169943749473`, \
-0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.16245984811645317`, -0.5`, -0.8506508083520399`}}, .1],
   Cylinder[{{0, 0, 0}, 
    0.0011 {-0.27639320225002106`, -0.8506508083520399`, \
-0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.7236067977499789`, 
      0.5257311121191336`, -0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.42532540417602`, 
      0.3090169943749474`, -0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.85065080835204`, 0.`, -0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.27639320225002106`, 
      0.8506508083520399`, -0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.16245984811645317`, 0.5`, -0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.2628655560595668`, 
      0.8090169943749473`, -0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.8944271909999159`, 0.`, -0.4472135954999579`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.5257311121191336`, 0.`, -0.8506508083520399`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.6881909602355868`, 0.5`, -0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.6881909602355868`, -0.5`, -0.5257311121191336`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, 1.`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.5877852522924731`, 0.8090169943749473`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.9510565162951535`, 0.3090169943749474`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.9510565162951535`, -0.3090169943749474`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {-0.5877852522924731`, -0.8090169943749473`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 0.0011 {0.`, -1.`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.5877852522924731`, -0.8090169943749473`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.9510565162951535`, -0.3090169943749474`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.9510565162951535`, 0.3090169943749474`, 0.`}}, .1], 
  Cylinder[{{0, 0, 0}, 
    0.0011 {0.5877852522924731`, 0.8090169943749473`, 0.`}}, .1]}]
share|improve this question
    
I think I've seen someone use a hidden option once for sphere's but I cannot find where ... –  Szabolcs Jun 25 at 23:59
    
Out of curiosity how did you determine it is a 40-gon? –  mfvonh Jun 26 at 0:46
    
Never mind, I see the roughness now. –  Mr.Wizard Jun 26 at 1:03
1  
I am experimenting with exporting Mathematica output in .stl format for 3d printing. This sort of exporting seems to work well if it only involves basic objects like cylinders but seems to prone to create problems when you try to export fancier stuff. Anyway, here is what a collection of cylinders looks like when you preview it at Shapeways. To determine that it's a 40-gon just output to pdf and then have a close look in a vector graphics program. –  Burkard Polster Jun 26 at 1:05
    
I pulled the version-8 tag since this applies multiple versions. –  Mr.Wizard Jun 26 at 1:27

4 Answers 4

up vote 13 down vote accepted

You can fix this problem by using the following Option in Graphics3D:

Method -> {"CylinderPoints" -> {200, 1}}

Adjust 200 to match your requirements. (Indeed the default is 40.)

Edit: I don't know exactly what the second parameter does, but using the single parameter form shown in the documentation linked below results in a big slow-down. I could guess that it is points in the other direction but that doesn't seem to make sense. Anyway I can't tell the visual difference between {200, 1} and {200, 200} but the former is much faster than the latter. ("CylinderPoints" -> 200 is apparently equivalent to "CylinderPoints" -> {200, 200}.)

You can make the change permanent with the Option Inspector by changing this value in the Graphics3DBoxOptions:

enter image description here

From Three-Dimensional Graphics Primitives

Even though Cone, Cylinder and Sphere produce high-quality renderings, their usage is scalable. A single image can contain thousands of these primitives. When rendering so many primitives, you can increase the efficiency of rendering by using special options to change the number of points used by default to render Cone, Cylinder and Sphere. The "ConePoints" Method option to Graphics3D is used to reduce the rendering quality of each individual cone. Cylinder and sphere quality can be similarly adjusted using "CylinderPoints" and "SpherePoints", respectively.

40 points:

enter image description here

200 points:

enter image description here

share|improve this answer
    
Crushed it as usual. What does the second element in the option setting do? I don't see an explanation in the docs. –  mfvonh Jun 26 at 1:17
    
@mfvonh It is apparently superfluous based on the example in the tutorial I just linked. –  Mr.Wizard Jun 26 at 1:24
    
Thank you very much for that. Exactly what I was looking for! –  Burkard Polster Jun 26 at 1:31
    
@Mr.Wizard I hope it was not presumptuous of me to add pictures to show your solution in all its glory :) –  mfvonh Jun 26 at 1:33
    
@mfvonh Thanks for the examples! –  Mr.Wizard Jun 26 at 1:33

The direct answer has been given by Mr. Wizard already, but there is also another way that renders smoothly while giving some additional advantages:

Use Tube instead of Cylinder. One advantage is that Tube allows you to do additional styling with VertexColors, not supported by Cylinder.

I will assume that we named your large list of Cylinder objects artwork. Using this, you can render the Tube version like this:

Graphics3D[{CapForm["Butt"], 
 artwork /. Cylinder -> Tube}, 
 Method -> {"TubePoints" -> 600}]

Tube

Here, TubePoints is the equivalent to CylinderPoints in Mr.Wizard's answer. I deliberately cranked up the number of points to 600 to see if there is any noticeable lag with Tube. It seems that this method produces output that is just as responsive as the Cylinder method with Method -> {"CylinderPoints" -> {600, 1}}.

Edit to address follow-up question about Export

As was not initially clear, the ultimate goal of the question is to produce a 3D graphics that can be exported to STL format at the same vertex count that is displayed in Mathematica.

This is not the case with solutions based on Cylinder or Tube as far as we've been able to tell so far. Therefore, I revisited another answer where I made a custom cylinder function motivated by the desire to incorporate VertexNormals. It's slight overkill here because that function allows an arbitrary cross-sectional shape which we don't need here. But since I already have it, this seemed easiest to me. Also, prism can be used in its own right to generalize the question.

First I recall the function prism from that answer, and then I wrap it by a function cyl that emulates a Cylinder between two points:

ClearAll[prism]
prism[pts_List, h_] := 
 Module[{bottoms, tops, surfacePoints, sidePoints},
  surfacePoints = 
   Table[Map[PadRight[#, 3, height] &, pts], {height, {0, h}}];
  {bottoms, tops} = {Most[#], Rest[#]} &@surfacePoints;
  sidePoints = 
   Flatten[{bottoms, RotateLeft[bottoms, {0, 1}], 
     RotateLeft[tops, {0, 1}], tops}, {{2, 3}, {1}}];
  MapThread[
   Polygon[#1, VertexNormals -> (#1 - #2)] &,
   {
    Join[sidePoints, surfacePoints],
    Join[Map[{0, 0, 1} # &, sidePoints, {2}],
     Map[({1, 1, 0} # + {0, 0, h/2}) &, surfacePoints, {2}]
     ]
    }
   ]
  ]

cyl[{pt1_, pt2_}, r_, n_: 90] := Module[{
   circle = 
    r Table[{Cos[ϕ], Sin[ϕ]}, {ϕ, Pi/n, 2 Pi, Pi/n}],
   h = EuclideanDistance[pt1, pt2]},
  GeometricTransformation[prism[circle, h], 
   Composition[TranslationTransform[pt1], 
    Quiet[Check[RotationTransform[{{0, 0, 1.}, pt2 - pt1}], 
      Identity]]]]]

gg = Graphics3D[artwork /. Cylinder -> cyl];

Export["gg.stl", gg]

The result is in gg, and the default vertex count around the perimeter is n=90. You can verify in an external program that this count is preserved in the Export. Here is what it looks like in Blender with the default 90 polygon points:

blender

share|improve this answer
    
Oops, looks like the second parameter was important after all! It's super slow without it. I'll be curious to know how this compares to Method -> {"CylinderPoints" -> {200, 1}} on your machine. –  Mr.Wizard Jun 26 at 2:29
    
That does the trick! With Method -> {"CylinderPoints" -> {600, 1}} your plot seems to be just as responsive as the Tube version. So the speed isn't an issue anymore, and I'll edit my answer to account for your update. –  Jens Jun 26 at 2:33
    
Good; I'm seeing the same behavior here. +1 for showing a different way. –  Mr.Wizard Jun 26 at 2:34
    
Looks like a great solution with a lot of scope for refining the output, e.g. by using a ring as a cross-section instead of a circle to create an empty core. Thank you very much for your help with solving this problem, and thank you also again to Mr. Wizard. –  Burkard Polster Jun 26 at 4:52

Here's a replacement for Cylinder that uses splines.

Clear[splineCylinder];
splineCylinder[{a_, b_}, r_: 1] :=
  Module[{
    base = r {{0, -1, 0}, {1, -1, 0}, {1, 1, 0}, {0, 1, 0},
              {-1, 1, 0}, {-1, -1, 0}, {0, -1, 0}},
    weights = {1, 0.5, 0.5, 1, 0.5, 0.5, 1},
    knots = {0, 0, 0, 1/4, 1/2, 1/2, 3/4, 1, 1, 1},
    transform, baseA, baseB
    },
    transform = If[Chop@Cross[{0, 0, 1}, b - a] == {0, 0, 0}, Identity, 
      RotationTransform[{{0, 0, 1}, Normalize[b - a]}]];
    baseA = a + transform@# & /@ base;
    baseB = b + transform@# & /@ base;

    BSplineSurface[#, SplineDegree -> 2, SplineKnots -> {Automatic, knots}, 
      SplineWeights -> {weights, weights}, SplineClosed -> {False, True}] & /@
    {
      {baseA, baseB},
      {baseA, a + 0 # & /@ base},
      {baseB, b + 0 # & /@ base}
    }
  ]

It's smoother, yet slower. It also has a balloon knot in the centre of each cap. But you can't see that in your graphic.

splineCylinder

Edit: This fails utterly to be exported to an STL file. It appears that exporting a 3D spline is not yet fully implemented in Mathematica (9.0.1).

share|improve this answer
    
I was waiting for someone to post this. +1 –  Mr.Wizard Jun 27 at 0:17

Perhaps you could hack together disks using a plotting function (and use PlotPoints if necessary)?

PolarPlot[1, {\[Theta], 0, 2 Pi}, PlotPoints -> 1000];
Cases[%, _Line, Infinity] /. {p__?NumberQ} :> {p, 0};
%[[1,1]] // Length
%% // Graphics3D

1761

enter image description here

share|improve this answer
    
I am experimenting with exporting Mathematica output in .stl format for 3d printing. This sort of exporting seems to work well if it only involves basic objects like cylinders but seems to prone to create problems when you try to export fancier stuff. Anyway, here is what a collection of cylinders looks like when you preview it at Shapeways. –  Burkard Polster Jun 26 at 1:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.