5

I'd like to visualize some points in 3D together with the connecting triangles and the unit normals of these triangles (cross product of the difference vectors between the points) together with the average unit normal (n_i) of the normals.

What I did so far can be seen in this MWE. It's kind of hacky and looks "incorrect". The latter seems to be caused by:

  1. I'm not sure if the normals are oriented into the right direction.
  2. I'm pretty sure the normals do not have the correct length (they have the same length in 2D, but not in 3D).

Also, there is this gap between the right angles and the indicated difference vectors. Any help is more than appreciated! Btw. I tried the answer(s) in this post but did not see an improvement.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{intersections}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{angles}

\begin{document}

\newcommand{\RightAngle}[4][blue]{%
  \draw[#1] ($#3!0.15cm!#2$)
  --($ #3!2!($($#3!0.15cm!#2$)!.5!($#3!0.15cm!#4$)$) $)
  --($#3!0.15cm!#4$) ;
}

\begin{center}
  \definecolor{vis_pab}{RGB}{0,0,255}
  \definecolor{vis_pbc}{RGB}{0,150,0}
  \definecolor{vis_pda}{RGB}{255,0,0}
  \definecolor{vis_pcd}{RGB}{255,165,0}
  \definecolor{vis_highlight}{RGB}{0,0,0}

  \tdplotsetmaincoords{70}{130}
  \begin{tikzpicture}[>=stealth,shorten >=1pt,tdplot_main_coords, scale=1.2]

    \pgfmathsetmacro{\Px}{ 0.0}; \pgfmathsetmacro{\Py}{-0.1}; \pgfmathsetmacro{\Pz}{ 0.25};
    \pgfmathsetmacro{\Ax}{ 2.0}; \pgfmathsetmacro{\Ay}{ 2.3}; \pgfmathsetmacro{\Az}{ 0.0};
    \pgfmathsetmacro{\Bx}{-1.5}; \pgfmathsetmacro{\By}{ 1.35}; \pgfmathsetmacro{\Bz}{-0.95};
    \pgfmathsetmacro{\Cx}{-2.0}; \pgfmathsetmacro{\Cy}{-2.5}; \pgfmathsetmacro{\Cz}{ 0.0};
    \pgfmathsetmacro{\Dx}{ 2.0}; \pgfmathsetmacro{\Dy}{-1.0}; \pgfmathsetmacro{\Dz}{ -0.25};
    \coordinate (p) at (\Px, \Py, \Pz);
    \coordinate (a) at (\Ax, \Ay, \Az);
    \coordinate (b) at (\Bx, \By, \Bz);
    \coordinate (c) at (\Cx, \Cy, \Cz);
    \coordinate (d) at (\Dx, \Dy, \Dz);


    \draw[dashed,->] (0,0,0) -- (3,0,0) node[left] {$x$};
    \draw[dashed,->] (0,0,0) -- (0,3,0) node[right] {$y$};
    \draw[dashed,->] (0,0,0) -- (0,0,2) node[above] {$z$};

    \draw[fill=black] (a) circle (2pt) node [below] {$\boldsymbol{a}$};
    \draw[fill=black] (b) circle (2pt) node [right] {$\boldsymbol{b}$};
    \draw[fill=black] (c) circle (2pt) node [above] {$\boldsymbol{c}$};
    \draw[fill=black] (d) circle (2pt) node [left] {$\boldsymbol{d}$};

    \fill[fill=vis_pab,opacity=0.1] (p) -- (a) -- (b) -- cycle;
    \fill[fill=vis_pbc,opacity=0.1] (p) -- (b) -- (c) -- cycle;
    \fill[fill=vis_pcd,opacity=0.1] (p) -- (c) -- (d) -- cycle;
    \fill[fill=vis_pda,opacity=0.1] (p) -- (d) -- (a) -- cycle;

    \draw (a) -- (b) -- (c) -- (d) -- (a) -- cycle;
    \draw (p) -- (a);
    \draw (p) -- (b);
    \draw (p) -- (c);
    \draw (p) -- (d);

    \draw[vis_highlight,fill=vis_highlight] (p) circle (2pt) node [below right] {$\boldsymbol{p}_i$};

    \coordinate (N1) at (barycentric cs:a=1,b=1,p=1);
    \coordinate (N2) at (barycentric cs:b=1,c=1,p=1);
    \coordinate (N3) at (barycentric cs:c=1,d=1,p=1);
    \coordinate (N4) at (barycentric cs:d=1,a=1,p=1);

    \fill[fill=vis_pab] (N1) circle (1pt);
    \fill[fill=vis_pbc] (N2) circle (1pt);
    \fill[fill=vis_pcd] (N3) circle (1pt);
    \fill[fill=vis_pda] (N4) circle (1pt);

    \pgfmathsetmacro{\PAx}{\Ax-\Px};
    \pgfmathsetmacro{\PAy}{\Ay-\Py};
    \pgfmathsetmacro{\PAz}{\Az-\Pz};
    \pgfmathsetmacro{\PBx}{\Bx-\Px};
    \pgfmathsetmacro{\PBy}{\By-\Py};
    \pgfmathsetmacro{\PBz}{\Bz-\Pz};
    \pgfmathsetmacro{\PCx}{\Cx-\Px};
    \pgfmathsetmacro{\PCy}{\Cy-\Py};
    \pgfmathsetmacro{\PCz}{\Cz-\Pz};
    \pgfmathsetmacro{\PDx}{\Dx-\Px};
    \pgfmathsetmacro{\PDy}{\Dy-\Py};
    \pgfmathsetmacro{\PDz}{\Dz-\Pz};
    \tdplotcrossprod(\PAx,\PAy,\PAz)(\PBx,\PBy,\PBz);
    \coordinate (NE1) at (\tdplotresx, \tdplotresy, \tdplotresz);
    \draw[dashed,draw=vis_pab] (N1) -- ($(N1)!1.75cm!(NE1)$);
    \draw[thick,draw=vis_pab,->] (N1) -- ($(N1)!1cm!(NE1)$);
    \coordinate (N1_support_a) at ($(N1) - (p) + (a)$);
    \draw[draw=vis_pab] (N1) -- ($(N1)!0.3cm!(N1_support_a)$);
    \coordinate (N1_support_b) at ($(N1) - (p) + (b)$);
    \draw[draw=vis_pab] (N1) -- ($(N1)!0.3cm!(N1_support_b)$);
    \RightAngle[draw=vis_pab]{(NE1)}{(N1)}{(N1_support_a)};
    \RightAngle[draw=vis_pab]{(NE1)}{(N1)}{(N1_support_b)};

    \tdplotcrossprod(\PBx,\PBy,\PBz)(\PCx,\PCy,\PCz);
    \coordinate (NE2) at (\tdplotresx, \tdplotresy, \tdplotresz);
    \draw[dashed,draw=vis_pbc>] (N2) -- ($(N2)!1.75cm!(NE2)$);
    \draw[thick,draw=vis_pbc,->] (N2) -- ($(N2)!1cm!(NE2)$);
    \coordinate (N2_support_b) at ($(N2) - (p) + (b)$);
    \draw[draw=vis_pbc] (N2) -- ($(N2)!0.3cm!(N2_support_b)$);
    \coordinate (N2_support_c) at ($(N2) - (p) + (c)$);
    \draw[draw=vis_pbc] (N2) -- ($(N2)!0.3cm!(N2_support_c)$);
    \RightAngle[draw=vis_pbc]{(NE2)}{(N2)}{(N2_support_b)};
    \RightAngle[draw=vis_pbc]{(NE2)}{(N2)}{(N2_support_c)};

    \tdplotcrossprod(\PCx,\PCy,\PCz)(\PDx,\PDy,\PDz);
    \coordinate (NE3) at (\tdplotresx, \tdplotresy, \tdplotresz);
    \draw[dashed,draw=vis_pcd] (N3) -- ($(N3)!1.75cm!(NE3)$);
    \draw[thick,draw=vis_pcd,->] (N3) -- ($(N3)!1cm!(NE3)$);
    \coordinate (N3_support_c) at ($(N3) - (p) + (c)$);
    \draw[draw=vis_pcd] (N3) -- ($(N3)!0.3cm!(N3_support_c)$);
    \coordinate (N3_support_d) at ($(N3) - (p) + (d)$);
    \draw[draw=vis_pcd] (N3) -- ($(N3)!0.3cm!(N3_support_d)$);
    \RightAngle[draw=vis_pcd]{(NE3)}{(N3)}{(N3_support_c)};
    \RightAngle[draw=vis_pcd]{(NE3)}{(N3)}{(N3_support_d)};

    \tdplotcrossprod(\PDx,\PDy,\PDz)(\PAx,\PAy,\PAz);
    \coordinate (NE4) at (\tdplotresx, \tdplotresy, \tdplotresz);
    \draw[dashed,draw=vis_pda] (N4) -- ($(N4)!1.75cm!(NE4)$);
    \draw[thick,draw=vis_pda,->] (N4) -- ($(N4)!1cm!(NE4)$);
    \coordinate (N4_support_d) at ($(N4) - (p) + (d)$);
    \draw[draw=vis_pda] (N4) -- ($(N4)!0.3cm!(N4_support_d)$);
    \coordinate (N4_support_a) at ($(N4) - (p) + (a)$);
    \draw[draw=vis_pda] (N4) -- ($(N4)!0.3cm!(N4_support_a)$);
    \RightAngle[draw=vis_pda]{(NE4)}{(N4)}{(N4_support_d)};
    \RightAngle[draw=vis_pda]{(NE4)}{(N4)}{(N4_support_a)};

    \coordinate (NP) at (barycentric cs:NE1=1,NE2=1,NE3=1,NE4=1);
    \draw[ultra thick,vis_highlight,->,>=stealth] (p) -- ($(p)!1cm!(NP)$) node [vis_highlight,near end,right] {$\boldsymbol{n}_i$};

  \end{tikzpicture}
\end{center}

\end{document}

result right now

1 Answers1

4

The results of the cross product are given as a vector relative to the origin, but you want it drawn relative to (N1) for example. Calculating the unit vector turned out to be straight foreward.

\pgfmathsetmacro{\s}{1/sqrt(\tdplotresx*\tdplotresx + \tdplotresy*\tdplotresy + \tdplotresz*\tdplotresz)}
\coordinate (NE1) at ($(N1)+(\s*\tdplotresx, \s*\tdplotresy, \s*\tdplotresz)$);
\draw[thick,draw=vis_pab,->] (N1) -- (NE1);

You can reuse \s when you do the other normal vectors.

\newcommand{\RightAngle}[4][blue]{%
  \draw[#1] #3 -- ($#3!0.15cm!#2$)
  --($($#3!0.3cm!#2$)!.5!($#3!0.3cm!#4$)$)
  --($#3!0.15cm!#4$) -- cycle;
}

will get rid of the gaps.

normal vectors

John Kormylo
  • 79,712
  • 3
  • 50
  • 120