You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
tex-compiler/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization...

198 lines
7.1 KiB

% Copyright 2008 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