4
$\begingroup$

How to get the axis of the cylinder oriented along the red line shown in the figure below ?

Here is my code :

Show[ContourPlot3D[{y^2 + z^2 == 10}, {x, -20, 20}, {y, -10, 10}, {z, -10, 10}, Mesh -> None, PlotRange -> Full], 
 Graphics3D[{Thick, Red, InfiniteLine[{{-20, -10, 0}, {20, 10, 0}}]}, 
  BoxRatios -> {1, 1, 1}]]

enter image description here

Thank you in advance.

$\endgroup$
8
  • 1
    $\begingroup$ By rotating it? $\endgroup$ Commented May 27 at 19:05
  • $\begingroup$ Try: Graphics3D[ GeometricTransformation[ Cylinder[{{-20, 0, 0}, {20, 0, 0}}, Sqrt[10]], RotationTransform[Pi/4, {0, 0, 1}]]] $\endgroup$ Commented May 27 at 20:07
  • 1
    $\begingroup$ Can't it be done in ContourPlot3D, without using Cylinder ? $\endgroup$
    – user444
    Commented May 27 at 20:55
  • $\begingroup$ The surface (x-2y)^2/9 + z^2 == 10 looks about right. $\endgroup$
    – LouisB
    Commented May 28 at 2:14
  • $\begingroup$ @LouisB Should be (x - 2 y)^2/5 + z^2 == 10 since we need to use rotationmatrix {{-(2/Sqrt[5]), 1/Sqrt[5], 0}, {-(1/Sqrt[5]), -(2/Sqrt[5]), 0}, {0, 0, 1}}. $\endgroup$
    – cvgmt
    Commented May 28 at 2:40

3 Answers 3

6
$\begingroup$

Given the cylinder( y^2 + z^2 == 10 ) we can find its axis as

axis = InfiniteLine[{{0, 0, 0}, {1, 0, 0}}];

Red line

line = InfiniteLine[{{-20, -10, 0}, {20, 10, 0}}];

The two lines are lying in the same plane(xy), therefore a rotation in xy plane would suffice in order to align the cylinder's axis with the red line.

Calculating the angle between the axis and the line:

axisVector = First@*Differences @@ axis; (* {1, 0, 0} *)
lineVector = First@*Differences @@ line; (* {40, 20, 0} *)

angle = VectorAngle[axisVector, lineVector] (* ArcCos[2/Sqrt[5]] *)

Plotting:

plot = ContourPlot3D[{y^2 + z^2 == 10}, {x, -20, 20}, {y, -10, 10}, {z, -10, 10}
        , Mesh -> None, PlotRange -> Full];

Graphics3D[{Opacity[.3], First@plot
  , GeometricTransformation[First@plot, RotationTransform[ArcCos[2/Sqrt[5]], {0, 0, 1}]]
  , Opacity[.7], Thick, Blue, axis, Thick, Red, line}, Axes -> True, AxesLabel -> {x, y, z}]

enter image description here

$\endgroup$
7
$\begingroup$

Besides of rotate the original contourplot3d, we also have aother ways to get the desired results.

Method-1

  • We set the DisplayFunction to be
ReplaceAll[{x_Real, y_Real, z_Real} :> 
  RotationTransform[{{1, 0, 0}, dir}, center]@{x, y, z}]

to rotate the original contourplot3d.

Clear["Global`*"];
dir = {-20, -10, 0} - {20, 10, 0};
{cylinder1, cylinder2} = 
  ContourPlot3D[{y^2 + z^2 == 10}, {x, -20, 20}, {y, -10, 
      10}, {z, -10, 10}, Mesh -> None, PlotRange -> All, 
     DisplayFunction -> #] & /@ {Identity, 
    ReplaceAll[{x_Real, y_Real, z_Real} :> 
      RotationMatrix[{{1, 0, 0}, dir}] . {x, y, z}]};
Show[cylinder1, cylinder2, BoxRatios -> Automatic]

enter image description here

Method-2

  • Using the RegionDistance respect to the InfiniteLine[{{-20, -10, 0}, {20, 10, 0}}] to define a new ContourPlot3D.

Clear["Global`*"];
line = InfiniteLine[{{-20, -10, 0}, {20, 10, 0}}];
dir = {-20, -10, 0} - {20, 10, 0};
center = {0, 0, 0};
dist = RegionDistance[line];
cylinder1 = 
  ContourPlot3D[{y^2 + z^2 == 10}, {x, -20, 20}, {y, -10, 
    10}, {z, -10, 10}, Mesh -> None, PlotRange -> All];
cylinder2 = 
  ContourPlot3D[
   dist@{x, y, z} == Sqrt[10], {x, y, z} ∈ 
    RotationTransform[{{1, 0, 0}, dir}, center]@
     Cuboid[{-20, -10, -10}, {20, 10, 10}], 
   RegionBoundaryStyle -> None, Mesh -> None];
Show[cylinder1, cylinder2, PlotRange -> All, BoxRatios -> Automatic]

enter image description here

Method-3

  • We define a cylinder with center,direction,radius and length.
cylinder[center_, dir_, radius_, length_] := 
 Module[{bases}, 
  bases = Select[
    Orthogonalize@Normal@HodgeDual[dir], # =!= {0, 0, 0} &];
  ParametricPlot3D[
   center + radius {Cos[t], Sin[t]} . bases + s*Normalize[dir], {t, 0,
     2  π}, {s, -length/2, length/2}, Mesh -> None, 
   PlotPoints -> 80, MaxRecursion -> 4, BoxRatios -> Automatic, 
   PlotRange -> All]]

Show[cylinder[{0, 0, 0}, {1, 0, 0}, Sqrt[10], 40], 
 cylinder[{0, 0, 0}, {-20, -10, 0} - {20, 10, 0}, Sqrt[10], 40], 
 cylinder[{10, 20, 30}, {1, 1, 1}, Sqrt[10], 40], 
 BoxRatios -> Automatic, PlotRange -> All]

enter image description here

$\endgroup$
3
$\begingroup$

Use the equation for the distance between a line and a point in 3D space:

x1 = {-20, -10, 0};
x2 = {20, 10, 0};
x0 = {x, y, z};
d = Sqrt[10];
neweqn = Simplify[Norm[Cross[x0 - x1, x0 - x2]]^2 - d^2 Norm[x2 - x1]^2, 
    Assumptions -> Element[x | y | z, Reals]]

(* 400 (-50 + x^2 - 4 x y + 4 y^2 + 5 z^2) *)

Show[ContourPlot3D[{y^2 + z^2 == 10, neweqn == 0}, {x, -20, 20}, {y, -10, 10}, {z, -10, 10}, Mesh -> None, PlotRange -> Full], 
 Graphics3D[{Thick, Red, InfiniteLine[{{-20, -10, 0}, {20, 10, 0}}]}, 
  BoxRatios -> {1, 1, 1}]]

enter image description here

Explanation: the quantity neweqn is equal to $$[(\vec{x}_0 - \vec{x}_1) \times (\vec{x}_0 - \vec{x}_2)]^2 - d^2 (\vec{x}_1 - \vec{x}_2)^2.$$ According to the derivation given in the link above, all points with a distance of $d = \sqrt{10}$ from the given line will satisfy the equation neweqn == 0; so this equation defines a 3D cylinder with the same radius centered on this new axis.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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