Is there a more elegant implementation of this fit-to-bounding-box coordinate transform in TikZ/PGF

tikz-pgftransformation

I have a plottable function whose normalized domain is [0,1] and whose normalized range is [-1,1]. I also have two TikZ coordinates, (BOTLEFT) and (TOPRIGHT) defining the bottom left and top right of a bounding box where I would like the plot to appear.

I would like to effect a skewless, rotationless affine linear coordinate transform such that the plot domain/range is fitted exactly to the bounding box. That is, each point (x,y) is mapped to

(x,y) → (BOTLEFT) + ((TOPRIGHT)(BOTLEFT)) · ((x,y) – (0,-1)) ÷ ((1,1) – (0,-1))

For example, the sine wave

\draw[domain = 0:1, samples = 256] plot (\x,{sin(\x*4*pi r)});

when subject to the transform, should fit exactly inside the bounding box

\draw[red] (-2,5) rectangle (1,8);

if (BOTLEFT) is (-2,5) and (TOPRIGHT) is (1,8).

TikZ supports the xshift, yshift, xscale and yscale properties to implement the coordinate transform. However, computing the xscale and yscale properties manually using coordinate arithmetic would appear to require isolating the x and y components of (BOTLEFT) and (TOPRIGHT). I know this can be done (e.g., by the let directive):

\coordinate (BOTLEFT) at ({-.2},.5);
\coordinate (TOPRIGHT) at (.1,.8);

\draw let
    \p1 = (BOTLEFT),
    \p2 = (TOPRIGHT) in [domain = 0:1, samples = 256,
        xshift = \x1,
        xscale = (\x2 - \x1)\pts,
        yshift = (\y1 + (\y2 - \y1)/2),
        yscale = ((\y2 - \y1)/2)\pts
        ] plot (\x,{sin(\x*4*pi r)});
\draw[red] (BOTLEFT) rectangle (TOPRIGHT);

where \pts is a macro that expands to *<constant> to convert from pts to the scaling units for the figure, but this seems extremely messy, especially for TikZ/PGF. I can't help but think that TikZ has some kind of built-in to handle this. It would be especially useful if the transform could be scope-d, too. That is,

\begin{scope}[<set transform here>]
    \draw[domain = 0:1, samples = 256] plot (\x,{sin(\x*4*pi r)});
    <more commands in same coordinate frame>
    ...
\end{scope}

Is there a more elegant way of handling this in TikZ, or am I stuck with hacking the coordinate math in this way?


Clarification #1

The coordinates (BOTLEFT) and (TOPRIGHT) are computed using expressions involving node anchor points, not numeric literals as in the example.

Best Answer

This fits (0,0) to (1,1) into (BOTLEFT) to (TOPRIGHT). It involves the fewest math or conversion steps I could think of.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\coordinate (BOTLEFT) at (-1,-1);
\coordinate (TOPRIGHT) at (2,1);
\fill[black] (BOTLEFT) rectangle (TOPRIGHT);

\coordinate (BOTRIGHT) at (BOTLEFT-|TOPRIGHT);
\coordinate (xscale) at ($(BOTRIGHT)-(BOTLEFT)$);% (3,0)
\coordinate (yscale) at ($(TOPRIGHT)-(BOTRIGHT)$);% (0,2)

\pgfscope
\pgfsetxvec{\pgfpointanchor{xscale}{center}}%
\pgfsetyvec{\pgfpointanchor{yscale}{center}}%
\begin{scope}[shift=(BOTLEFT)]
\node[gray] at (0.5,0.5) {test};
\draw[red] (0,0) rectangle (1,1);
\end{scope}
\endpgfscope
\end{tikzpicture}
\end{document}