user1320502 - 7 months ago 28
R Question

# intercept between straight line and circle

Imagine we have the circle defined by:

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

The origin of the circle is
`0`
and
`radius = 1`
. If we draw a horizontal line from the origin moving to the right with coordinates
`(x1,y1)=(0,0)`
and
`(x2,y2) = (2,0)`
this line should intersect the circle. e.g.

``````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
``````

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.

Source (Stackoverflow)