# How to change the axis orientation of the cylinder in ContourPlot3D?

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}]]


• By rotating it? Commented May 27 at 19:05
• Try: Graphics3D[ GeometricTransformation[ Cylinder[{{-20, 0, 0}, {20, 0, 0}}, Sqrt[10]], RotationTransform[Pi/4, {0, 0, 1}]]] Commented May 27 at 20:07
• Can't it be done in ContourPlot3D, without using Cylinder ? Commented May 27 at 20:55
• The surface (x-2y)^2/9 + z^2 == 10 looks about right. Commented May 28 at 2:14
• @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}}. Commented May 28 at 2:40

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}]


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]


## 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]


## 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]


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}]]


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.