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