user1320502 - 27 days ago 6

R Question

Imagine we have the circle defined by:

`X^2 + Y^2 = r^2`

The origin of the circle is

`0`

`radius = 1`

`(x1,y1)=(0,0)`

`(x2,y2) = (2,0)`

`library(plotrix)`

plot(0,0,xlim=c(-3,3),ylim=c(-2,2))

draw.circle(0,0,1)

lines(c(0,2),c(0,0))

I have tried to find the intersect of the line with the circle but with no luck. I took

my approach from the this wolfram page and produce the following code but it does not seem to produce the correct result. Can someone please point me to my (no doubt) stupid mistake?

`r <- 1`

id <- 1:5

x1 <- c(0)

y1 <- c(0)

x2 <- c(2)

y2 <- c(0)

df <- data.frame(id,x1,y1,x2,y2)

df <- transform(df, dx = x2-x1)

df <- transform(df, dy = y2-y1)

df <- transform(df, dr = sqrt(dx^2+dy^2))

df <- transform(df, D = (x1*y2)-(x2*y1))

df <- transform(df, dysign = sapply(dy,function(x) ifelse(x < 0,-1,1)))

df <- transform(df, newxplus = (D*dy + (dysign*dy) *dx*sqrt(r^2*dr^2-D^2))/dr^2)

df <- transform(df, newxneg = (D*dy - (dysign*dy) *dx*sqrt(r^2*dr^2-D^2))/dr^2)

df <- transform(df, newyplus = (-D*dx + (abs(dy)) *sqrt(r^2*dr^2-D^2))/dr^2)

df <- transform(df, newyneg = (-D*dx - (abs(dy)) *sqrt(r^2*dr^2-D^2))/dr^2)

# where newxplus and newxneg are the two x coordinates for the two possible intercepts

# similarly for newyplus and newyneg

df

Answer

You made a typo in your calculation of `newxplus`

, and `newxneg`

.

The notation `sgn*(dy)`

on the wolfram page you linked is the function `sgn*`

*applied* to the value `dy`

, i.e. your column `dysign`

, *not* the column `dysign`

*multiplied* by `dy`

.

so:

```
# df <- transform(df, newxplus = (D*dy + (dysign*dy)*dx*sqrt(r^2*dr^2-D^2))/dr^2)
df <- transform(df, newxplus = (D*dy + dysign*dx*sqrt(r^2*dr^2-D^2))/dr^2)
# df <- transform(df, newxneg = (D*dy - (dysign*dy)*dx*sqrt(r^2*dr^2-D^2))/dr^2)
df <- transform(df, newxneg = (D*dy - dysign*dx*sqrt(r^2*dr^2-D^2))/dr^2)
```

Giving your x coordinates of the intercepts of -1 and +1.

Note that the page you linked is for the intersection of an *infinite* line with the circle which is why you got two intersections, but you can later apply the x/y limits of the lines to the output intersections to filter which ones you want if you are using *finite* lines.

Also you mention you're only using a dataframe for now in the practice (note that the 5 rows you have are always the same...), but when you write your full version of this function I recommend pre-calculating the value `sqrt(r^2 * dr^2 - D^2)`

since it's used to calculate both the x and y coordinates.