Objective: Given two points, find the coordinates of the arc that connects them and plot it.
Implementation: One function to find the arc's points (circleFun
) and another to plot it (plottest
). The colors shows the direction of the path, from red to green.
circleFun <- function(x,y)
{
center <- c((x[1]+y[1])/2,(x[2]+y[2])/2)
diameter <- as.numeric(dist(rbind(x,y)))
r <- diameter / 2
tt <- seq(0,2*pi,length.out=1000)
xx <- center[1] + r * cos(tt)
yy <- center[2] + r * sin(tt)
res <- data.frame(x = xx, y = yy)
if((x[1]<y[1] & x[2]>y[2]) | (x[1]>y[1] & x[2]<y[2])){
res <- res[which(res$x>min(c(x[1],y[1])) & res$y>min(c(x[2],y[2]))),]
} else {
res <- res[which(res$x<max(c(x[1],y[1])) & res$y>min(c(x[2],y[2]))),]
}
return(res)
}
plottest <- function(x1,y1)
{
plot(c(x1[1],y1[1]),c(x1[2],y1[2]),
xlim=c(-2,2),ylim=c(-2,2),col=2:3,pch=20,cex=2,asp=1)
lines(circleFun(x1,y1))
}
par(mfrow=c(2,2))
plottest(c( 1,-1),c(-1, 1))
plottest(c(-1, 1),c( 1,-1))
plottest(c(-1,-1),c( 1, 1))
plottest(c( 1, 1),c(-1,-1))
Result:
Question: I cannot figure out why lines
function closes the path in Figures [1,1] and [1,2] while it does not for Figures [2,1] and [2,2]. The expected result should be all Figures as those of the second row.
Thank you!
Like the others said. This being said, here is a much simpler version of your function, with your expected output.
circleFun <- function(x, y) {
center <- (x + y) / 2
radius <- sqrt(sum((x - y)^2)) / 2
angle <- atan2((y - x)[2], (y - x)[1])
direc <- ifelse(abs(angle) > pi / 2, -1, 1)
tt <- seq(0, direc * pi, length.out = 1000)
return(data.frame(x = center[1] + radius * cos(angle + tt),
y = center[2] + radius * sin(angle + tt)))
}
where the direc
variable is what decides whether to draw the semi-circle clockwise or counter-clockwise.
I can answer your question about the lines
function, but I will leave it to you to figure out how to fix your circleFun
to produce the expected behavior:
lines()
connects points in the order in which they appear in the data. Also, the path is closed only when the first point is included again at the end of the data. The following figure illustrates this behavior.
par(mfrow=c(1, 2))
plot(x=c(-1, 0, 1), y=c(-1, 1, -1), xlim=c(-2, 2), ylim=c(-2, 2),
type="l", asp=1)
points(x=c(-1, 1), y=c(-1, -1))
plot(x=c(-1, 0, 1, -1), y=c(-1, 1, -1, -1), xlim=c(-2, 2), ylim=c(-2, 2),
type="l", asp=1)
points(x=c(-1, 1), y=c(-1, -1))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With