1cb93a386Sopenharmony_ci---
2cb93a386Sopenharmony_cititle: 'Two-point Conical Gradient'
3cb93a386Sopenharmony_cilinkTitle: 'Two-point Conical Gradient'
4cb93a386Sopenharmony_ci---
5cb93a386Sopenharmony_ci
6cb93a386Sopenharmony_ci<script type="text/x-mathjax-config">
7cb93a386Sopenharmony_ciMathJax.Hub.Config({
8cb93a386Sopenharmony_ci    tex2jax: {
9cb93a386Sopenharmony_ci        inlineMath: [['$','$'], ['\\(','\\)']]
10cb93a386Sopenharmony_ci    }
11cb93a386Sopenharmony_ci});
12cb93a386Sopenharmony_ci</script>
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ci<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML'></script>
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci(Please refresh the page if you see a lot of dollars instead of math symbols.)
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ciWe present a fast shading algorithm (compared to bruteforcely solving the
19cb93a386Sopenharmony_ciquadratic equation of gradient $t$) for computing the two-point conical gradient
20cb93a386Sopenharmony_ci(i.e., `createRadialGradient` in
21cb93a386Sopenharmony_ci[spec](https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-createradialgradient)).
22cb93a386Sopenharmony_ciIt reduced the number of multiplications per pixel from ~10 down to 3, and
23cb93a386Sopenharmony_cibrought a speedup of up to 26% in our nanobenches.
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ciThis document has 3 parts:
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ci1. Problem Statement and Setup
28cb93a386Sopenharmony_ci2. Algorithm
29cb93a386Sopenharmony_ci3. Appendix
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ciPart 1 and 2 are self-explanatory. Part 3 shows how to geometrically proves our
32cb93a386Sopenharmony_ciTheorem 1 in part 2; it's more complicated but it gives us a nice picture about
33cb93a386Sopenharmony_ciwhat's going on.
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci## Problem Statement and Setup
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ciLet two circles be $C_0, r_0$ and $C_1, r_1$ where $C$ is the center and $r$ is
38cb93a386Sopenharmony_cithe radius. For any point $P = (x, y)$ we want the shader to quickly compute a
39cb93a386Sopenharmony_cigradient $t \in \mathbb R$ such that $p$ is on the linearly interpolated circle
40cb93a386Sopenharmony_ciwith center $C_t = (1-t) \cdot C_0 + t \cdot C_1$ and radius
41cb93a386Sopenharmony_ci$r_t = (1-t) \cdot r_0 + t \cdot r_1 > 0$ (note that radius $r_t$ has to be
42cb93a386Sopenharmony_ci_positive_). If there are multiple (at most 2) solutions of $t$, choose the
43cb93a386Sopenharmony_cibigger one.
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ciThere are two degenerated cases:
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci1. $C_0 = C_1$ so the gradient is essentially a simple radial gradient.
48cb93a386Sopenharmony_ci2. $r_0 = r_1$ so the gradient is a single strip with bandwidth $2 r_0 = 2 r_1$.
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci<!-- TODO maybe add some fiddle or images here to illustrate the two degenerated cases -->
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ciThey are easy to handle so we won't cover them here. From now on, we assume
53cb93a386Sopenharmony_ci$C_0 \neq C_1$ and $r_0
54cb93a386Sopenharmony_ci\neq r_1$.
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ciAs $r_0 \neq r_1$, we can find a focal point
57cb93a386Sopenharmony_ci$C_f = (1-f) \cdot C_0 + f \cdot C_1$ where its corresponding linearly
58cb93a386Sopenharmony_ciinterpolated radius $r_f = (1-f) \cdot r_0 + f \cdot r_1 = 0$. Solving the
59cb93a386Sopenharmony_cilatter equation gets us $f = r_0 / (r_0 - r_1)$.
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ciAs $C_0 \neq C_1$, focal point $C_f$ is different from $C_1$ unless $r_1 = 0$.
62cb93a386Sopenharmony_ciIf $r_1 = 0$, we can swap $C_0, r_0$ with $C_1, r_1$, compute swapped gradient
63cb93a386Sopenharmony_ci$t_s$ as if $r_1 \neq 0$, and finally set $t = 1 - t_s$. The only catch here is
64cb93a386Sopenharmony_cithat with multiple solutions of $t_s$, we shall choose the smaller one (so $t$
65cb93a386Sopenharmony_cicould be the bigger one).
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ciAssuming that we've done swapping if necessary so $C_1 \neq C_f$, we can then do
68cb93a386Sopenharmony_cia linear transformation to map $C_f, C_1$ to $(0, 0), (1, 0)$. After the
69cb93a386Sopenharmony_citransformation:
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci1. All centers $C_t = (x_t, 0)$ must be on the $x$ axis
72cb93a386Sopenharmony_ci2. The radius $r_t$ is $x_t r_1$.
73cb93a386Sopenharmony_ci3. Given $x_t$ , we can derive $t = f + (1 - f) x_t$
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ciFrom now on, we'll focus on how to quickly computes $x_t$. Note that $r_t > 0$
76cb93a386Sopenharmony_ciso we're only interested positive solution $x_t$. Again, if there are multiple
77cb93a386Sopenharmony_ci$x_t$ solutions, we may want to find the bigger one if $1 - f > 0$, and smaller
78cb93a386Sopenharmony_cione if $1 - f < 0$, so the corresponding $t$ is always the bigger one (note that
79cb93a386Sopenharmony_ci$f \neq 1$, otherwise we'll swap $C_0, r_0$ with $C_1, r_1$).
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ci## Algorithm
82cb93a386Sopenharmony_ci
83cb93a386Sopenharmony_ci**Theorem 1.** The solution to $x_t$ is
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci1. $\frac{x^2 + y^2}{(1 + r_1) x} = \frac{x^2 + y^2}{2 x}$ if $r_1 = 1$
86cb93a386Sopenharmony_ci2. $\left(\sqrt{(r_1^2 - 1) y ^2 + r_1^2 x^2}  - x\right) / (r_1^2 - 1)$ if
87cb93a386Sopenharmony_ci   $r_1 > 1$
88cb93a386Sopenharmony_ci3. $\left(\pm \sqrt{(r_1^2 - 1) y ^2 + r_1^2 x^2}  - x\right) / (r_1^2 - 1)$ if
89cb93a386Sopenharmony_ci   $r_1 < 1$.
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ciCase 2 always produces a valid $x_t$. Case 1 and 3 requires $x > 0$ to produce
92cb93a386Sopenharmony_civalid $x_t > 0$. Case 3 may have no solution at all if
93cb93a386Sopenharmony_ci$(r_1^2 - 1) y^2 + r_1^2 x^2 < 0$.
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci_Proof._ Algebriacally, solving the quadratic equation
96cb93a386Sopenharmony_ci$(x_t - x)^2 + y^2 = (x_t r_1)^2$ and eliminate negative $x_t$ solutions get us
97cb93a386Sopenharmony_cithe theorem.
98cb93a386Sopenharmony_ci
99cb93a386Sopenharmony_ciAlternatively, we can also combine Corollary 2., 3., and Lemma 4. in the
100cb93a386Sopenharmony_ciAppendix to geometrically prove the theorem. $\square$
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ciTheorem 1 by itself is not sufficient for our shader algorithm because:
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci1. we still need to compute $t$ from $x_t$ (remember that $t = f + (1-f) x_t$);
105cb93a386Sopenharmony_ci2. we still need to handle cases of choosing the bigger/smaller $x_t$;
106cb93a386Sopenharmony_ci3. we still need to handle the swapped case (we swap $C_0, r_0$ with $C_1, r_1$
107cb93a386Sopenharmony_ci   if $r_1 = 0$);
108cb93a386Sopenharmony_ci4. there are way too many multiplications and divisions in Theorem 1 that would
109cb93a386Sopenharmony_ci   slow our shader.
110cb93a386Sopenharmony_ci
111cb93a386Sopenharmony_ciIssue 2 and 3 are solved by generating different shader code based on different
112cb93a386Sopenharmony_cisituations. So they are mainly correctness issues rather than performance
113cb93a386Sopenharmony_ciissues. Issue 1 and 4 are performance critical, and they will affect how we
114cb93a386Sopenharmony_cihandle issue 2 and 3.
115cb93a386Sopenharmony_ci
116cb93a386Sopenharmony_ciThe key to handle 1 and 4 efficiently is to fold as many multiplications and
117cb93a386Sopenharmony_cidivisions into the linear transformation matrix, which the shader has to do
118cb93a386Sopenharmony_cianyway (remember our linear transformation to map $C_f, C_1$ to
119cb93a386Sopenharmony_ci$(0, 0), (1, 0)$).
120cb93a386Sopenharmony_ci
121cb93a386Sopenharmony_ciFor example, let $\hat x, \hat y = |1-f|x, |1-f|y$. Computing $\hat x_t$ with
122cb93a386Sopenharmony_cirespect to $\hat x,
123cb93a386Sopenharmony_ci\hat y$ allow us to have
124cb93a386Sopenharmony_ci$t = f + (1 - f)x_t = f + \text{sign}(1-f) \cdot \hat x_t$. That saves us one
125cb93a386Sopenharmony_cimultiplication. Applying similar techniques to Theorem 1 gets us:
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ci1. If $r_1 = 1$, let $x' = x/2,~ y' = y/2$, then $x_t = (x'^2 + y'^2) / x'$.
128cb93a386Sopenharmony_ci2. If $r_1 > 1$, let
129cb93a386Sopenharmony_ci   $x' = r_1 / (r_1^2 - 1) x,~ y' = \frac{\sqrt{r_1^2 - 1}}{r_1^2 - 1} y$, then
130cb93a386Sopenharmony_ci   $x_t = \sqrt{x'^2 + y'^2} - x' / r_1$
131cb93a386Sopenharmony_ci3. If $r_1 < 1$, let
132cb93a386Sopenharmony_ci   $x' = r_1 / (r_1^2 - 1) x,~ y' = \frac{\sqrt{1 - r_1^2}}{r_1^2 - 1} y$, then
133cb93a386Sopenharmony_ci   $x_t = \pm\sqrt{x'^2 - y'^2} - x' / r_1$
134cb93a386Sopenharmony_ci
135cb93a386Sopenharmony_ciCombining it with the swapping, the equation $t = f + (1-f) x_t$, and the fact
136cb93a386Sopenharmony_cithat we only want positive $x_t > 0$ and bigger $t$, we have our final
137cb93a386Sopenharmony_cialgorithm:
138cb93a386Sopenharmony_ci
139cb93a386Sopenharmony_ci**Algorithm 1.**
140cb93a386Sopenharmony_ci
141cb93a386Sopenharmony_ci1. Let $C'_0, r'_0, C'_1, r'_1 = C_0, r_0, C_1, r_1$ if there is no swapping and
142cb93a386Sopenharmony_ci   $C'_0,
143cb93a386Sopenharmony_ci    r'_0, C'_1, r'_1 = C_1, r_1, C_0, r_0$ if there is swapping.
144cb93a386Sopenharmony_ci2. Let $f = r'_0 / (r'_0 - r'_1)$ and $1 - f = r'_1 / (r'_1 - r'_0)$
145cb93a386Sopenharmony_ci3. Let $x' = x/2,~ y' = y/2$ if $r_1 = 1$, and
146cb93a386Sopenharmony_ci   $x' = r_1 / (r_1^2 - 1) x,~ y' = \sqrt{|r_1^2 - 1|} / (r_1^2 - 1) y$ if
147cb93a386Sopenharmony_ci   $r_1 \neq 1$
148cb93a386Sopenharmony_ci4. Let $\hat x = |1 - f|x', \hat y = |1 - f|y'$
149cb93a386Sopenharmony_ci5. If $r_1 = 1$, let $\hat x_t = (\hat x^2 + \hat y^2) / \hat x$
150cb93a386Sopenharmony_ci6. If $r_1 > 1$, let $\hat x_t = \sqrt{\hat x^2 + \hat y^2} - \hat x / r_1$
151cb93a386Sopenharmony_ci7. If $r_1 < 1$
152cb93a386Sopenharmony_ci8. return invalid if $\hat x^2 - \hat y^2 < 0$
153cb93a386Sopenharmony_ci9. let $\hat x_t =  -\sqrt{\hat x^2 - \hat y^2} - \hat x / r_1$ if we've swapped
154cb93a386Sopenharmony_ci   $r_0, r_1$, or if $1 - f < 0$
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ci10. let $\hat x_t =  \sqrt{\hat x^2 - \hat y^2} - \hat x / r_1$ otherwise
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci11. $t$ is invalid if $\hat x_t < 0$ (this check is unnecessary if $r_1 > 1$)
159cb93a386Sopenharmony_ci12. Let $t = f + \text{sign}(1 - f) \hat x_t$
160cb93a386Sopenharmony_ci13. If swapped, let $t = 1 - t$
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ciIn step 7, we try to select either the smaller or bigger $\hat x_t$ based on
163cb93a386Sopenharmony_ciwhether the final $t$ has a negative or positive relationship with $\hat x_t$.
164cb93a386Sopenharmony_ciIt's negative if we've swapped, or if $\text{sign}(1 - f)$ is negative (these
165cb93a386Sopenharmony_citwo cannot both happen).
166cb93a386Sopenharmony_ci
167cb93a386Sopenharmony_ciNote that all the computations and if decisions not involving $\hat x, \hat y$
168cb93a386Sopenharmony_cican be precomputed before the shading stage. The two if decisions
169cb93a386Sopenharmony_ci$\hat x^2 - \hat y^2 < 0$ and $\hat x^t < 0$ can also be omitted by precomputing
170cb93a386Sopenharmony_cithe shading area that never violates those conditions.
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ciThe number of operations per shading is thus:
173cb93a386Sopenharmony_ci
174cb93a386Sopenharmony_ci- 1 addition, 2 multiplications, and 1 division if $r_1 = 1$
175cb93a386Sopenharmony_ci- 2 additions, 3 multiplications, and 1 sqrt for $r_1 \neq 1$ (count subtraction
176cb93a386Sopenharmony_ci  as addition; dividing $r_1$ is multiplying $1/r_1$)
177cb93a386Sopenharmony_ci- 1 more addition operation if $f \neq 0$
178cb93a386Sopenharmony_ci- 1 more addition operation if swapped.
179cb93a386Sopenharmony_ci
180cb93a386Sopenharmony_ciIn comparison, for $r_1 \neq 1$ case, our current raster pipeline shading
181cb93a386Sopenharmony_cialgorithm (which shall hopefully soon be upgraded to the algorithm described
182cb93a386Sopenharmony_cihere) mainly uses formula
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci$$
185cb93a386Sopenharmony_cit = 0.5 \cdot
186cb93a386Sopenharmony_ci(1/a) \cdot \left(-b \pm \sqrt{b^2 - 4ac}\right)$$ It precomputes
187cb93a386Sopenharmony_ci$a = 1 - (r_1 - r_0)^2, 1/a, r1 -
188cb93a386Sopenharmony_cir0$. Number
189cb93a386Sopenharmony_ci$b = -2 \cdot (x + (r1 - r0) \cdot r0)$ costs 2 multiplications and 1 addition.
190cb93a386Sopenharmony_ciNumber $c = x^2 + y^2 - r_0^2$ costs 3 multiplications and 2 additions. And the
191cb93a386Sopenharmony_cifinal $t$ costs 5 more multiplications, 1 more sqrt, and 2 more additions.
192cb93a386Sopenharmony_ciThat's a total of 5 additions, 10 multiplications, and 1 sqrt. (Our algorithm
193cb93a386Sopenharmony_cihas 2-4 additions, 3 multiplications, and 1 sqrt.) Even if it saves the
194cb93a386Sopenharmony_ci$0.5 \cdot (1/a), 4a, r_0^2$ and $(r_1 - r_0) r_0$ multiplications, there are
195cb93a386Sopenharmony_cistill 6 multiplications. Moreover, it sends in 4 unitofmrs to the shader while
196cb93a386Sopenharmony_ciour algorithm only needs 2 uniforms ($1/r_1$ and $f$).
197cb93a386Sopenharmony_ci
198cb93a386Sopenharmony_ci## Appendix
199cb93a386Sopenharmony_ci
200cb93a386Sopenharmony_ci**Lemma 1.** Draw a ray from $C_f = (0, 0)$ to $P = (x, y)$. For every
201cb93a386Sopenharmony_ciintersection points $P_1$ between that ray and circle $C_1 = (1, 0), r_1$, there
202cb93a386Sopenharmony_ciexists an $x_t$ that equals to the length of segment $C_f P$ over length of
203cb93a386Sopenharmony_cisegment $C_f P_1$. That is, $x_t = || C_f P || / ||C_f P_1||$
204cb93a386Sopenharmony_ci
205cb93a386Sopenharmony_ci_Proof._ Draw a line from $P$ that's parallel to $C_1 P_1$. Let it intersect
206cb93a386Sopenharmony_ciwith $x$-axis on point $C = (x', y')$.
207cb93a386Sopenharmony_ci
208cb93a386Sopenharmony_ci<img src="./lemma1.svg"/>
209cb93a386Sopenharmony_ci
210cb93a386Sopenharmony_ciTriangle $\triangle C_f C P$ is similar to triangle $\triangle C_f C_1 P_1$.
211cb93a386Sopenharmony_ciTherefore $||P C|| = ||P_1 C_1|| \cdot (||C_f C|| / ||C_f C_1||) = r_1 x'$. Thus
212cb93a386Sopenharmony_ci$x'$ is a solution to $x_t$. Because triangle $\triangle C_f C P$ and triangle
213cb93a386Sopenharmony_ci$\triangle C_f C_1 P_1$ are similar,
214cb93a386Sopenharmony_ci$x'
215cb93a386Sopenharmony_ci= ||C_f C_1|| \cdot (||C_f P|| / ||C_f P_1||) = ||C_f P|| / ||C_f P_1||$.
216cb93a386Sopenharmony_ci$\square$
217cb93a386Sopenharmony_ci
218cb93a386Sopenharmony_ci**Lemma 2.** For every solution $x_t$, if we extend/shrink segment $C_f P$ to
219cb93a386Sopenharmony_ci$C_f P_1$ with ratio $1 / x_t$ (i.e., find $P_1$ on ray $C_f P$ such that
220cb93a386Sopenharmony_ci$||C_f P_1|| / ||C_f P|| = 1 / x_t$), then $P_1$ must be on circle $C_1, r_1$.
221cb93a386Sopenharmony_ci
222cb93a386Sopenharmony_ci_Proof._ Let $C_t = (x_t, 0)$. Triangle $\triangle C_f C_t P$ is similar to
223cb93a386Sopenharmony_ci$C_f C_1 P_1$. Therefore $||C_1 P_1|| = r_1$ and $P_1$ is on circle $C_1, r_1$.
224cb93a386Sopenharmony_ci$\square$
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ci**Corollary 1.** By lemma 1. and 2., we conclude that the number of solutions
227cb93a386Sopenharmony_ci$x_t$ is equal to the number of intersections between ray $C_f P$ and circle
228cb93a386Sopenharmony_ci$C_1, r_1$. Therefore
229cb93a386Sopenharmony_ci
230cb93a386Sopenharmony_ci- when $r_1 > 1$, there's always one unique intersection/solution; we call this
231cb93a386Sopenharmony_ci  "well-behaved"; this was previously known as the "inside" case;
232cb93a386Sopenharmony_ci- when $r_1 = 1$, there's either one or zero intersection/solution (excluding
233cb93a386Sopenharmony_ci  $C_f$ which is always on the circle); we call this "focal-on-circle"; this was
234cb93a386Sopenharmony_ci  previously known as the "edge" case;
235cb93a386Sopenharmony_ci
236cb93a386Sopenharmony_ci<img src="./corollary2.2.1.svg"/>
237cb93a386Sopenharmony_ci<img src="./corollary2.2.2.svg"/>
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_ci- when $r_1 < 1$, there may be $0, 1$, or $2$ solutions; this was also
240cb93a386Sopenharmony_ci  previously as the "outside" case.
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ci<img src="./corollary2.3.1.svg" width="30%"/>
243cb93a386Sopenharmony_ci<img src="./corollary2.3.2.svg" width="30%"/>
244cb93a386Sopenharmony_ci<img src="./corollary2.3.3.svg" width="30%"/>
245cb93a386Sopenharmony_ci
246cb93a386Sopenharmony_ci**Lemma 3.** When solution exists, one such solution is
247cb93a386Sopenharmony_ci
248cb93a386Sopenharmony_ci
249cb93a386Sopenharmony_ci$$
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    x_t = {|| C_f P || \over ||C_f P_1||} = \frac{x^2 + y^2}{x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci$$
254cb93a386Sopenharmony_ci
255cb93a386Sopenharmony_ci_Proof._ As $C_f = (0, 0), P = (x, y)$, we have $||C_f P|| = \sqrt(x^2 + y^2)$.
256cb93a386Sopenharmony_ciSo we'll mainly focus on how to compute $||C_f P_1||$.
257cb93a386Sopenharmony_ci
258cb93a386Sopenharmony_ci**When $x \geq 0$:**
259cb93a386Sopenharmony_ci
260cb93a386Sopenharmony_ci<img src="./lemma3.1.svg"/>
261cb93a386Sopenharmony_ci
262cb93a386Sopenharmony_ciLet $X_P = (x, 0)$ and $H$ be a point on $C_f P_1$ such that $C_1 H$ is
263cb93a386Sopenharmony_ciperpendicular to $C_1
264cb93a386Sopenharmony_ciP_1$. Triangle $\triangle C_1 H C_f$ is similar to triangle
265cb93a386Sopenharmony_ci$\triangle P X_P C_f$. Thus
266cb93a386Sopenharmony_ci$$||C_f H|| = ||C_f C_1|| \cdot (||C_f X_P|| / ||C_f P||) = x / \sqrt{x^2 + y^2}$$
267cb93a386Sopenharmony_ci$$||C_1 H|| = ||C_f C_1|| \cdot (||P X_P|| / ||C_f P||) = y / \sqrt{x^2 + y^2}$$
268cb93a386Sopenharmony_ci
269cb93a386Sopenharmony_ciTriangle $\triangle C_1 H P_1$ is a right triangle with hypotenuse $r_1$. Hence
270cb93a386Sopenharmony_ci$$ ||H P_1|| = \sqrt{r_1^2 - ||C_1 H||^2} = \sqrt{r_1^2 - y^2 / (x^2 + y^2)} $$
271cb93a386Sopenharmony_ci
272cb93a386Sopenharmony_ciWe have \begin{align} ||C_f P_1|| &= ||C_f H|| + ||H P_1|| \\\\\\ &= x /
273cb93a386Sopenharmony_ci\sqrt{x^2 + y^2} + \sqrt{r_1^2 - y^2 / (x^2 + y^2)} \\\\\\ &= \frac{x +
274cb93a386Sopenharmony_ci\sqrt{r_1^2 (x^2 + y^2) - y^2}}{\sqrt{x^2 + y^2}} \\\\\\ &= \frac{x +
275cb93a386Sopenharmony_ci\sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}{\sqrt{x^2 + y^2}} \end{align}
276cb93a386Sopenharmony_ci
277cb93a386Sopenharmony_ci**When $x < 0$:**
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ciDefine $X_P$ and $H$ similarly as before except that now $H$ is on ray $P_1 C_f$
280cb93a386Sopenharmony_ciinstead of $C_f P_1$.
281cb93a386Sopenharmony_ci
282cb93a386Sopenharmony_ci<img src="./lemma3.2.svg"/>
283cb93a386Sopenharmony_ci
284cb93a386Sopenharmony_ciAs before, triangle $\triangle C_1 H C_f$ is similar to triangle
285cb93a386Sopenharmony_ci$\triangle P X_P C_f$, and triangle $\triangle C_1 H P_1$ is a right triangle,
286cb93a386Sopenharmony_ciso we have
287cb93a386Sopenharmony_ci$$||C_f H|| = ||C_f C_1|| \cdot (||C_f X_P|| / ||C_f P||) = -x / \sqrt{x^2 + y^2}$$
288cb93a386Sopenharmony_ci$$||C_1 H|| = ||C_f C_1|| \cdot (||P X_P|| / ||C_f P||) = y / \sqrt{x^2 + y^2}$$
289cb93a386Sopenharmony_ci$$ ||H P_1|| = \sqrt{r_1^2 - ||C_1 H||^2} = \sqrt{r_1^2 - y^2 / (x^2 + y^2)} $$
290cb93a386Sopenharmony_ci
291cb93a386Sopenharmony_ciNote that the only difference is changing $x$ to $-x$ because $x$ is negative.
292cb93a386Sopenharmony_ci
293cb93a386Sopenharmony_ciAlso note that now $||C_f P_1|| = -||C_f H|| + ||H P_1||$ and we have
294cb93a386Sopenharmony_ci$-||C_f H||$ instead of $||C_f H||$. That negation cancels out the negation of
295cb93a386Sopenharmony_ci$-x$ so we get the same equation of $||C_f P_1||$ for both $x \geq 0$ and
296cb93a386Sopenharmony_ci$x < 0$ cases:
297cb93a386Sopenharmony_ci
298cb93a386Sopenharmony_ci
299cb93a386Sopenharmony_ci$$
300cb93a386Sopenharmony_ci
301cb93a386Sopenharmony_ci    ||C_f P_1|| = \frac{x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}{\sqrt{x^2 + y^2}}
302cb93a386Sopenharmony_ci
303cb93a386Sopenharmony_ci$$
304cb93a386Sopenharmony_ci
305cb93a386Sopenharmony_ciFinally
306cb93a386Sopenharmony_ci
307cb93a386Sopenharmony_ci
308cb93a386Sopenharmony_ci$$
309cb93a386Sopenharmony_ci
310cb93a386Sopenharmony_ci    x_t = \frac{||C_f P||}{||C_f P_1||} = \frac{\sqrt{x^2 + y^2}}{||C_f P_1||}
311cb93a386Sopenharmony_ci        = \frac{x^2 + y^2}{x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}
312cb93a386Sopenharmony_ci
313cb93a386Sopenharmony_ci$$ $\square$
314cb93a386Sopenharmony_ci
315cb93a386Sopenharmony_ci**Corollary 2.** If $r_1 = 1$, then the solution
316cb93a386Sopenharmony_ci$x_t = \frac{x^2 + y^2}{(1 + r_1) x}$, and it's valid (i.e., $x_t > 0$) iff
317cb93a386Sopenharmony_ci$x > 0$.
318cb93a386Sopenharmony_ci
319cb93a386Sopenharmony_ci_Proof._ Simply plug $r_1 = 1$ into the formula of Lemma 3. $\square$
320cb93a386Sopenharmony_ci
321cb93a386Sopenharmony_ci**Corollary 3.** If $r_1 > 1$, then the unique solution is
322cb93a386Sopenharmony_ci$x_t = \left(\sqrt{(r_1^2 - 1) y ^2 + r_1^2 x^2}  - x\right) / (r_1^2 - 1)$.
323cb93a386Sopenharmony_ci
324cb93a386Sopenharmony_ci_Proof._ From Lemma 3., we have
325cb93a386Sopenharmony_ci
326cb93a386Sopenharmony_ci\begin{align} x_t &= \frac{x^2 + y^2}{x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}
327cb93a386Sopenharmony_ci\\\\\\ &= { (x^2 + y^2) \left ( -x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2} \right )
328cb93a386Sopenharmony_ci\over \left (x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2} \right ) \left (-x +
329cb93a386Sopenharmony_ci\sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2} \right ) } \\\\\\ &= { (x^2 + y^2) \left (
330cb93a386Sopenharmony_ci-x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2} \right ) \over -x^2 + (r_1^2 - 1) y^2 +
331cb93a386Sopenharmony_cir_1^2 x^2 } \\\\\\ &= { (x^2 + y^2) \left ( -x + \sqrt{(r_1^2 - 1) y^2 + r_1^2
332cb93a386Sopenharmony_cix^2} \right ) \over (r_1^2 - 1) (x^2 + y^2) } \\\\\\ &= \left(\sqrt{(r_1^2 - 1)
333cb93a386Sopenharmony_ciy ^2 + r_1^2 x^2} - x\right) / (r_1^2 - 1) \end{align}
334cb93a386Sopenharmony_ci
335cb93a386Sopenharmony_ciThe transformation above (multiplying $-x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}$
336cb93a386Sopenharmony_cito enumerator and denomenator) is always valid because $r_1 > 1$ and it's the
337cb93a386Sopenharmony_ciunique solution due to Corollary 1. $\square$
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_ci**Lemma 4.** If $r_1 < 1$, then
340cb93a386Sopenharmony_ci
341cb93a386Sopenharmony_ci1. there's no solution to $x_t$ if $(r_1^2 - 1) y^2 + r_1^2 x^2 < 0$
342cb93a386Sopenharmony_ci2. otherwise, the solutions are
343cb93a386Sopenharmony_ci   $x_t = \left(\sqrt{(r_1^2 - 1) y ^2 + r_1^2 x^2}  - x\right) / (r_1^2 - 1)$,
344cb93a386Sopenharmony_ci   or
345cb93a386Sopenharmony_ci   $x_t = \left(-\sqrt{(r_1^2 - 1) y ^2 + r_1^2 x^2}  - x\right) / (r_1^2 - 1)$.
346cb93a386Sopenharmony_ci
347cb93a386Sopenharmony_ci(Note that solution $x_t$ still has to be nonnegative to be valid; also note
348cb93a386Sopenharmony_cithat $x_t > 0 \Leftrightarrow x > 0$ if the solution exists.)
349cb93a386Sopenharmony_ci
350cb93a386Sopenharmony_ci_Proof._ Case 1 follows naturally from Lemma 3. and Corollary 1.
351cb93a386Sopenharmony_ci
352cb93a386Sopenharmony_ci<img src="./lemma4.svg"/>
353cb93a386Sopenharmony_ci
354cb93a386Sopenharmony_ciFor case 2, we notice that $||C_f P_1||$ could be
355cb93a386Sopenharmony_ci
356cb93a386Sopenharmony_ci1. either $||C_f H|| + ||H P_1||$ or $||C_f H|| - ||H P_1||$ if $x \geq 0$,
357cb93a386Sopenharmony_ci2. either $-||C_f H|| + ||H P_1||$ or $-||C_f H|| - ||H P_1||$ if $x < 0$.
358cb93a386Sopenharmony_ci
359cb93a386Sopenharmony_ciBy analysis similar to Lemma 3., the solution to $x_t$ does not depend on the
360cb93a386Sopenharmony_cisign of $x$ and they are either
361cb93a386Sopenharmony_ci$\frac{x^2 + y^2}{x + \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}$ or
362cb93a386Sopenharmony_ci$\frac{x^2 + y^2}{x - \sqrt{(r_1^2 - 1) y^2 + r_1^2 x^2}}$.
363cb93a386Sopenharmony_ci
364cb93a386Sopenharmony_ciAs $r_1 \neq 1$, we can apply the similar transformation in Corollary 3. to get
365cb93a386Sopenharmony_cithe two formula in the lemma. $\square$
366cb93a386Sopenharmony_ci
367cb93a386Sopenharmony_ci$$
368cb93a386Sopenharmony_ci$$
369