7
$\begingroup$

Consider the following:

g1 = Graphics3D[{Black, Sphere[{0, 0, 0}, 0.1]}];
g2 = Graphics3D[{Directive[Red, Thickness[0.02]], InfiniteLine[{0, 0, 0}, {1, 0, 0}]}];
Show[{g1, g2}, PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}, Boxed -> False, ImageSize -> Large]

When I rotate the resulting 3D image, the red line will clip through the black sphere, despite being smaller than the sphere radius. The edge where they meet appears two dimensional and at some angles the line is completely visible as though it were outside the sphere, see below. How can I prevent this?

enter image description here

enter image description here

$\endgroup$
13
$\begingroup$

I recommend using tubes to represent thick lines in 3D graphics. They look better because they are true 3D objects with circular cross-setions and not flat ribbons, which are how thick lines are drawn in 3D graphics.

Graphics3D[
  {{Black, Sphere[{0, 0, 0}, 0.1]}, {Red, Tube[{{-1, 0, 0}, {1, 0, 0}}, .04]}},
  PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}},
  ImageSize -> Medium]

graphics

Update

This update is added to address a question asked by the OP in a comment to this question.

No, you can't use an InfiniteLine as the spine of a tube. However, it not too hard to roll your own version (pun intended) of Tube that I think will mimic an infinite tube well enough for your purposes.

Here is a sketch of how it might be done. For industrial use. the function, at minimum, would need to be rewritten with guards placed on its arguments.

directedLongTube[p_, v_, r_, k_: 100.] := Tube[{(p - k v), (p + k v)}, r]

where

$\qquad p\quad$point the tube is centered on
$\qquad v\quad$direction vector of the tube
$\qquad r\quad$radius of the tube
$\qquad k\quad$extension factor of the tube

$k$ should be large enough so the tube will extend outside the bounding box of the plot in both directions.

Example

SeedRandom[1]
With[
    {center = RandomReal[2 {-1., 1.}, 3],
     directions = RandomReal[{-1., 1.}, {10, 3}],
     colors = Hue /@ Subdivide[9]},
  Module[{tubes},
    tubes =
      MapThread[{#1, directedLongTube[center, #2, .25]} &, {colors, directions}];
    Graphics3D[{{Gray, Sphere[{center}, 1]}, tubes}, 
      PlotRange -> 5 {{-1, 1}, {-1, 1}, {-1, 1}},
      Boxed -> False]]]

graphics

$\endgroup$
  • $\begingroup$ Is there a way to use tubes in InfiniteLine? Something with :> perhaps $\endgroup$ – Kai Sep 3 at 3:38
  • $\begingroup$ @Kai. I updated my answer to address the issue you raise in your comment. $\endgroup$ – m_goldberg Sep 3 at 18:32
1
$\begingroup$

The problem appears to be the Thickness directive. According to the documentation, it says, "is a graphics directive which specifies that lines which follow are to be drawn with thickness r. The thickness r is given as a fraction of the horizontal plot range."

I used "AbsoluteThickness" and it seems to do what you want. So try

g2 = Graphics3D[{Directive[Red, AbsoluteThickness[0.02]], InfiniteLine[{0, 0, 0}, {1,0, 0}]}];Show[{g1, g2}, PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}, Boxed -> False, ImageSize -> Large]
$\endgroup$
  • $\begingroup$ Thanks, this didn't fix it for me in my situation unfortunately, I still get clipping in my application. But AbsoluteThickness is still quite useful $\endgroup$ – Kai Aug 31 at 1:19
  • $\begingroup$ Sorry it didn't work for you. I do note that in 12.0, the AbsoluteThickness directive doesn't seem to be doing anything so it was a false hope. I like the tube idea from @m_goldberg $\endgroup$ – Mark R Aug 31 at 2:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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