Hi,
With the help of Richard Careaga and Jerry, we succeed in getting overlap area between circles in R. And after I read some articles, I want to know is it possible to know the overlap width? After we know it, we may analysis interaction intensity more directly. Thank you for all the help in advance.
My first thought is to find distance between the tangents of each pair of circles perpendicular to the radius. However, my trigonometry is almost eligible for an old age pension, so I'll need to confirm.
Update. I was making things too complicated.
library(PlaneGeometry)
# this block solely to illustrate the problem
O1 <- c(3,4); circ1 <- Circle$new(O1, 2)
O2 <- c(6,5); circ2 <- Circle$new(O2, 1.75)
intersections <- intersectionCircleCircle(circ1, circ2)
A <- intersections[[1]]; B <- intersections[[2]]
theta1 <- Arg((A-O1)[1] + 1i*(A-O1)[2])
theta2 <- Arg((B-O1)[1] + 1i*(B-O1)[2])
path1 <- Arc$new(O1, circ1$radius, theta1, theta2, FALSE)$path()
theta1 <- Arg((A-O2)[1] + 1i*(A-O2)[2])
theta2 <- Arg((B-O2)[1] + 1i*(B-O2)[2])
path2 <- Arc$new(O2, circ2$radius, theta2, theta1, FALSE)$path()
plot(0, 0, type="n", xlim = c(0,10), ylim = c(0,10),xlab = NA, ylab = NA)
grid()
draw(circ1, border = "blue", lwd = 2)
draw(circ2, border = "forestgreen", lwd = 2)
polypath(rbind(path1,path2), col = "red")
points(3,4,pch=19, col = "blue")
text(3,5,"A")
text(3,3.55,"r=2")
points(6,5,pch=19, col = "forestgreen")
text(6,6,"B")
text(6,4.5,"r=1.75")
circleOverlap <- function(x1, y1, r1, x2, y2, r2) {
# Calculate the distance between the centers of the circles
distance <- sqrt((x2 - x1)^2 + (y2 - y1)^2)
# Check that the circles overlap
if (distance > r1 + r2) {
return(0) # No overlap, return 0
}
# Check if the circles are tangential
if (distance == r1 + r2) {
return(1) # Tangential, return 1 (single point of contact)
}
# Calculate the overlap area or length of the overlapping segment
overlap <- r1 + r2 - distance
return(overlap)
}
circleOverlap(3,4,2,6,5,1.75)
#> [1] 0.5877223
Created on 2023-05-30 with reprex v2.0.2
Great work!!!And if x1, y1, r1, x2, y2, r2 are not a number respectively. x1 is dataframe, y1 is dataframe, others are the same, that contain many numbers. We may loop this function?
I'm not sure I understand how the data is organized; however, if you can write a function to extract the values of x1, etc. from one or multiple data frames and assemble into a vector, and apply the function to the vector once, you can do it for however many rows in a matrix or data frame as desired.
co <- function(x1, y1, r1, x2, y2, r2) {
distance <- sqrt((x2 - x1)^2 + (y2 - y1)^2)
if (distance > r1 + r2) return(0) # No overlap, return 0
if (distance == r1 + r2) return(1) # Tangential, return 1 (single point of contact)
overlap <- r1 + r2 - distance
return(overlap)
}
set.seed(42)
d <- data.frame(
x1 = sample(-10:10, 100, replace = TRUE),
y1 = sample(-10:10, 100, replace = TRUE),
r1 = sample(1:10, 100, replace = TRUE),
x2 = sample(-10:10, 100, replace = TRUE),
y2 = sample(-10:10, 100, replace = TRUE),
r2 = sample(1:10, 100, replace = TRUE)
)
apply(d, 1, function(row) co(row[1], row[2], row[3], row[4], row[5], row[6]))
#> [1] 1.7804555 0.0000000 2.5857864 6.2917961 0.0000000 0.0000000
#> [7] 13.3944487 0.0000000 0.0000000 1.5660189 0.0000000 4.0000000
#> [13] 6.0000000 0.0000000 0.0000000 0.0000000 3.9615952 2.7537887
#> [19] 9.9377423 4.6754447 7.9289322 0.0000000 0.0000000 12.6754447
#> [25] 0.0000000 14.0000000 1.8768944 7.8768944 0.0000000 6.0000000
#> [31] 9.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.7804555
#> [37] 3.5982457 3.4559963 0.0000000 0.0000000 0.0000000 9.3944487
#> [43] 2.4559963 10.0000000 0.0000000 0.0000000 0.0000000 0.0000000
#> [49] 0.0000000 3.6148352 0.0000000 0.0000000 5.0000000 5.8196601
#> [55] 4.7573593 0.0000000 0.0000000 0.1690481 7.2917961 0.0000000
#> [61] 0.0000000 0.0000000 6.7639320 0.0000000 0.0000000 6.7639320
#> [67] 0.8019610 4.0000000 3.9687805 0.0000000 0.0000000 0.0000000
#> [73] 0.0000000 1.3508894 0.0000000 1.8196601 5.7537887 3.9584054
#> [79] 0.0000000 0.0000000 1.0000000 4.7804555 0.0000000 0.9289322
#> [85] 4.9546390 0.9009805 0.0000000 0.0000000 8.0000000 0.0000000
#> [91] 0.0000000 0.0000000 0.0000000 6.0000000 0.0000000 0.0000000
#> [97] 12.0000000 0.0000000 0.0000000 6.8768944
Good advice and code example! Generally I am appreciative of your effort, help, and time in this matter.
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.
If you have a query related to it or one of the replies, start a new topic and refer back with a link.