user1320502 user1320502 - 1 year ago 49
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
radius = 1
. If we draw a horizontal line from the origin moving to the right with coordinates
(x2,y2) = (2,0)
this line should intersect the circle. e.g.


enter image description here

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

Answer Source

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.


# 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.