Extension of the circle overlap problem

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.
屏幕截图 2023-05-30 102458
屏幕截图 2023-05-30 102525

About circle overlap area - Posit Community (rstudio.com)

1 Like

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")

image


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

1 Like

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
1 Like

Good advice and code example! Generally I am appreciative of your effort, help, and time in this matter.

1 Like

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.