Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Displaying cylinders

  • To: mathgroup at smc.vnet.net
  • Subject: [mg110865] Re: Displaying cylinders
  • From: "David Park" <djmpark at comcast.net>
  • Date: Thu, 8 Jul 2010 20:35:04 -0400 (EDT)

Well, you always present interesting graphics problems. Presentations does
have Circle3D and Disk3D, (Using a flattened Cylinder isn't that bad, but
isn't it easier to think in terms of a 2D object in 3D space?). So using
Circle3D and the Presentations, PlaneGeometry, triangleCircumcenter routine
we can easily construct the graphic.

Needs["Presentations`Master`"] 

First, here is your example:

cp1 = {1, -1, 2};
cp2 = {2, 0, 1};
cp3 = {-1, 3, 2};
Draw3DItems[
 {AbsoluteThickness[4],
  Yellow, Circle3D[cp1, {1, -1, 1}, 12],
  Green, Circle3D[cp2, -{1, 1, -1}, 15],
  Red, Circle3D[cp3, -{1, 1, 1}, 12]},
 NiceRotation,
 Boxed -> False
 ] 

But you wanted to define the circles by three points. Here is a routine that
calculates the 3D center from the three points.

sphereCenter::usage = 
  "sphereCenter[{p1, p2, p3}] calculates the center of a sphere that \
passes through the three points p1, p2, p3 and lies in the plane of \
the three points.";
SyntaxInformation[sphereCenter] = {"ArgumentsPattern" -> {{_, _, _}}};
sphereCenter[{p1_, p2_, p3_}] :=
 Module[{normal, q1, q2, q3, center},
  (* Translate p1 to the origin = q1 *)
  {q1, q2, q3} = TranslationTransform[-p1]@{p1, p2, p3};
  (* Calculate a normal vector *)
  normal = q2\[Cross]q3;
  (* Rotate the normal vector to the z vector *)
  {q1, q2, q3} = 
   RotationTransform[{normal, {0, 0, 1}}]@{q1, q2, q3} // Chop;
  (* Find the center in 2D by dropping z components *)
  center = First@triangleCircumcenter[Drop[#, -1] & /@ {q1, q2, q3}];
  (* Pad and inverse rotate *)
  center = 
   RotationTransform[{{0, 0, 1}, normal}]@PadRight[center, 3] // Chop;
  (* Translate the origin back to p1*)
  center = TranslationTransform[p1]@center] 

The following generates a set of 10 random sets of circle points.

circlePoints = RandomReal[{0, 10}, {10, 3, 3}]; 

The following draws all the circles using colors picked from an indexed
color set.

Draw3DItems[
 {AbsoluteThickness[4],
  Table[
   Module[{p1, p2, p3, center, normal, radius},
    {p1, p2, p3} = circlePoints[[i]];
    center = sphereCenter[{p1, p2, p3}];
    normal = Cross[p1 - p2, p1 - p3];
    radius = Norm[p1 - center];
    {ColorData[31, i], Circle3D[center, normal, radius]}
    ], {i, 1, 10}]},
 NiceRotation,
 Boxed -> False
 ] 

The following adds the defining points to the circles.

Draw3DItems[
 {AbsoluteThickness[4],
  Table[
   Module[{p1, p2, p3, center, normal, radius},
    {p1, p2, p3} = circlePoints[[i]];
    center = sphereCenter[{p1, p2, p3}];
    normal = Cross[p1 - p2, p1 - p3];
    radius = Norm[p1 - center];
    {ColorData[31, i],
     Circle3D[center, normal, radius],
     AbsolutePointSize[5], Opacity[.999, Black],
     Point[{p1, p2, p3}]}
    ], {i, 1, 10}]},
 NiceRotation,
 Boxed -> False
 ] 

The following adds a low opacity disk to each circle.

Draw3DItems[
 {AbsoluteThickness[4],
  Table[
   Module[{p1, p2, p3, center, normal, radius},
    {p1, p2, p3} = circlePoints[[i]];
    center = sphereCenter[{p1, p2, p3}];
    normal = Cross[p1 - p2, p1 - p3];
    radius = Norm[p1 - center];
    {ColorData[31, i], Opacity[.999], Circle3D[center, normal, radius],
     Opacity[.1],
     Disk3D[center, normal, radius, Mesh -> None, MaxRecursion -> 1, 
      PlotPoints -> 10],
     AbsolutePointSize[5], Opacity[.999, Black],
     Point[{p1, p2, p3}]}
    ], {i, 1, 10}]},
 NiceRotation,
 Boxed -> False
 ] 


David Park
djmpark at comcast.net
http://home.comcast.net/~djmpark/  



From: S. B. Gray [mailto:stevebg at ROADRUNNER.COM] 

I have displays like this:

th = .01;
cp1 = {  1, -1, 2};
cp2 = {  2,   0, 1};
cp3 = {-1,   3, 2};
Graphics3D[{Opacity[.4],
   Yellow, Cylinder[{cp1, cp1 + {th, -th, th}}, 12],
   Green,  Cylinder[{cp2, cp2 - {th, th, -th}}, 15],
   Red,    Cylinder[{cp3, cp3 + {-th, -th, -th}}, 12]},
  Boxed -> False]

but the cylinders are stand-ins for what I really want, which is circles 
in 3D. (I would like a 3D circle primitive with circles defined by three 
points, rather than the way cylinders are specified.)

The smallest number of circles in the actual application is 20, so it is 
almost impossible to see how they interact, no matter what Opacity is 
set to. It would be much better if I could make the edges thicker and 
opaque (with EdgeForm), and have the cylinder ends or sides transparent. 
That way the edges (rings or circles) would occlude each other so it 
would be clear what is in front of what. So far as I know, the edges 
cannot be contolled separately. If you set "th" to a higher value, you 
get a double ring which is really the cylinder side, which also cannot 
be given its own Opacity.

I've tried parametric plot to display thick torii, but it's glacially 
slow. Any tips will be appreciated.

Steve Gray




  • Prev by Date: Re: FindMinimum numerical constraint functions
  • Next by Date: Re: Problem with a diagram
  • Previous by thread: Re: Displaying cylinders
  • Next by thread: Re: Displaying cylinders