13

First consider the following example for illustration purposes. The objective is to draw the shortest line segment from the point H to the plane BDE. The prism ABCD.EFGH has AB=AD=5\sqrt{2} and AE=12. I think that these numbers are badly selected by the author.

The following is my attempt to draw it with pst-3dplot (with premature 3D support) and pst-eucl (designed only fo 2D). The process is tedious because many tasks such as

  • defining a new 3D colinear point from 2 existing 3D points with a certain scaling factor,
  • projecting an existing 3D point onto a line joining two existing 3D points,
  • marking right angle with a slanted perpendicular symbol,

are performed with manual calculation beforehand. Among others, \pstProjection and \pstRightAngle from pst-eucl do not work in 3D.

Here it is the painful parts that I did. Look at the magic exact numbers.

\pstHomO[HomCoef=\pscalculate{50/194},PosAngle=-80]{E}{D}[P]
\pstHomO[HomCoef=\pscalculate{25/72},PosAngle=135]{E}{B}[Q]
\pstHomO[HomCoef=\pscalculate{9409/4225},PosAngle=0]{Q}{P}[H']

Other operations such as

  • projecting an existing 3D point onto a plane passing through 3 existing 3D points,
  • finding the intersecting point between two lines, each passing through 2 distinct points,
  • etc

are also required in the future projects.

Question

Here I want to know which LaTeX packages really support 3D drawing operation above with ease. Redrawing what I did below to prove the effectiveness of package you propose is required. I don't know much about Asymptote, TikZ, Metapost, and others.

My painful attempt

enter image description here

\documentclass[pstricks,border=0cm,12pt]{standalone}
\usepackage{pst-3dplot,pst-eucl}

\psset{unit=5mm}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% OBJECTIVE
% Draw the shortest line segment 
% from the point H to 
% the plane BDE .
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



\def\pstSlantedRightAngle#1#2#3{%
  \pnodes([nodesep=6pt]{#1}#2){s}([nodesep=6pt]{#3}#2){t}
  \pstTranslation[PointName=none,PointSymbol=none]{#2}{s}{t}[u]
  \psline(s)(u)(t)}
        
\begin{document}
\begin{pspicture}[showgrid=false](-8,-1)(6,15)
    \psset{Alpha=-115,Beta=55}
    
    
    % prism ABCD.EFGH
    \def\A{(5 2 sqrt mul,0,0)}
    \def\B{(5 2 sqrt mul,5 2 sqrt mul,0)}
    \def\C{(0,5 2 sqrt mul,0)}
    \def\D{(0,0,0)}
    \def\E{(5 2 sqrt mul,0,12)}
    \def\F{(5 2 sqrt mul,5 2 sqrt mul,12)}
    \def\G{(0,5 2 sqrt mul,12)}
    \def\H{(0,0,12)}
    
    % hidden lines do not work!
    %\edef\coor{\D\A\C\H}
    %\expandafter\pstThreeDBox\coor
  
    
    \foreach \i in {A,B,...,H}{%
        \edef\coor{\csname\i\endcsname}
        \expandafter\pstThreeDDot\coor
        \expandafter\pstThreeDNode\coor{\i}
    } 
    
    \foreach \i/\j in {0/A,180/B,-135/C,-45/D,45/E,180/F,180/G,115/H}{\uput[\i](\j){$\j$}}
    \pspolygon(C)(D)(A)(E)(F)(G)
    \psline(H)(E)
    \psline(H)(G)
    \psline(H)(D)
    
    \psline[linestyle=dashed](B)(F)
    \psline[linestyle=dashed](B)(C)
    \psline[linestyle=dashed](B)(A)
    
    
    
    % plane EDB
    \pspolygon[fillstyle=solid,fillcolor=yellow,opacity=0.25,linestyle=none,linewidth=0](E)(B)(D)
    \psline[linestyle=dashed,linecolor=red](E)(B)(D)
    \psline[linecolor=red](E)(D)
    
    % the shortest distance from H to EDB
    \pstHomO[HomCoef=\pscalculate{50/194},PosAngle=-80]{E}{D}[P]
    \pstHomO[HomCoef=\pscalculate{25/72},PosAngle=135]{E}{B}[Q]
    \pstHomO[HomCoef=\pscalculate{9409/4225},PosAngle=0]{Q}{P}[H']
    
    \psline[linestyle=dashed,linecolor=green](H)(Q)(P)
    \pspolygon[linecolor=green](P)(H')(H)
    

  % right-angle mark
    \pstSlantedRightAngle{H}{P}{D}
    \pstSlantedRightAngle{E}{P}{Q}
    \pstSlantedRightAngle{H}{H'}{P}
    \pstSlantedRightAngle{H}{E}{Q}  
\end{pspicture}
\end{document}

Behind the scene calculation

enter image description here

enter image description here

enter image description here

enter image description here

I love Euclidean geometry!

enter image description here

In some cases, the hidden lines are wrongly rendered!

15
  • 3
    I don't know much about Asymptote, TikZ, Metapost, and others. Hmm, you can refresh your brain and start with one of them! :-) – user213378 Jun 17 '20 at 12:19
  • I use Maple to find. The distance from the point H to the plane (DBE) is 60/13. – minhthien_2016 Feb 13 at 15:12
  • I use Tikz. If a = 5*sqrt(2) and h = 12, then projection of the point H on the plane (DBE) is ({a*h*h/(a*a+2*h*h)}, {-a*h*h/(a*a+2*h*h)}, {2*h*h*h/(a*a+2*h*h)}) – minhthien_2016 Feb 13 at 15:44
  • 1
    @BlackMild: So the auto-hidden lines in this simple cube problem can easily be solved with P=currenprojection? If yes, I will invest my time to master asymptote. :-) – Kim Jong Un Feb 22 at 3:24
  • 1
    @MoneyOrientedProgrammer In my plain opinion, the choice of drawing tool depends on our needs. If you are interested in a broad scope including higher maths, physics, chemistry,... at univesity/college level, Asymptote (3D) is non-avoidable choice. If you care about drawing only in high school level, TikZ (internally 2D) is enough. If your favourite is just auto-dashed curves, go with it (but soon you will realise it is overcomplicated and less meaningful, mathematically). – Black Mild Feb 22 at 4:19
6
+150

This is not a complete solution. I have not yet to make the hidden dashed lines are automatically adjusted whenever you rotate the cube with the segment HY. Note that, the distance from the point H to the plane BDE is sqrt{a^2h^2}{a^2+h^2}, where a = AB, h=AE. Many thanks to marmot with 3dtools

    \documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools} % https://github.com/marmotghost/tikz-3dtools
\begin{document}
    \pgfdeclarelayer{background} 
    \pgfdeclarelayer{foreground}
        \pgfsetlayers{background,main,foreground} 
\foreach \Angle in {5,15,...,355} % {5,15,...,355}
    {\begin{tikzpicture}[same bounding box=A,line cap=round,line join=round,declare function={a=5*sqrt(2);h=12;} ]
    \begin{scope}[3d/install view={phi=\Angle,psi=0,theta=70}]
\path
  (a,0,0) coordinate (A)
 (a,a,0) coordinate (B)
 (0,a,0) coordinate (C)
 (0,0,0) coordinate (D)
 (a,0,h) coordinate (E)
 (a,a,h) coordinate (F)
 (0,a,h) coordinate (G)
 (0,0,h)  coordinate (H)
 ({a*h*h/(a*a+2*h*h)}, {-a*h*h/(a*a+2*h*h)}, {2*h*h*h/(a*a+2*h*h)}) coordinate (Y) %using Maple
[3d coordinate={(O)=0.5*(A)+0.5*(G)}];
\foreach \p in {A,B,C,D,E,F,G,H,Y,O}
{\draw[fill=black] (\p) circle (1.2 pt);}
\foreach \p/\g in {A/-90,B/-90,C/-90,D/90,E/90,F/90,G/90,H/90,Y/90,O/-90}
{\path (\p)+(\g:3mm) node{$\p$};}
\tikzset{3d/polyhedron/.cd,fore layer=foreground,back layer=background,
    face edges/.style={},%
    back/.style={3d/hidden,fill=none},
    fore/.style={3d/visible,solid,fill=none,3d/polyhedron/edges have complete dashes=false},
    complete dashes,
    O={(O)},
    draw face with corners={{(A)},{(B)},{(E)}},
    draw face with corners={{(B)},{(E)},{(F)}},
    draw face with corners={{(B)},{(C)},{(G)},{(F)}},
    draw face with corners={{(D)},{(C)},{(G)},{(H)}},
    draw face with corners={{(H)},{(E)},{(D)}},
    draw face with corners={{(A)},{(D)},{(E)}},
    draw face with corners={{(E)},{(F)},{(G)},{(H)}}}
\draw[3d/hidden] (B) --(D);
\draw[3d/visible] (H) -- (Y);
\end{scope}
\end{tikzpicture}}
\end{document}

You can use 3dtools to find projection of the point H on the plane BDE with syntax

\path[3d/plane through={(E) and (D) and (B) named pEDB}];
\path[3d/project={(H) on pEDB}] coordinate (X);

In this code, I reduce length of AH to AH=5.

   \documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools} % https://github.com/marmotghost/tikz-3dtools
\begin{document}
    \pgfdeclarelayer{background} 
    \pgfdeclarelayer{foreground}
        \pgfsetlayers{background,main,foreground} 
\foreach \Angle in {70} % {5,15,...,355}
    {\begin{tikzpicture}[same bounding box=A,line cap=round,line join=round,declare function={a=5*sqrt(2);h=5;} ]
    \begin{scope}[3d/install view={phi=\Angle,psi=0,theta=70}]
\path
  (a,0,0) coordinate (A)
 (a,a,0) coordinate (B)
 (0,a,0) coordinate (C)
 (0,0,0) coordinate (D)
 (a,0,h) coordinate (E)
 (a,a,h) coordinate (F)
 (0,a,h) coordinate (G)
 (0,0,h)  coordinate (H)
 ({a*h*h/(a*a+2*h*h)}, {-a*h*h/(a*a+2*h*h)}, {2*h*h*h/(a*a+2*h*h)}) coordinate (Y) %using Maple
[3d coordinate={(O)=0.5*(A)+0.5*(G)}];
\path[3d/plane through={(E) and (D) and (B) named pEDB}];
\path[3d/project={(H) on pEDB}] coordinate (X);
\foreach \p in {A,B,C,D,E,F,G,H,Y,O,X}
{\draw[fill=black] (\p) circle (1.2 pt);}
\foreach \p/\g in {A/-90,B/-90,C/-90,D/90,E/90,F/90,G/90,H/90,Y/90,O/-90,X/0}
{\path (\p)+(\g:3mm) node{$\p$};}
\tikzset{3d/polyhedron/.cd,fore layer=foreground,back layer=background,
    face edges/.style={},%
    back/.style={3d/hidden,fill=none},
    fore/.style={3d/visible,solid,fill=none,3d/polyhedron/edges have complete dashes=false},
    complete dashes,
    O={(O)},
    draw face with corners={{(A)},{(B)},{(E)}},
    draw face with corners={{(B)},{(E)},{(F)}},
    draw face with corners={{(B)},{(C)},{(G)},{(F)}},
    draw face with corners={{(D)},{(C)},{(G)},{(H)}},
    draw face with corners={{(H)},{(E)},{(D)}},
    draw face with corners={{(A)},{(D)},{(E)}},
    draw face with corners={{(E)},{(F)},{(G)},{(H)}}}
\draw[3d/hidden] (B) --(D);
\draw[3d/visible] (H) -- (Y);
\end{scope}
\end{tikzpicture}}
\end{document}

And Here is a slightly different solution. from marmot

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\begin{document}
    \pgfdeclarelayer{background} 
    \pgfdeclarelayer{foreground}
    \pgfsetlayers{background,main,foreground} 
    \foreach \Angle in {5,15,...,355}
    {\begin{tikzpicture}[same bounding box=A,line cap=round,line join=round,visible/.style={draw,solid}, hidden/.style={draw, dashed}, 3d/install view={phi=\Angle,psi=0,theta=70},declare function={a=5*sqrt(2);h=10;} ]
            \path
            (a/2,-a/2,0) coordinate (A)
            (a/2,a/2,0) coordinate (B)
            (-a/2,a/2,0) coordinate (C)
            (-a/2,-a/2,0) coordinate (D)
            (a/2,-a/2,h) coordinate (E)
            (a/2,a/2,h) coordinate (F)
            (-a/2,a/2,h) coordinate (G)
            (-a/2,-a/2,h)  coordinate (H)
            [3d coordinate={(O)=0.33*(B)+0.33*(D)+0.33*(E)+0.1*a*(nscreenx,nscreeny,nscreenz)}];
            [3d coordinate={(O)=0.5*(A)+0.5*(G)}];
            \path[3d/plane through={(E) and (D) and (B) named pEDB}];
            \path[3d/project={(H) on pEDB}] coordinate (X);
            \foreach \p in {A,B,C,D,E,F,G,H,O,X}
            {\draw[fill=black] (\p) circle (1.2 pt);}
            \foreach \p/\g in {A/-90,B/-90,C/-90,D/90,E/90,F/90,G/90,H/90,O/-90,X/0}
            {\path (\p)+(\g:3mm) node{$\p$};}
            \tikzset{3d/polyhedron/.cd,O={(O)},
                fore layer=foreground,back layer=background,
                back/.style={3d/polyhedron/complete dashes,fill=none},
                fore/.style={3d/visible,fill=none},%3d/polyhedron/edges have complete dashes=false
                draw face with corners={{(A)},{(B)},{(E)}},
                draw face with corners={{(B)},{(E)},{(F)}},
                draw face with corners={{(B)},{(C)},{(G)},{(F)}},
                draw face with corners={{(D)},{(C)},{(G)},{(H)}},
                draw face with corners={{(H)},{(E)},{(D)}},
                draw face with corners={{(A)},{(D)},{(E)}},
                draw face with corners={{(E)},{(F)},{(G)},{(H)}}
            }
            \draw[hidden] (B) -- (D);
            \draw[visible] (H) -- (X);
    \end{tikzpicture}}
\end{document}  

enter image description here

enter image description here

enter image description here

4
\documentclass[pstricks,border=0cm,12pt]{standalone}
\usepackage{pst-3dplot,pst-calculate}
\psset{unit=5mm}
\begin{document}

\def\X{5 2 sqrt mul}
\psset{Beta=40,Alpha=65}

\begin{pspicture}[showgrid](-5,-8)(8,10)
\pstThreeDCoor
\pstThreeDBox[hiddenLine](0,0,0)(\X,0,0)(0,\X,0)(0,0,12)
\pstThreeDTriangle[fillcolor=yellow,fillstyle=solid,opacity=0.5,linecolor=red,
    linestyle=dashed](\X,\X,0)(0,\X,12)(0,0,0)
\pstThreeDLine[linecolor=red](\X,\X,0)(0,\X,12)
\pstThreeDNode(0,\X,12){E}\uput[0](E){E}
\pstThreeDNode(\X,\X,12){H}\pstThreeDNode(\X,\X,0){D}\uput[0](D){D}
\psRelNode(E)(0,0){2425 36 div 194 div}{Q}\psdot(Q)
\psRelNode(D)(E){144 194 div}{P}\psdot(P)\uput[0](P){P}
\psline[linestyle=dashed,linecolor=green](H)(Q)(P)
\psline[linecolor=green](H)(P)
\psRelNode(Q)(P){2}{H'}\psdot(H')\psline[linecolor=green](P)(H')(H)
\end{pspicture}
\end{document}

enter image description here

3
  • 1
    no magic! Only for this test. You have to calculate it for the correct image. – user187802 Jun 17 '20 at 13:00
  • By the way, the hiddenLine option sometimes does not work as expected. For certain Alpha, the dashed lines are wrongly on the front parts rather than on the rear parts. – Kim Jong Un Jun 17 '20 at 13:28
  • 1
    Works only if the view is from x>0, y>0 – user187802 Jun 17 '20 at 13:30

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.