3

Credit: https://tex.stackexchange.com/a/727949/319072

Is there a way to automate the drawing of angles in 3d perspective? The angles library just draws them on the screen plane. I can do it manually, but the process is extremely time consuming.

\documentclass[tikz, border=1cm]{standalone} \usepackage{tikz-3dplot} \usetikzlibrary{calc,angles} \begin{document} \tdplotsetmaincoords{60}{130} \begin{tikzpicture}[tdplot_main_coords] \pgfmathsetmacro\pa{2} \pgfmathsetmacro\pb{2} \pgfmathsetmacro\pc{1} \pgfmathsetmacro\qa{-1} \pgfmathsetmacro\qb{2} \pgfmathsetmacro\qc{2} \pgfmathsetmacro\ra{1} \pgfmathsetmacro\rb{-1} \pgfmathsetmacro\rc{2} \pgfmathsetmacro\qpa{\pa-\qa} \pgfmathsetmacro\qpb{\pb-\qb} \pgfmathsetmacro\qpc{\pc-\qc} \pgfmathsetmacro\qpl{sqrt((\qpa)^2 + (\qpb)^2 + (\qpc)^2)} \pgfmathsetmacro\qpa{\qpa/\qpl} \pgfmathsetmacro\qpb{\qpb/\qpl} \pgfmathsetmacro\qpc{\qpc/\qpl} \pgfmathsetmacro\qra{\ra-\qa} \pgfmathsetmacro\qrb{\rb-\qb} \pgfmathsetmacro\qrc{\rc-\qc} \pgfmathsetmacro\qrl{sqrt((\qra)^2 + (\qrb)^2 + (\qrc)^2)} \pgfmathsetmacro\qra{\qra/\qrl} \pgfmathsetmacro\qrb{\qrb/\qrl} \pgfmathsetmacro\qrc{\qrc/\qrl} \tdplotcrossprod(\qpa,\qpb,\qpc)(\qra,\qrb,\qrc) \pgfmathsetmacro\za{\tdplotresx} \pgfmathsetmacro\zb{\tdplotresy} \pgfmathsetmacro\zc{\tdplotresz} \coordinate (P) at (\pa,\pb,\pc); \coordinate (Q) at (\qa,\qb,\qc); \coordinate (R) at (\ra,\rb,\rc); \coordinate (QP) at (\qpa,\qpb,\qpc); \coordinate (QR) at (\qra,\qrb,\qrc); \coordinate (Z) at (\za,\zb,\zc); \draw[<->] (P) -- (Q) -- (R); \begin{scope}[ x={(QP)}, y={(QR)}, z={(Z)}, canvas is xy plane at z=0 ] \draw[red] ($(Q) + (QP)$) arc[start angle=0, end angle=90, radius=1]; \draw pic[draw,blue,-, angle radius=1cm,]{angle=R--Q--P}; \end{scope} \end{tikzpicture} \end{document} 

output

1
  • Use transform shape as in \draw pic[draw, blue, angle radius=1cm, transform shape] {angle=P--Q--R};. Commented Nov 1, 2024 at 19:37

3 Answers 3

5

This code was written by the author of the luadraw. I would like to thank the author for allowing me to share it.

\documentclass[12pt]{standalone}% compile with lualatex only \usepackage[svgnames]{xcolor} \usepackage{fouriernc} \usepackage[3d]{luadraw}%https://github.com/pfradin/luadraw %https://tex.stackexchange.com/questions/729965/automate-the-drawing-of-angles-in-3d-perspective \begin{document} \begin{luadraw}{name=arc3d} local g = graph3d:new{window={-5,5,-4,3}, viewdir={30,60}, size={10,10}} g:Linejoin("round"); Hiddenlines = true; g:Linewidth(5);Hiddenlinestyle = "dashed" g:Dplane({Origin,vecK}, vecJ, 7,8) local A, B, C = M(2,-1,0), M(1,2,0), M(-2,1,0) g:Dpolyline3d({A,B,C},true) g:Darc3d(B,A,C,1,1) g:Darc3d(A,B,C,0.5,1,"->") g:Dpath3d({A,C,B,0.75,1,"ca",C,"l","cl"},"fill=pink,draw=none") g:Darc3d(A,C,B,0.75,1) g:Dlabel3d("$A$",A,{pos="S"}, "$B$",B,{}, "$C$",C,{pos="N"}) g:Show() \end{luadraw} \end{document} 

enter image description here

I have added this code

