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.
198 lines
7.1 KiB
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
|
|
|