Search code examples
rggplot2complex-numbers

Draw ellpses in R with foci and eccentricity


I have n ellipses with foci and eccentricity. The coordinates are in complex format

<table>
<thead>
<tr>
<th>focus1</th>
<th>focus2</th>
<th>eccentricity</th>
</tr>
</thead>
<tbody>
<tr>
<td>0.04058774642776+0.492230980361489i</td>
<td>0.023005747265301+0.513567552038155i</td>
<td>0.979999999908804+0i</td>
</tr>
<tr>
<td>0.042509209111742+0.484534970821593i</td>
<td>0.02218800715139+0.527050799457565i</td>
<td>0.979999998540944+0i</td>
</tr>
</tbody>
</table> 

and so on.

How can I plot those ellipses in R?

Edit: My initial code is:

library(ggforce)
n = 2500
k <- 0
ellipses<- data.frame(focus1 = numeric(n), focus2 = numeric(n), ecc = numeric(n))
while ( k <= n) {
  F1_k <- ( -3/2)*((sin(2*pi*k/n))^3) + (3/10)*((sin(2*pi*k/n))^7) + (1i) * sin((2*pi*k/1875) + (pi/6)) + (1/4)*(sin((2*pi*k /1875) + (pi/6)))^3 + ((2/15) - (1/8)*cos(pi*k/625)* exp(68*pi*(1i)*k/n))
   F2_k <- ( -3/2)*((sin(2*pi*k/n))^3) + (3/10)*((sin(2*pi*k/n))^7) + (1i) * sin((2*pi*k/1875) + (pi/6)) + (1/4)*(sin((2*pi*k /1875) + (pi/6)))^3 - ((2/15) - (1/8)*cos(pi*k/625)* exp(68*pi*(1i)*k/n))
  D_k <- (49/50) - (1/7)*(sin(4*pi*k/n))^4
  ellipses[k, ] <- c(F1_k, F2_k,  D_k)
  k <- k + 1
}

I am new to R, so I know my code may be inefficient.


Solution

  • It can be done. But first, let's prepare a function that will generate an ellipse on the complex plane based on the arguments F1, F2 and e (focal length and eccentricity).

    fEllipse = function(F1, F2, e, n=100){
      F0 = (F1+F2)/2
      c = Mod(F2-F1)/2
      a = c/Mod(e)
      b = sqrt(a^2 - c^2)
      gamma = Arg(F2-F1)
      t = seq(0, 2*pi, length.out = n)
      F0+((a+b)/2)*exp(1i*(t+gamma))+((a-b)/2)*exp(-1i*(t-gamma))
    }
    

    Let's see if it works!

    fEllipse(0 + 5i, 5 + 0i, 0.95 + 0i, 10)
    # [1]  5.131579-0.131579i  5.044092+1.012279i  3.766196+2.852258i  1.895832+4.527411i  0.308166+5.253917i
    # [6] -0.253917+4.691834i  0.472589+3.104168i  2.147742+1.233804i  3.987721-0.044092i  5.131579-0.131579i
    

    Great. Now let's try to draw it

    tibble(Ellipse = fEllipse(0 + 5i, 5 + 0i, 0.95 + 0i)) %>% 
      ggplot(aes(Re(Ellipse), Im(Ellipse)))+
      geom_path()
    

    enter image description here

    Great. Now let's go a step further. Let's make a "tibble" with ten random ellipses and then draw them on the graph.

    set.seed(1234)
    nEllipses = 10
    df = tibble(
      id = paste("Ellipse", 1:nEllipses) %>% fct_inorder(),
      F1 = runif(nEllipses, -10, 10) + runif(nEllipses, -10, 10)*1i,
      F2 = runif(nEllipses, -10, 10) + runif(nEllipses, -10, 10)*1i,
      e = runif(nEllipses, 0.7, 0.999) + 0i
    ) %>% group_by(id) %>% 
      nest() %>% 
      mutate(Ellipse = map(id, ~fEllipse(data[[1]]$F1, data[[1]]$F2, data[[1]]$e))) %>% 
      unnest(c(data, Ellipse))
    
    df %>% ggplot(aes(Re(Ellipse), Im(Ellipse), color=id))+
      geom_path()
    
    

    enter image description here

    Bingo. That's what we meant! All you need to do now is load your ellipses into the tibble and draw it as I did above.

    Update 1

    If I understand your intentions correctly, you want to generate a series of ellipses. It is true that you do it in a very complicated and illegible way, but so be it.

    n = 100
    k <- 0
    ellipses<- data.frame(focus1 = numeric(n), focus2 = numeric(n), ecc = numeric(n))
    while ( k <= n) {
      F1_k <- ( -3/2)*((sin(2*pi*k/n))^3) + (3/10)*((sin(2*pi*k/n))^7) + (1i) * sin((2*pi*k/1875) + (pi/6)) + (1/4)*(sin((2*pi*k /1875) + (pi/6)))^3 + ((2/15) - (1/8)*cos(pi*k/625)* exp(68*pi*(1i)*k/n))
      F2_k <- ( -3/2)*((sin(2*pi*k/n))^3) + (3/10)*((sin(2*pi*k/n))^7) + (1i) * sin((2*pi*k/1875) + (pi/6)) + (1/4)*(sin((2*pi*k /1875) + (pi/6)))^3 - ((2/15) - (1/8)*cos(pi*k/625)* exp(68*pi*(1i)*k/n))
      D_k <- (49/50) - (1/7)*(sin(4*pi*k/n))^4
      ellipses[k, ] <- c(F1_k, F2_k,  D_k)
      k <- k + 1
    }
    
    df = ellipses %>% as_tibble() %>% 
      mutate(id = paste("ell",1:nrow(.))) %>% 
      group_by(id) %>%
      nest() %>%
      mutate(Ellipse = map(id, ~fEllipse(data[[1]]$focus1, data[[1]]$focus2, data[[1]]$ecc))) %>%
      unnest(c(data, Ellipse))
    
    df %>% ggplot(aes(Re(Ellipse), Im(Ellipse), color=id))+
      geom_path()+
      theme(legend.position = "none")
    

    enter image description here

    More than 100 ellipses generated with your code and drawn with my code. I hope that was it.