\documentclass[12pt]{standalone}% compile with lualatex only \usepackage[svgnames]{xcolor} \usepackage{fouriernc} \usepackage[3d]{luadraw}%https://github.com/pfradin/luadraw %https://tex.stackexchange.com/questions/729965/automate-the-drawing-of-angles-in-3d-perspective \begin{document} \begin{luadraw}{name=arc3d} local g = graph3d:new{window={-5,5,-5,6}, viewdir={60,60}, size={10,10}} g:Linejoin("round"); Hiddenlines = true; g:Linewidth(5);Hiddenlinestyle = "dashed" local A, B, C = M(2,0,0), M(0,3,0), M(0,0,3) local n = pt3d.prod(B-A,C-A) g:Dplane({(A+B+C)/3,n}, B-A, 8,8) g:Dpolyline3d({A,B,C},true) g:Darc3d(B,A,C,0.5,1) g:Darc3d(A,B,C,0.5,1,"->") g:Dpath3d({A,C,B,0.75,1,"ca",C,"l","cl"},"fill=pink,draw=none") g:Darc3d(A,C,B,0.75,1) g:Dlabel3d("$A$",A,{pos="S"}, "$B$",B,{}, "$C$",C,{pos="N"}) g:Show() \end{luadraw} \end{document} 

enter image description here

3

You can make use of the transform shape option:

\documentclass[tikz, border=1cm]{standalone} \usepackage{tikz-3dplot} \usetikzlibrary{angles} \begin{document} \tdplotsetmaincoords{60}{130} \begin{tikzpicture}[tdplot_main_coords] \pgfmathsetmacro\pa{2} \pgfmathsetmacro\pb{2} \pgfmathsetmacro\pc{1} \pgfmathsetmacro\qa{-1} \pgfmathsetmacro\qb{2} \pgfmathsetmacro\qc{2} \pgfmathsetmacro\ra{1} \pgfmathsetmacro\rb{-1} \pgfmathsetmacro\rc{2} \pgfmathsetmacro\qpa{\pa-\qa} \pgfmathsetmacro\qpb{\pb-\qb} \pgfmathsetmacro\qpc{\pc-\qc} \pgfmathsetmacro\qpl{sqrt((\qpa)^2 + (\qpb)^2 + (\qpc)^2)} \pgfmathsetmacro\qpa{\qpa/\qpl} \pgfmathsetmacro\qpb{\qpb/\qpl} \pgfmathsetmacro\qpc{\qpc/\qpl} \pgfmathsetmacro\qra{\ra-\qa} \pgfmathsetmacro\qrb{\rb-\qb} \pgfmathsetmacro\qrc{\rc-\qc} \pgfmathsetmacro\qrl{sqrt((\qra)^2 + (\qrb)^2 + (\qrc)^2)} \pgfmathsetmacro\qra{\qra/\qrl} \pgfmathsetmacro\qrb{\qrb/\qrl} \pgfmathsetmacro\qrc{\qrc/\qrl} \tdplotcrossprod(\qpa,\qpb,\qpc)(\qra,\qrb,\qrc) \pgfmathsetmacro\za{\tdplotresx} \pgfmathsetmacro\zb{\tdplotresy} \pgfmathsetmacro\zc{\tdplotresz} \coordinate (P) at (\pa,\pb,\pc); \coordinate (Q) at (\qa,\qb,\qc); \coordinate (R) at (\ra,\rb,\rc); \coordinate (QP) at (\qpa,\qpb,\qpc); \coordinate (QR) at (\qra,\qrb,\qrc); \coordinate (Z) at (\za,\zb,\zc); \draw[<->] (P) -- (Q) -- (R); \begin{scope}[ x={(QP)}, y={(QR)}, z={(Z)}, canvas is xy plane at z=0 ] %\draw[red] ($(Q) + (QP)$) arc[start angle=0, end angle=90, radius=1]; \draw pic[draw, blue, angle radius=1cm, transform shape] {angle=P--Q--R}; \end{scope} \end{tikzpicture} \end{document} 

output of above code


To automate things a bit further, you can create a custom style:

