Non-affine transform for visual detail

71 Views Asked by At

I'm designing a transformation that I think needs to be non-affine by definition. Technically it's a chain of two transformations:

The first transforms from the frequency space to a logarithmic chromatic music note space, in units of cents, via

$$ x = 100 \cdot 12 \log_2 \frac f {55} - t $$

where $t$ is some known, desired tuning note.

The second is an antisymmetric non-affine transformation $y(x)$ for the purposes of graphing with the following requirements:

$$y(0) = 0$$ $$y(600) = 600$$ $$y(x) = -y(-x)$$ $$ \text{For all } 0 \le x \le 600, \frac {\partial y}{\partial x} > 0$$ $$ \text{For all } 0 < x < 600, y(x) < x $$

The purpose is to zoom into $x=0$ while still showing $x = -600, x=600$. The function must be invertible and the inverse will be used about as frequently as the function itself, due to the way that matplotlib is written.

The two candidates I thought of are a cubic and a tangent. The cubic implementation is

$$ y = a x^3 + b x , b > 0$$ $$ a = \frac {s - 100} {s(600^2 - s^2)} $$ $$ b = 1 - 600^2 a $$

where $s$ is a scaling parameter, interpreted as the value of $x$ where $y = 100$.

This works well enough; here is a $1 - \left| \frac x {600} \right|$ triangle shown with this horizontal zoom for $s = 320$:

abs demo

This formulation has two big disadvantages:

  • Values of $s > 330$ are not possible without making $b < 0$, in turn giving the curve undesired inflection points
  • The inverse $x(y)$ is truly monstrous and I won't include it here unless requested

Is there a different function that will meet these requirements but is more easily invertible?

2

There are 2 best solutions below

0
On BEST ANSWER

An easy way to get what you're looking for is using the equation for the motion of a particle in a velocity field, $v$:

$\dot x(t) = v(x(t))$

In your case, $x(t)$ is $y$, $x(0)$ is $x$, and $t$ is $s$. Rewriting with these variable names,

$\dot y(s) = v(y(s))$

$y(0) = x$

This will produce smooth uniform zooming, moving the view of the original function at the same rate, no matter what the value of $s$ is. It is a first order ODE, so $y(x)$ is guaranteed to be invertible. Where $v=0$, the velocity is zero and the action is stationary. Where $\frac{dv}{dx} > 0$, the effect will be a zoom inward, and vice versa with $\frac{dv}{dx} < 0$. So, it is very easy to control the zoom using $v$. This also is a very easy ODE to solve, with a judicious choice of $v$.

First, let's just scale the problem from $\pm600$ to $\pm1$. It is trivial to scale the problem back again afterward. If you choose $v(x) = \frac 1 2 x(1 - x)(1 + x)$, you get the desired zooming in at $x=0$, while keeping $x=0$, $x=1$, and $x=-1$ stationary, as required. (The factor of 1/2 is there to simplify the math.) Math, math, math, and

$$y(x, s) = \frac x {\sqrt{e^{-s} + (1 - e^{-s}) x^2}}$$

Well, that's a pretty function! In $x$, it's just a straight line divided by a hyperbola!

There are other choices of $v$ that give similar results. $v(x) = \sin(\frac \tau 2 x)$ should work, though the integral may be messier. $v(x) = x(1 - |x|)$ will give even simpler results than the cubic I just did—a tanh function will result from it—but the zooming may be more unnatural because of the singularity in $v$ at $x=0$.

0
On

Well, the best I've found so far is neither $\tan$ nor cubic, but a piecewise hyperbola; with a scaling parameter $a$ the following applies to the right half of the domain, with the left half mirrored:

$$a = 1 \times 10^{-5} $$ $$b = \frac {600a + \sqrt{600^2 a^2 + 4a}} 2 $$ $$y = \frac 1 {b - ax} - \frac 1 b $$

This is trivially invertible and does not have the same scaling parameter limit as the cubic.