# Hyperbola in terms of its asymptote slopes and semi-major axis¶

Mauro Werder 2016-03-31

I was looking for the function of one branch of a generally oriented hyperbola to use as a function which smoothly transitions between two linear functions (continous). Alas, either this is not to be found on the internet or my search-foo failed me. Now it's written down here for the next person to find. I show two approaches, the first entails a bit more algebra and uses the semi-major axis as a parameter, the second uses the abcissa as parameter instead.

Note that there are other ways to make a smooth transition, even between discontinous functions, e.g. using sigmoid functions.

This notebook can be downloaded here, you need to run it yourself to use the interactive features.

## Using slopes and semi-major axis¶

The general equation for a conic section centered at the origin is

$$Ax^2 + 2Bxy + Cy^2 + 1 = 0$$

(refer to Wikipedia). It is a hyperbola if $D=AC-B^2<0$. Above equation can be solved for y $$y(x) = \frac{-Bx \pm \sqrt{-D x^2-C}}{C},$$ which gives the two branches of the hyperbola.

However, instead of the coefficients A, B and C, I want the formula in terms of the slopes of the asymptotes (s1, s2) and the semi-major axis a (i.e. the closest distance to the origin). The slopes are given by $$s_{1/2} = \frac{-B \pm \sqrt{-D}}{C}$$

and a is given by (see Wikipedia)

$$a^2 = -\frac{1}{\lambda_1} = -\frac{2}{A+C - \sqrt{(A+C)^2 - 4D}}$$

These equations can be solved for A, B, C (and D):

$$A = \sqrt{-D} \alpha, \quad B = \sqrt{-D} \beta, \quad C = \sqrt{-D} \gamma$$

with $\gamma=2/(s_1-_s2), \quad \beta = (s_2+s_1)/(s_2-s_1), \quad \alpha = - (1-b^2)/c$ and

$$D = - \frac{4}{a^4 \big( \alpha + \gamma - \sqrt{(\alpha+\gamma)^2 +4} \big)^2}$$

Now I got everything for the desired hyperbola function, implemented below:

In [1]:
"""
One branch of a hyperbola as a function of x given by

- s1: asymptote slope for x<0
- s2: asymptote slope for x>0
- a: semi major axis, i.e. minimum distance from the origin
- optionally shift the origin by xoff, yoff
"""
function hyperbola(x, s1, s2, a, xoff=0.0, yoff=0.0)
x = x-xoff
# Deal with degenerate cases and select the right branch of the hyperbola
if a==0 # return two lines
i1 = x.<0
i2 = x.>=0
return vcat(s1*x[i1], s2*x[i2]) + yoff
elseif s1==s2 # return one line
return collect(s1*x + yoff) # collect to make it type stable
elseif s1>s2
branch = +1
s1,s2 = s2,s1
else
branch = -1
end
γ = 2/(s1-s2)
β = (s2+s1)/(s2-s1)
α = - (1- β^2)/γ
D = - 4 / ( a^2 *( α + γ - sqrt((α+γ)^2 +4)) )^2
@assert D<0
C = sqrt(-D) * γ
B = sqrt(-D) * β
A = sqrt(-D) * α
@assert isapprox(D, A*C-B^2)
return (-B*x + branch * sqrt(x.^2*(B^2-A*C) - C))/C + yoff
end;

In [5]:
using Reactive, Interact, Plots # make an interactive graphic
gr(size=(600,600)) # use GR.jl, much faster than PyPlot

dx = 0.05
x = -5:dx:5
@manipulate for s1=-6:0.1:5, s2=-5:0.1:5.5, a=0.0:0.05:1.5, xoff=-1:0.1:1, yoff=-1:0.1:1
x1 = -5:dx:xoff
x2 = xoff:dx:5
plot(x, hyperbola(x, s1, s2, a, xoff, yoff), label="hyperbola", w=3)
plot!(x1, (x1-xoff)*s1+yoff, label="s1", w=2)
plot!(x2, (x2-xoff)*s2+yoff, label="s2", xlims=(-5,5), ylims=(-5,5), w=2)
end

Out[5]:

## Using slopes and abcissa¶

Much easier is using the abcissa at x=0. Use the ansatz (note A,C, and D are different from above):

$$y(x) = Bx + \sqrt{-Dx^2-C}$$

with $D<0, C<0$. This gives the slopes

$$s_{1/2} = B\mp \sqrt{-D}$$

and absolute value of abcissa at $x=0$

$$\Delta y = \sqrt{-C}$$

solving for B, C, D

$$B = \frac{s_1+s_2}{2}, \quad D=\frac{(s_2-s_1)^2}{4}, \quad C = -\Delta y^2$$

Implemented below, also taking care to select the right hyperbola branche and of degenerate cases:

In [3]:
"""
One branch of a hyperbola as a function of x given by

- s1: asymptote slope for x<0
- s2: asymptote slope for x>0
- Δy: absolute value of abcissa at x=0
- optionally shift the origin by xoff, yoff
"""
function hyperbola2(x, s1, s2, Δy, xoff=0.0, yoff=0.0)
x = x-xoff
# Deal with degenerate cases and select the right branch of the hyperbola
if Δy==0 # return two lines
i1 = x.<0
i2 = x.>=0
return vcat(s1*x[i1], s2*x[i2]) + yoff
elseif s1==s2 # return one line
branch = 0
elseif s1>s2
branch = -1
s1,s2 = s2,s1
else
branch = +1
end
B = (s1+s2)/2
C = -Δy^2
D = - (s2-s1)^2/4
return B*x + branch * sqrt(-D*x.^2-C) + yoff
end;

In [4]:
@manipulate for s1=-6:0.1:5, s2=-5:0.1:5.5, Δy=0:0.05:1.5, xoff=-1:0.1:1, yoff=-1:0.1:1
x1 = -5:dx:xoff
x2 = xoff:dx:5
plot(x, hyperbola2(x, s1, s2, Δy, xoff, yoff), label="hyperbola", w=3)
plot!(x1, (x1-xoff)*s1+yoff, label="s1", w=2)
plot!(x2, (x2-xoff)*s2+yoff, label="s2", xlims=(-5,5), ylims=(-5,5), w=2)
plot!([xoff,xoff], sign(s2-s1)*[yoff, yoff+Δy], label="\\Delta y", w=2)
end

Out[4]:
In [ ]: