summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty')
-rw-r--r--Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty320
1 files changed, 268 insertions, 52 deletions
diff --git a/Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty b/Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty
index 819e8394fd4..4873efb424d 100644
--- a/Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty
+++ b/Master/texmf-dist/tex/latex/tikz-3dplot/tikz-3dplot.sty
@@ -20,7 +20,7 @@
%tikz-3dplot.sty - package for plotting three dimensional axes and coordinates in TikZ. The user can specify orientation of the display, and also define rotated coordinate systems within the 3d display coordinate system.
-%Created 2009-11-07 by Jeff Hein. Last updated: 2010-01-17
+%Created 2009-11-07 by Jeff Hein. Last updated: 2010-01-20
%----------------------------------------------------------
%Requirements
@@ -30,20 +30,8 @@
%Update Notes
%------------
-%2009-11-07: Created package from previous scratch work
-%2009-11-18: Added a few macros for storing user-specified coordinate frame angles. Useful for commands which would like to know what the current display perspective is.
-%2009-11-21: Added spherical polar parametric surface plotting functionality with the \tdplotsphericalsurfaceplot command.
-%2009-12-03: Fixed the range checking for polar parametric plotting. It should now behave better around the range \phi = 0
-%2010-01-17: renamed the package to tikz-3dplot.
+%see the documentation for update notes
-%TODO list
-%---------
-
-%TODO: figure out how to work in a variable scope that doesn't interfere with other packages
-%TODO: find a way to check if TikZ is loaded, and give a compile error if necessary
-%TODO: find a way to use predefined coordinates in rotated or translated coordinate frames, instead of just literal coordinates
-%TODO: generalize matrix math if such a package exists
-%TODO: look into using TikZ spherical polar coordinates explicitly to streamline coordinate definitions.
\RequirePackage{pgf}
\RequirePackage{ifthen}
@@ -54,11 +42,11 @@
\tikzset{tdplot_screen_coords/.style={x={(1 cm,0 cm)},y={(0 cm, 1 cm)},z={(-1 cm, -1 cm)}}}%
-\pgfmathsetmacro{\lowerphi}{0}
-\pgfmathsetmacro{\upperphi}{360}
-\pgfmathsetmacro{\lowertheta}{0}
-\pgfmathsetmacro{\uppertheta}{180}
-
+\pgfmathsetmacro{\tdplotlowerphi}{0}
+\pgfmathsetmacro{\tdplotupperphi}{360}
+\pgfmathsetmacro{\tdplotlowertheta}{0}
+\pgfmathsetmacro{\tdplotuppertheta}{180}
+%\pgfmathsetmacro{\tdplotlinewidth}{.25pt}
%Commands
%--------
@@ -145,22 +133,12 @@
\tikzset{tdplot_main_coords/.style={x={(\raarot cm,\rbarot cm)},y={(\rabrot cm, \rbbrot cm)},z={(\racrot cm, \rbcrot cm)}}}%
}
-
-%\tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}
-%generates the coordinate transformation for the rotated coordinate system within the display coordinate system. This should be called only after the display coordinate system has been defined. If the display coordinate system changes, this will have to be updated.
-%#1: user-specified euler angle \alpha.
-%#2: user-specified euler angle \beta.
-%#3: user-specified euler angle \gamma.
-\newcommand{\tdplotsetrotatedcoords}[3]{%
-%
-\pgfmathsetmacro{\alphaeul}{#1}
-\pgfmathsetmacro{\betaeul}{#2}
-\pgfmathsetmacro{\gammaeul}{#3}
-%
+%determines the rotation matrix for transformation from the rotation coordinate frame to the main coordinate frame. This also defines the rotation to produce the rotated coordinate frame.
+\newcommand{\tdplotcalctransformrotmain}{%
%perform some trig for the Euler transformation
-\tdplotsinandcos{\sinalpha}{\cosalpha}{\alphaeul}
-\tdplotsinandcos{\sinbeta}{\cosbeta}{\betaeul}
-\tdplotsinandcos{\singamma}{\cosgamma}{\gammaeul}
+\tdplotsinandcos{\sinalpha}{\cosalpha}{\tdplotalpha}
+\tdplotsinandcos{\sinbeta}{\cosbeta}{\tdplotbeta}
+\tdplotsinandcos{\singamma}{\cosgamma}{\tdplotgamma}
%
\tdplotmult{\sasb}{\sinalpha}{\sinbeta}
\tdplotmult{\sbsg}{\sinbeta}{\singamma}
@@ -198,6 +176,87 @@
%\rbaeul\ \rbbeul\ \rbceul
%
%\rcaeul\ \rcbeul\ \rcceul
+}
+
+
+%determines the rotation matrix for transformation from the main coordinate frame to the rotated coordinate frame.
+\newcommand{\tdplotcalctransformmainrot}{%
+%perform some trig for the Euler transformation
+\tdplotsinandcos{\sinalpha}{\cosalpha}{\tdplotalpha}
+\tdplotsinandcos{\sinbeta}{\cosbeta}{\tdplotbeta}
+\tdplotsinandcos{\singamma}{\cosgamma}{\tdplotgamma}
+%
+\tdplotmult{\sasb}{\sinalpha}{\sinbeta}
+\tdplotmult{\sbsg}{\sinbeta}{\singamma}
+\tdplotmult{\sasg}{\sinalpha}{\singamma}
+\tdplotmult{\sasbsg}{\sasb}{\singamma}
+%
+\tdplotmult{\sacb}{\sinalpha}{\cosbeta}
+\tdplotmult{\sacg}{\sinalpha}{\cosgamma}
+\tdplotmult{\sbcg}{\sinbeta}{\cosgamma}
+\tdplotmult{\sacbsg}{\sacb}{\singamma}
+\tdplotmult{\sacbcg}{\sacb}{\cosgamma}
+%
+\tdplotmult{\casb}{\cosalpha}{\sinbeta}
+\tdplotmult{\cacb}{\cosalpha}{\cosbeta}
+\tdplotmult{\cacg}{\cosalpha}{\cosgamma}
+\tdplotmult{\casg}{\cosalpha}{\singamma}
+%
+\tdplotmult{\cacbsg}{\cacb}{\singamma}
+\tdplotmult{\cacbcg}{\cacb}{\cosgamma}
+%
+%determine rotation matrix elements for Euler transformation
+\pgfmathsetmacro{\raaeul}{\cacbcg - \sasg}
+\pgfmathsetmacro{\rabeul}{\sacbcg + \casg}
+\pgfmathsetmacro{\raceul}{-\sbcg}
+\pgfmathsetmacro{\rbaeul}{-\cacbsg - \sacg}
+\pgfmathsetmacro{\rbbeul}{-\sacbsg + \cacg}
+\pgfmathsetmacro{\rbceul}{\sbsg}
+\pgfmathsetmacro{\rcaeul}{\casb}
+\pgfmathsetmacro{\rcbeul}{\sasb}
+\pgfmathsetmacro{\rcceul}{\cosbeta}
+%
+%DEBUG: display euler matrix elements
+%\raaeul\ \rabeul\ \raceul
+%
+%\rbaeul\ \rbbeul\ \rbceul
+%
+%\rcaeul\ \rcbeul\ \rcceul
+}
+
+%transforms a coordinate from the main coordinate frame to the rotated coordinate frame
+\newcommand{\tdplottransformmainrot}[3]{%
+ \tdplotcalctransformmainrot
+
+ \pgfmathsetmacro{\tdplotresx}{\raaeul * #1 + \rabeul * #2 + \raceul * #3}
+ \pgfmathsetmacro{\tdplotresy}{\rbaeul * #1 + \rbbeul * #2 + \rbceul * #3}
+ \pgfmathsetmacro{\tdplotresz}{\rcaeul * #1 + \rcbeul * #2 + \rcceul * #3}
+}
+
+%transforms a coordinate from the rotated coordinate frame to the main coordinate frame
+\newcommand{\tdplottransformrotmain}[3]{%
+ \tdplotcalctransformrotmain
+
+ \pgfmathsetmacro{\tdplotresx}{\raaeul * #1 + \rabeul * #2 + \raceul * #3}
+ \pgfmathsetmacro{\tdplotresy}{\rbaeul * #1 + \rbbeul * #2 + \rbceul * #3}
+ \pgfmathsetmacro{\tdplotresz}{\rcaeul * #1 + \rcbeul * #2 + \rcceul * #3}
+}
+
+
+
+%\tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}
+%generates the coordinate transformation for the rotated coordinate system within the display coordinate system. This should be called only after the display coordinate system has been defined. If the display coordinate system changes, this will have to be updated.
+%#1: user-specified euler angle \alpha.
+%#2: user-specified euler angle \beta.
+%#3: user-specified euler angle \gamma.
+\newcommand{\tdplotsetrotatedcoords}[3]{%
+%
+\pgfmathsetmacro{\tdplotalpha}{#1}
+\pgfmathsetmacro{\tdplotbeta}{#2}
+\pgfmathsetmacro{\tdplotgamma}{#3}
+%
+\tdplotcalctransformrotmain
+
%
%now, determine master rotation matrix to define euler-rotated coordinates within the display coordinate frame
\tdplotmult{\raaeaa}{\raarot}{\raaeul}
@@ -292,7 +351,7 @@
%this places the rotated coordinate system into the "theta plane" for the current rotated coordinate system, at user-specified angle \phi'. Note that it replaces the current rotated coordinate system
%#1: user-specified \phi' angle from x'-axis
\newcommand{\tdplotsetrotatedthetaplanecoords}[1]{%
- \tdplotsetrotatedcoords{\alphaeul}{\betaeul}{\gammaeul + #1}%
+ \tdplotsetrotatedcoords{\tdplotalpha}{\tdplotbeta}{\tdplotgamma + #1}%
%
%permute the coordinates
\tikzset{tdplot_rotated_coords/.append style={y={(\raarc cm,\rbarc cm)},z={(\rabrc cm, \rbbrc cm)},x={(\racrc cm, \rbcrc cm)}}}%
@@ -354,6 +413,77 @@
\draw[#1] #2 + (#4:#3) arc (#4:#5:#3);
}
+\def\tdplotdefinepoints(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){%
+ \pgfmathsetmacro{\tdplotvertexx}{#1}
+ \pgfmathsetmacro{\tdplotvertexy}{#2}
+ \pgfmathsetmacro{\tdplotvertexz}{#3}
+ \pgfmathsetmacro{\tdplotax}{#4}
+ \pgfmathsetmacro{\tdplotay}{#5}
+ \pgfmathsetmacro{\tdplotaz}{#6}
+ \pgfmathsetmacro{\tdplotbx}{#7}
+ \pgfmathsetmacro{\tdplotby}{#8}
+ \pgfmathsetmacro{\tdplotbz}{#9}
+}%
+
+
+%draws an arc using three specified points
+%\tdplotdrawpolytopearc[thick]{1}{anchor=west}{$\theta$}
+\newcommand{\tdplotdrawpolytopearc}[4][]{%
+
+ %determine vector lengths
+ \pgfmathsetmacro{\ax}{\tdplotax - \tdplotvertexx}
+ \pgfmathsetmacro{\ay}{\tdplotay - \tdplotvertexy}
+ \pgfmathsetmacro{\az}{\tdplotaz - \tdplotvertexz}
+
+ \pgfmathsetmacro{\bx}{\tdplotbx - \tdplotvertexx}
+ \pgfmathsetmacro{\by}{\tdplotby - \tdplotvertexy}
+ \pgfmathsetmacro{\bz}{\tdplotbz - \tdplotvertexz}
+
+ %determine normal to vectors
+ \tdplotcrossprod(\ax,\ay,\az)(\bx,\by,\bz)
+
+ %DEBUG: show the cross product
+ %\draw[->,blue] (\tdplotvertexx,\tdplotvertexy,\tdplotvertexz)
+ % -- ++(\tdplotresx,\tdplotresy,\tdplotresz);
+
+ %get angles for this vector
+ \tdplotgetpolarcoords{\tdplotresx}{\tdplotresy}{\tdplotresz}
+
+ %place the rotated coordinate system so that the z' axis points along this vector
+ \tdplotsetrotatedcoords{\tdplotresphi}{\tdplotrestheta}{0}
+ \coordinate (Vertex) at (\tdplotvertexx,\tdplotvertexy,\tdplotvertexz);
+ \tdplotsetrotatedcoordsorigin{(Vertex)}
+
+ %DEBUG: show the rotated coordinate system
+ %\draw[thick,tdplot_rotated_coords,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x'$};
+ %\draw[thick,tdplot_rotated_coords,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y'$};
+ %\draw[thick,tdplot_rotated_coords,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z'$};
+
+ %calculate the start angle of the arc
+ \tdplottransformmainrot{\ax}{\ay}{\az}
+ \tdplotgetpolarcoords{\tdplotresx}{\tdplotresy}{\tdplotresz}
+ \pgfmathsetmacro{\tdplotstartphi}{\tdplotresphi}
+
+ %calculate the end angle of the arc
+ \tdplottransformmainrot{\bx}{\by}{\bz}
+ \tdplotgetpolarcoords{\tdplotresx}{\tdplotresy}{\tdplotresz}
+
+ %draw the arc
+ \pgfmathparse{\tdplotstartphi < \tdplotresphi}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {}%
+ {
+ \pgfmathsetmacro{\tdplotstartphi}{\tdplotstartphi - 360}
+ }
+
+ \draw[tdplot_rotated_coords,#1] (0,0,0) + (\tdplotstartphi:#2) arc (\tdplotstartphi:\tdplotresphi:#2);
+
+ \pgfmathsetmacro{\tdplotresphi}{(\tdplotresphi + \tdplotstartphi)/2}
+
+ \draw[tdplot_rotated_coords] (0,0,0) + (\tdplotresphi:#2) node[#3]{#4};
+}
+
+
% \tdplotsphericalsurfaceplot[fill mode]{theta step size}{phi step size}{r}
%draws a surface in spherical polar coordinates given by r(\theta,\phi), where angular ranges and steps are defined.
%#1: draw styles
@@ -450,17 +580,17 @@
%sets the angular range of the polar plot to user-specified values
\newcommand{\tdplotsetpolarplotrange}[4]{%
- \pgfmathsetmacro{\lowerphi}{#3}
- \pgfmathsetmacro{\upperphi}{#4}
- \pgfmathsetmacro{\lowertheta}{#1}
- \pgfmathsetmacro{\uppertheta}{#2}
+ \pgfmathsetmacro{\tdplotlowerphi}{#3}
+ \pgfmathsetmacro{\tdplotupperphi}{#4}
+ \pgfmathsetmacro{\tdplotlowertheta}{#1}
+ \pgfmathsetmacro{\tdplotuppertheta}{#2}
}
\newcommand{\tdplotresetpolarplotrange}{%
- \pgfmathsetmacro{\lowerphi}{0}
- \pgfmathsetmacro{\upperphi}{360}
- \pgfmathsetmacro{\lowertheta}{0}
- \pgfmathsetmacro{\uppertheta}{180}
+ \pgfmathsetmacro{\tdplotlowerphi}{0}
+ \pgfmathsetmacro{\tdplotupperphi}{360}
+ \pgfmathsetmacro{\tdplotlowertheta}{0}
+ \pgfmathsetmacro{\tdplotuppertheta}{180}
}
@@ -505,23 +635,23 @@
}{}%
%test to see if this value is within the specified angular range
- \pgfmathparse{\tdplottheta > \uppertheta}
+ \pgfmathparse{\tdplottheta > \tdplotuppertheta}
\pgfmathsetmacro{\logictest}{1 - \pgfmathresult}
- \pgfmathparse{\tdplottheta < \lowertheta}
+ \pgfmathparse{\tdplottheta < \tdplotlowertheta}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
\pgfmathsetmacro{\tdplottheta}{\tdplottheta + \viewthetastep}
- \pgfmathparse{\tdplottheta > \uppertheta}
+ \pgfmathparse{\tdplottheta > \tdplotuppertheta}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
- \pgfmathparse{\tdplottheta < \lowertheta}
+ \pgfmathparse{\tdplottheta < \tdplotlowertheta}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
- \pgfmathparse{\tdplotphi > \upperphi}
+ \pgfmathparse{\tdplotphi > \tdplotupperphi}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
- \pgfmathparse{\tdplotphi < \lowerphi}
+ \pgfmathparse{\tdplotphi < \tdplotlowerphi}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
\pgfmathsetmacro{\tdplotphi}{\tdplotphi + \viewphistep}
@@ -531,19 +661,21 @@
\pgfmathsetmacro{\tdplotphi}{\tdplotphi + 360}
}{}%
- \pgfmathparse{\tdplotphi > \upperphi}
+ \pgfmathparse{\tdplotphi > \tdplotupperphi}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
- \pgfmathparse{\tdplotphi < \lowerphi}
+ \pgfmathparse{\tdplotphi < \tdplotlowerphi}
\pgfmathsetmacro{\logictest}{\logictest * (1 - \pgfmathresult)}
\pgfmathsetmacro{\tdplottheta}{\curtheta}
\pgfmathsetmacro{\tdplotphi}{\curphi}
-
+ %if using fill color parametric to angles
\ifthenelse{\equal{#6}{parametricfill}}{%
\pgfmathsetmacro{\radius}{#1}
+ \pgfmathsetmacro{\tdplotr}{\radius*360} %factor of 360 lets the radius change hue through one full cycle for each unit radius
+
\pgfmathlessthan{\radius}{0}
\pgfmathsetmacro{\phaseshift}{180 * \pgfmathresult}
@@ -632,6 +764,90 @@
}
+%\tdplotgetpolarcoords{\vx}{\vy}{\vz}
+%determines the theta and phi angle associated with the specified x, y, and z components of a vector
+\newcommand{\tdplotgetpolarcoords}[3]{%
+%
+ \pgfmathsetmacro{\vxcalc}{#1}
+ \pgfmathsetmacro{\vycalc}{#2}
+ \pgfmathsetmacro{\vzcalc}{#3}
+%
+ \pgfmathsetmacro{\vcalc}{ sqrt(\vxcalc^2 + \vycalc^2 + \vzcalc^2) }
+% \pgfmathsetmacro{\vcalc}{ (\vxcalc^2 + \vycalc^2 + \vzcalc^2)^.5 }
+
+ \pgfmathsetmacro{\vxycalc}{ sqrt(\vxcalc^2 + \vycalc^2) }
+% \pgfmathsetmacro{\vxycalc}{ (\vxcalc^2 + \vycalc^2)^.5 }
+
+ \pgfmathsetmacro{\tdplotrestheta}{asin(\vxycalc/\vcalc)}
+%
+ %check for angles larger than 90
+ \pgfmathparse{\vzcalc < 0}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {%
+ \pgfmathsetmacro{\tdplotrestheta}{180 - \tdplotrestheta}
+ }
+ {}
+%
+ %check for special case: vx = 0
+ \ifthenelse{\equal{\vxcalc}{0.0}}%
+ {%
+ %check the sign of vy, and set angle appropriately
+ \pgfmathparse{\vycalc < 0}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {%
+ \pgfmathsetmacro{\tdplotresphi}{270}
+ }
+ {%
+ \pgfmathparse{\vycalc == 0}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {%
+ \pgfmathsetmacro{\tdplotresphi}{0}
+ }
+ {%
+ \pgfmathsetmacro{\tdplotresphi}{90}
+ }
+ }
+ }
+ {%
+ %perform the arctan calculation
+ \pgfmathsetmacro{\tdplotresphi}{atan(\vycalc/\vxcalc)}
+%
+ %check if vx is less than zero, to properly identify the quadrant
+ \pgfmathparse{\vxcalc < 0}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {%
+ %increase by half a rotation if necessary
+ \pgfmathsetmacro{\tdplotresphi}{\tdplotresphi+180}
+ }
+ {}
+
+ %ensure the angle lies between 0 and 360 degrees
+ \pgfmathparse{\tdplotresphi < 0}
+ \ifthenelse{\equal{\pgfmathresult}{1.0}}%
+ {%
+ \pgfmathsetmacro{\tdplotresphi}{\tdplotresphi+360}
+ }
+ {}
+ }
+}
+
+
+% \tdplotcrossprod(\ax,\ay,\az)(\bx,\by,\bz)
+\def\tdplotcrossprod(#1,#2,#3)(#4,#5,#6){%
+ \pgfmathsetmacro{\tdplotresx}{#2 * #6 - #3 * #5}
+ \pgfmathsetmacro{\tdplotresy}{#3 * #4 - #1 * #6}
+ \pgfmathsetmacro{\tdplotresz}{#1 * #5 - #2 * #4}
+
+}
+
+%\newcommand{\tdplottransform
+%
+%
+%\newcommand{\tdplotgetplane}{
+%
+%}
+
+
%Notes
%-----