5

I saw this answer How to draw this arc (intersection of a plane and a sphere) automatically? and tried to draw this sphere. But, I can't obtain the correct result. How can I get the correct result?

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{tikz-3dplot}
\usepackage{fouriernc}
\usetikzlibrary{intersections,calc,backgrounds} 
\makeatletter
% retrieves the 3D coordinates
\def\RawCoord(#1){\csname tikz@dcl@coord@#1\endcsname}%
\def\scalprod#1=#2.#3;{%
\edef\coordA{\RawCoord#2}%
\edef\coordB{\RawCoord#3}%
\pgfmathsetmacro\pgfutil@tmpa{scalarproduct({\coordA},{\coordB})}
\edef#1{\pgfutil@tmpa}}%
\makeatother 
\newcommand{\spaux}[6]{(#1)*(#4)+(#2)*(#5)+(#3)*(#6)}  
\pgfmathdeclarefunction{scalarproduct}{2}{% scalar product of two 3-vectors
  \begingroup%
  \pgfmathparse{\spaux#1#2}%
  \pgfmathsmuggle\pgfmathresult\endgroup}  
\tikzset{reverseclip/.style={insert path={(current bounding box.south west) -- (current bounding box.north west) -- (current bounding box.north east) --(current bounding box.south east) -- cycle} }} 
\begin{document}
\tdplotsetmaincoords{70}{50}
    \begin{tikzpicture}[scale=1,tdplot_main_coords,declare function={R=5*sqrt(7)*(1/3);r=5*sqrt(3)*(1/3);
        alpha1(\th,\ph,\b)=\ph+asin(cot(\th)*tan(\b));%
        alpha2(\th,\ph,\b)=-180+\ph-asin(cot(\th)*tan(\b));%
        beta1(\th,\ph,\a)=90+atan(cot(\th)/sin(\a-\ph));%
        beta2(\th,\ph,\a)=270+atan(cot(\th)/sin(\a-\ph));%
    }]
    \path  
       (5/2, {5* sqrt(3)/6}, 0) coordinate (O)
      (0,0, 0) coordinate (A) 
      (5, 0, 0) coordinate (B) 
      (5/2, {5* sqrt(3)/2}, 0) coordinate (C) 
      (32/5,0, 24/5)  coordinate (S) 
     (5/2, 0, 10/3) coordinate (I)
      (5/2, {5* sqrt(3)/6}, 10/3) coordinate (T)
        ($ (A)!0.5!(B) $) coordinate (M)
        (0,0,1) coordinate(Z);
    \begin{scope}[tdplot_screen_coords, on background layer]
    \draw[thick,name path global=ball] (T) circle (R);
    \end{scope}

    \begin{scope}[canvas is xy plane at z={0}]
    \draw[dashed,cyan] (O) circle (r);
    \scalprod\myz=(T).(Z); % z component of T
    \pgfmathsetmacro{\myel}{atan(-1*\myz/r)}
    \draw[thick] ({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) 
    arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}: 
    {alpha2(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) ;
    \end{scope}

    \begin{scope}[canvas is xz plane at y={0}]
     \draw[dashed,red,name path=c1] (I) circle (25/6);
    \clip[name intersections={of=c1 and ball,total=\t}] 

    let \p1=($(intersection-1)-(I)$),\n1={atan2(\y1,\x1)+180},\n2={2*veclen(\y1,\x1)} in 
    (intersection-1) -- ++ (\n1:\n2) -- (current bounding box.north west) 
    -- (current bounding box.south west) -- cycle; 
     \draw[thick] (I) circle (25/6); 
    \end{scope} 

    \begin{scope}[on background layer]
        \foreach \v/\position in {T/above,O/below,A/below,B/below,C/below,S/right,I/above,M/below} {
        \draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
    }
    \end{scope}
    \foreach \X in {A,B,C} \draw[dashed] (\X) -- (S); 
    \draw[dashed] (A) -- (B) -- (C) -- cycle
    (T) -- (I) -- (M) -- (O) -- cycle
    ;
     \end{tikzpicture}
\end{document}

enter image description here

9
  • 1
    Could you please explain a bit what you want to achieve, and where you are struggling. The center of the sphere, T, and O, which often denotes the origin, have nontrivial x and y components. Why? What is the purpose of these conventions? (The first arc works as expected if you use \draw[thick] ($(O)+({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r)$) arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}: {alpha2(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) ;, i.e. shift its center appropriately.)
    – user194703
    Sep 4, 2019 at 3:03
  • 1
    @Thuy Nguyen You can make vector (-5/2, {-5* sqrt(3)/6}, 0) coordinate (V) to get O at origin. E.g. ($ (5/2, {5* sqrt(3)/6}, 0) + (V) $) coordinate (O) Similarly to every points. Sep 4, 2019 at 3:11
  • @Schrödinger'scat I want to correct dashed (thick) line of red and blue circle. I tried wiht your coment, and it is correct. Sep 4, 2019 at 3:16
  • Yes, but I do not understand how you get the location of I and why the radius of the red dashed circle is 25/6, which is greater than r=5/sqrt(3). This seems to be part of a larger sphere. If you want to draw a visible arc, it should be the visible arc on that sphere. Clearly I am missing something basic.
    – user194703
    Sep 4, 2019 at 3:26
  • @Schrödinger'scat Perhaps this is also a good case when the center of the circle (sphere) does not coincide with the origin. Sep 4, 2019 at 3:27

1 Answer 1

7

This is some attempt to answer your question following the strategy you devised. As for the first arc, everything works, you only forgot to shift the center of the arc to the center of the circle, (O). The second scope also works as you intended to do except that one needs to be somewhat careful since the clip path is subject to the transformations from canvas is xz plane at y=.... I used here the y coordinate of (I), but this is not really important since this is only a shift. I also followed minthien_2016's suggestion to shift (O) back to the origin. This is not crucial here but if you ever intend to produce animations, this is advantageous. In principle the second arc can be obtained analytically, too, but I did not attempt to do this here.

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{tikz-3dplot}
\usepackage{fouriernc}
\usetikzlibrary{intersections,backgrounds} % calc gets loaded by tikz-3dplot
\makeatletter
% retrieves the 3D coordinates
\def\RawCoord(#1){\csname tikz@dcl@coord@#1\endcsname}%
\def\scalprod#1=#2.#3;{%
\edef\coordA{\RawCoord#2}%
\edef\coordB{\RawCoord#3}%
\pgfmathsetmacro\pgfutil@tmpa{scalarproduct({\coordA},{\coordB})}
\edef#1{\pgfutil@tmpa}}%
\makeatother 
\newcommand{\spaux}[6]{(#1)*(#4)+(#2)*(#5)+(#3)*(#6)}  
\pgfmathdeclarefunction{scalarproduct}{2}{% scalar product of two 3-vectors
  \begingroup%
  \pgfmathparse{\spaux#1#2}%
  \pgfmathsmuggle\pgfmathresult\endgroup}  
\begin{document}
\tdplotsetmaincoords{70}{50}
\begin{tikzpicture}[scale=1,tdplot_main_coords,
declare function={R=5*sqrt(7)*(1/3);r=5*sqrt(3)*(1/3);
      alpha1(\th,\ph,\b)=\ph+asin(cot(\th)*tan(\b));%
      alpha2(\th,\ph,\b)=-180+\ph-asin(cot(\th)*tan(\b));%
      beta1(\th,\ph,\a)=90+atan(cot(\th)/sin(\a-\ph));%
      beta2(\th,\ph,\a)=270+atan(cot(\th)/sin(\a-\ph));%
  }]
  %\path[tdplot_screen_coords,use as bounding box] (-2*R,-0.6*R) rectangle (2*R,2.1*R);
  \path  % I shifted O to the origin
     (0, 0, 0) coordinate (O)
    (-5/2,{-5* sqrt(3)/6}, 0) coordinate (A) 
    (5/2, {-5* sqrt(3)/6}, 0) coordinate (B) 
    (0, {5* sqrt(3)/3}, 0) coordinate (C) 
    (32/5-5/2,{-5* sqrt(3)/6}, 24/5)  coordinate (S) 
   (0, {-5* sqrt(3)/6}, 10/3) coordinate (I)
    (0, 0, 10/3) coordinate (T)
      ($ (A)!0.5!(B) $) coordinate (M)
      (0,1,0) coordinate(Y)
      (0,0,1) coordinate(Z);
  \begin{scope}[tdplot_screen_coords, on background layer]
   \draw[thick,name path global=ball] (T) circle (R);
  \end{scope}
  \scalprod\myz=(T).(Z); % z component of T
  \begin{scope}[canvas is xy plane at z={0}]
  \draw[dashed,cyan] (O) circle (r);
  \pgfmathsetmacro{\myel}{atan(-1*\myz/r)}
  \draw[thick] ($(O)+({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r)$)
  arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}: 
  {alpha2(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) ;
  \end{scope}
  \scalprod\myy=(I).(Y); % y component of I
  \begin{scope}[canvas is xz plane at y={\myy}]
   \draw[dashed,red,name path=c1] (I) circle[radius=25/6];
   \clip[name intersections={of=c1 and ball,total=\t},overlay]
   %\pgfextra{\message{\t\space intersections found.^^J}}
    (intersection-1) -- (intersection-1|-current bounding box.north)
    -- (current bounding box.north east)
    -- (current bounding box.south east)
    -- (intersection-\t|-current bounding box.south west)  
    -- (intersection-\t) -- cycle;
   \draw[thick] (I) circle[radius=25/6];    
  \end{scope} 

  \begin{scope}[on background layer]
      \foreach \v/\position in {T/above,O/below,A/below,B/below,C/below,S/right,I/above,M/below} {
      \draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
  }
  \end{scope}
  \foreach \X in {A,B,C} \draw[dashed] (\X) -- (S); 
  \draw[dashed] (A) -- (B) -- (C) -- cycle
  (T) -- (I) -- (M) -- (O) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

3
  • When I change \tdplotsetmaincoords{70}{50} into \tdplotsetmaincoords{70}{120}, the dased line of red circle incorrect. How can I fix it in every cases? Sep 4, 2019 at 7:51
  • @minhthien_2016 To fix it in every case, one would need the analytical formula (or at least distinguish cases). Whenever we are using intersections, there are some issues.
    – user194703
    Sep 4, 2019 at 14:19
  • Thank you for your Comment. Sep 4, 2019 at 14:28

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.