rational ordering of vectors

20 Views Asked by At

I have some vectors $v_i = (x_i, y_i) \in \mathbb{Z}^2$ in the plane. I would like to sort them in "clockwise" order, i.e. $v_i > v_j$ if the angle $\theta_i$ between $(1,0)$ and $v_i$ is greater than that between $(1,0)$ and $v_j$, measured by starting at $(0,1)$ and sweeping clockwise.

The problem is that $\theta_i$ is not so simple to compute exactly for arbitrary $v_i$. I would like a rational function $f(v):\mathbb{Z}^2\to \mathbb{Q}$ with $f(v_i) > f(v_j)$ if and only if $\theta_i > \theta_j$. (It doesn't bother me if $f$ is only defined on $\mathbb{Z}^2$ minus a finite set of points, such as $(0,0)$ and/or $(1,0)$).

My best attempt so far is to compute the half-angle tangent: $$f(v_i) = \tan \frac{\theta_i-\pi}{2} = \frac{y_i}{\sqrt{x_i^2+y_i^2}-x_i}$$ but it still requires computing that square root. Does there exist a pleasant rational $f$?

1

There are 1 best solutions below

0
On

A piece-wise function will do.

For $0$ to $\frac{\pi}{4}$, use $\frac{y-x}{x}$, so it is an increasing function with range from $-1$ to $0$.

For $\frac{\pi}{4}$ to $\frac{\pi}{2}$, use $\frac{y-x}{y}$, so it is an increasing function with range from $0$ to $1$.

Similar things can be done for the remaining 6 parts of the plane. You may need to add some constants here and there.

One example is

$$ f(v) = \left\{ \begin{array}{lr} \frac{y-x}{x} & 0<\theta<\pi/4 & -1<f(v)<0\\ \frac{y-x}{y} & \pi/4<\theta<3\pi/4 & 0<f(v)<2\\ \frac{y-x}{x}+4 & 3\pi/4<\theta<5\pi/4 & 2<f(v)<4\\ \frac{y-x}{y}+4 & 5\pi/4<\theta<7\pi/4 & 4<f(v)<6\\ \frac{y-x}{x}+8 & 7\pi/4<\theta<2\pi & 6<f(v)<7\\ \end{array} \right. $$

If you want a single-line function, you can add in what I call "checker": a factor of the form $\frac12\times\left(\frac{|x|}{x}+1\right)$ gives you $1$ when $x$ is positive and $0$ when $x$ is negative. Similar checkers can be constructed for different conditions of the sign of $x$ and $y$ or $x-y$. Multiplying each part of the stepwise function to a correct combination of checkers and add them up will give you a single-line function that does the same thing.