% Copyright 2018 by Till Tantau % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. \ProvidesFileRCS{pgflibrarydatavisualization.polar.code.tex} \usepgfmodule{datavisualization}% % This file defines code for doing plots involving polar % coordinates. This includes not only standard polar plots, but also % pie charts. \pgfooclass{polar transformer} {% % Class polar mapper % % A polar mapper is used to transform attributes given as (2d) polar % coordinates to canvas coordinates. Note that no special ranges % can be specified and that the angle must be given in degrees. You % can, however, use a standard mapper to change these things. \attribute angle;% % The attribute from which the angle is read. \attribute radius;% % The attribute from which the radius is read. \attribute unit vector 0 degrees;% % The unit vector 0 degrees \attribute unit vector 90 degrees;% % The unit vector 90 degrees % Constructor % % #1 = angle attribute. Example: rotation. % #2 = radius attribute. Example: height. % #3 = unit vector 0 degrees % #4 = unit vector 90 degrees % \method polar transformer(#1,#2,#3,#4) { \pgfooset{angle}{#1} \pgfooset{radius}{#2} \pgfooset{unit vector 0 degrees}{#3} \pgfooset{unit vector 90 degrees}{#4} }% % Method \method default connects() { \pgfoothis.get handle(\pgf@dv@me) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,transform,transform datapoint signal) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,path,path signal) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,direction,direction signal) }% % Getters \method get angle attribute(#1) { \pgfooget{angle}{#1} }% \method get radius attribute(#1) { \pgfooget{radius}{#1} }% % Slot % % This slot should be connected to the transform datapoint % signal. When this signal is emitted, the coordinate system will be % shifted according to the current value of the attribute. \method transform() { \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}/const}\pgf@dv@angle% \ifx\pgf@dv@angle\relax \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@angle% \fi \ifx\pgf@dv@angle\relax\else% \ifx\pgf@dv@angle\pgfutil@empty\else% \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}/const}\pgf@dv@radius% \ifx\pgf@dv@radius\relax \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@radius% \fi \ifx\pgf@dv@radius\pgfutil@empty\else% \ifx\pgf@dv@radius\relax\else% \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@angle}% \pgfdvmathexitbyscientificformat{\pgf@dv@angle}{\pgf@dv@val}% \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@radius}% \pgfdvmathexitbyscientificformat{\pgf@dv@radius}{\pgf@dv@val}% \pgfmathsincos{\pgf@dv@angle}% \pgfmathmultiply{\pgfmathresultx}{\pgf@dv@radius}% \let\pgf@dv@polar@temp=\pgfmathresult \pgftransformshift{\pgfpointscale{\pgf@dv@polar@temp}{\pgfoovalueof{unit vector 0 degrees}}}% \pgfmathmultiply{\pgfmathresulty}{\pgf@dv@radius}% \let\pgf@dv@polar@temp=\pgfmathresult \pgftransformshift{\pgfpointscale{\pgf@dv@polar@temp}{\pgfoovalueof{unit vector 90 degrees}}}% \fi% \fi% \fi% \fi% }% % Reaction to the path signal % % Here is what we do: When a pgfdvpathmoveto is done, the radius and % the angle are recorded. When a pgfdvpathlineto is done, the saved % radius and angle are compared with the new angle and radius. If, % and only if, the radius is the same, but the angle is different, % the lineto is caught and replaced by an arc from the previous % position to the new position. \attribute prev angle;% \attribute prev radius;% \method path(#1) {% \ifpgfdvhandled% \else% \ifx#1\pgfdvpathlinetotoken % Ok, let us have a look... \pgfooget{prev radius}\pgf@dv@prev@rad \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@current@rad \ifx\pgf@dv@current@rad\relax \else \ifx\pgf@dv@current@rad\pgf@dv@prev@rad% \pgfooget{prev angle}\pgf@dv@prev@angle \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@current@angle \ifx\pgf@dv@current@angle\relax \else \ifx\pgf@dv@current@angle\pgf@dv@prev@angle% % do nothing \else% % Do arc: \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@angle}% \pgfdvmathexitbyscientificformat{\pgf@dv@prev@angle}{\pgf@dv@val}% \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@rad}% \pgfdvmathexitbyscientificformat{\pgf@dv@prev@rad}{\pgf@dv@val}% \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@angle}% \pgfdvmathexitbyscientificformat{\pgf@dv@current@angle}{\pgf@dv@val}% \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@rad}% \pgfdvmathexitbyscientificformat{\pgf@dv@current@rad}{\pgf@dv@val}% \pgfpatharcaxes{\pgf@dv@prev@angle}{\pgf@dv@current@angle} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 0 degrees}}} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 90 degrees}}}% \pgfdvhandledtrue% \fi% \fi% \fi% \fi% \fi% \fi% % No matter what, record the current position \pgfooeset{prev angle}{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} \pgfooeset{prev radius}{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} }% % Method % % React to direction signals. See pgfpointdvdirection for an % explanation % \method direction(#1) {% \ifx#1\pgfdvdirectionfromtoken % Record from angle and radius \xdef\pgf@dv@polar@from@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} \xdef\pgf@dv@polar@from@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} \else\ifx#1\pgfdvdirectiontotoken% % Record to angle and radius \xdef\pgf@dv@polar@to@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} \xdef\pgf@dv@polar@to@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} \else% \ifx\pgf@dv@polar@from@radius\pgf@dv@polar@to@radius% \pgfdvmathenter{\pgf@dv@a}{\pgf@dv@polar@from@angle}% \pgfdvmathenter{\pgf@dv@b}{\pgf@dv@polar@to@angle}% \pgfdvmathifless{\pgf@dv@a}{\pgf@dv@b}{\def\pgf@dv@temp@sign{+}}{\def\pgf@dv@temp@sign{-}}% \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@temp% \ifx\pgf@temp\relax% \else% \pgfdvmathenter{\pgf@dv@val}{\pgf@temp}% \pgfdvmathexitbyscientificformat{\pgf@dv@polar@angle}{\pgf@dv@val}% \pgf@process{\pgfpointpolar{\pgf@dv@polar@angle\pgf@dv@temp@sign90}{1pt}}% \pgfdvhandledtrue% \fi% \fi% \fi\fi% }% }% \endinput