\documentclass[tikz, border=1cm]{standalone} \usepackage{tikz-3dplot} \usetikzlibrary{angles} \tikzset{ angle in plane/.style args={#1,#2,#3}{ x={(#1)}, y={(#2)}, z={(#3)}, canvas is xy plane at z=0, transform shape } } \begin{document} \tdplotsetmaincoords{60}{130} \begin{tikzpicture}[tdplot_main_coords] \pgfmathsetmacro\pa{2} \pgfmathsetmacro\pb{2} \pgfmathsetmacro\pc{1} \pgfmathsetmacro\qa{-1} \pgfmathsetmacro\qb{2} \pgfmathsetmacro\qc{2} \pgfmathsetmacro\ra{1} \pgfmathsetmacro\rb{-1} \pgfmathsetmacro\rc{2} \pgfmathsetmacro\qpa{\pa-\qa} \pgfmathsetmacro\qpb{\pb-\qb} \pgfmathsetmacro\qpc{\pc-\qc} \pgfmathsetmacro\qpl{sqrt((\qpa)^2 + (\qpb)^2 + (\qpc)^2)} \pgfmathsetmacro\qpa{\qpa/\qpl} \pgfmathsetmacro\qpb{\qpb/\qpl} \pgfmathsetmacro\qpc{\qpc/\qpl} \pgfmathsetmacro\qra{\ra-\qa} \pgfmathsetmacro\qrb{\rb-\qb} \pgfmathsetmacro\qrc{\rc-\qc} \pgfmathsetmacro\qrl{sqrt((\qra)^2 + (\qrb)^2 + (\qrc)^2)} \pgfmathsetmacro\qra{\qra/\qrl} \pgfmathsetmacro\qrb{\qrb/\qrl} \pgfmathsetmacro\qrc{\qrc/\qrl} \tdplotcrossprod(\qpa,\qpb,\qpc)(\qra,\qrb,\qrc) \pgfmathsetmacro\za{\tdplotresx} \pgfmathsetmacro\zb{\tdplotresy} \pgfmathsetmacro\zc{\tdplotresz} \coordinate (P) at (\pa,\pb,\pc); \coordinate (Q) at (\qa,\qb,\qc); \coordinate (R) at (\ra,\rb,\rc); \coordinate (QP) at (\qpa,\qpb,\qpc); \coordinate (QR) at (\qra,\qrb,\qrc); \coordinate (Z) at (\za,\zb,\zc); \draw[<->] (P) -- (Q) -- (R); \draw pic[draw, blue, angle radius=1cm, angle in plane={QP,QR,Z}] {angle={P--Q--R}}; \end{tikzpicture} \end{document} 

Same output as above.

But maybe setting the perspective globally is a better approach? Something like this (but I am unsure why the perspective is different from your original code):

\documentclass[tikz, border=1cm]{standalone} \usepackage{tikz-3dplot} \usetikzlibrary{angles} \tikzset{ xyz from points/.code args={(#1,#2,#3) (#4,#5,#6) (#7,#8,#9)}{ \pgfmathsetmacro\qpa{(#1-#4) / (sqrt((#1-#4)^2 + (#2-#5)^2 + (#3-#6)^2))} \pgfmathsetmacro\qpb{(#2-#5) / (sqrt((#1-#4)^2 + (#2-#5)^2 + (#3-#6)^2))} \pgfmathsetmacro\qpc{(#3-#6) / (sqrt((#1-#4)^2 + (#2-#5)^2 + (#3-#6)^2))} \pgfmathsetmacro\qra{(#7-#4) / (sqrt((#7-#4)^2 + (#8-#5)^2 + (#9-#6)^2))} \pgfmathsetmacro\qrb{(#8-#5) / (sqrt((#7-#4)^2 + (#8-#5)^2 + (#9-#6)^2))} \pgfmathsetmacro\qrc{(#9-#6) / (sqrt((#7-#4)^2 + (#8-#5)^2 + (#9-#6)^2))} \tdplotcrossprod(\qpa,\qpb,\qpc)(\qra,\qrb,\qrc) \tikzset{ x={(\qpa,\qpb,\qpc)}, y={(\qra,\qrb,\qrc)}, z={(\tdplotresx,\tdplotresy,\tdplotresz)}, canvas is xy plane at z=0 } } } \begin{document} \tdplotsetmaincoords{60}{130} \begin{tikzpicture}[ tdplot_main_coords, xyz from points={(2,2,1) (-1,2,2) (1,-1,2)} ] \coordinate (P) at (2,0,0); \coordinate (Q) at (0,0,0); \coordinate (R) at (0,2,0); \draw[<->] (P) -- (Q) -- (R); \draw pic[draw, blue, angle radius=1cm, transform shape] {angle={P--Q--R}}; \end{tikzpicture} \end{document} 
10
  • Thank you, is there a way to do it without specifying the unit vectors for the canvas? I don't like doing all of those calculations. Commented Nov 1, 2024 at 22:47
  • Like, could I just define three coordinates, and have the angle automatically be drawn in the plane through them? Commented Nov 1, 2024 at 22:51
  • @Jasper What about creating a custom style with x={(QP)}, y={(QR)}, z={(Z)}, canvas is xy plane at z=0, transform shape and add this as option to the pic? Commented Nov 2, 2024 at 6:28
  • Ah, I think I can use a distance modifier in tikz calc to make QP and QR unit vectors, then we wouldn't need to use so many \pgfmathsetmacros. The hard part with calculating the style is that I need to access the individual coordinate components to perform calculations on them (e.g. the cross product). Commented Nov 2, 2024 at 7:46
  • 1
    @Jasper You can accept your own answer if this is better suited to solve your problem. Commented Jan 13 at 5:57
2

There is a tikz-3dplot solution: (the thick green one is correct, though it has a dimension too large error.) See \tdplotdrawpolytopearc

\documentclass[tikz, border=1cm]{standalone} \usepackage{tikz-3dplot} \usetikzlibrary{calc,angles} \begin{document} \tdplotsetmaincoords{60}{130} \begin{tikzpicture}[tdplot_main_coords] \pgfmathsetmacro\pa{2} \pgfmathsetmacro\pb{2} \pgfmathsetmacro\pc{1} \pgfmathsetmacro\qa{-1} \pgfmathsetmacro\qb{2} \pgfmathsetmacro\qc{2} \pgfmathsetmacro\ra{1} \pgfmathsetmacro\rb{-1} \pgfmathsetmacro\rc{2} \pgfmathsetmacro\qpa{\pa-\qa} \pgfmathsetmacro\qpb{\pb-\qb} \pgfmathsetmacro\qpc{\pc-\qc} \pgfmathsetmacro\qpl{sqrt((\qpa)^2 + (\qpb)^2 + (\qpc)^2)} \pgfmathsetmacro\qpa{\qpa/\qpl} \pgfmathsetmacro\qpb{\qpb/\qpl} \pgfmathsetmacro\qpc{\qpc/\qpl} \pgfmathsetmacro\qra{\ra-\qa} \pgfmathsetmacro\qrb{\rb-\qb} \pgfmathsetmacro\qrc{\rc-\qc} \pgfmathsetmacro\qrl{sqrt((\qra)^2 + (\qrb)^2 + (\qrc)^2)} \pgfmathsetmacro\qra{\qra/\qrl} \pgfmathsetmacro\qrb{\qrb/\qrl} \pgfmathsetmacro\qrc{\qrc/\qrl} \tdplotcrossprod(\qpa,\qpb,\qpc)(\qra,\qrb,\qrc) \pgfmathsetmacro\za{\tdplotresx} \pgfmathsetmacro\zb{\tdplotresy} \pgfmathsetmacro\zc{\tdplotresz} \coordinate (P) at (\pa,\pb,\pc); \coordinate (Q) at (\qa,\qb,\qc); \coordinate (R) at (\ra,\rb,\rc); \coordinate (QP) at (\qpa,\qpb,\qpc); \coordinate (QR) at (\qra,\qrb,\qrc); \coordinate (Z) at (\za,\zb,\zc); \draw[<->] (P) -- (Q) -- (R); \begin{scope}[ x={(QP)}, y={(QR)}, z={(Z)}, canvas is xy plane at z=0 ] \draw[red] ($(Q) + (QP)$) arc[start angle=0, end angle=90, radius=1]; \draw pic[draw,blue,-, angle radius=1cm,]{angle=R--Q--P}; \end{scope} %%% added \tdplotdefinepoints(\qa,\qb,\qc)(\pa,\pb,\pc)(\ra,\rb,\rc) \tdplotdrawpolytopearc[ultra thick, green]{1}{left}{} \end{tikzpicture} \end{document} 

output

4
  • you asked if I would change the tick here. hmm. there is not the same advantage to changing this one because your answer will not go to the top if you accept it. however, accepting this answer may make it more likely it will get enough votes to rise to the top and encourage people to read on, whereas having the other answer ticked guarantees it will always be first. but I don't tend to switch a tick - or even accept - my own answer, if it builds on another one or is just an alternative. so maybe ask the other Jasper whether s/t/he/y'd prefer to add a pointer to this answer first? Commented Jan 13 at 3:39
  • Thank you @cfr, I will inquire about this with Jasper. Thank you for your time. Commented Jan 13 at 3:42
  • 1
    note that I don't really know this code well enough to understand the answers and compare them without spending time playing with them, so I'm just assuming your assessment is correct. note, too, that SE policy says you should accept the best answer irrespective of author. so what I say I would do is not what SE says you should do. sorry if this makes it more complicated. SE wouldn't suggest you ask the other author, either. but TeX SE has a bunch of social conventions which aren't always perfectly aligned with SE theory ;). Commented Jan 13 at 3:43
  • 1
    @cfr, the code looks complicated because I included all examples. The real answer is just \tdplotdrawpolytopearc Commented Jan 13 at 3:47

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.