2 years ago

#9964

test-img

Stavrum

calculating angle of closest point to multiple lines across time n r

I am trying to find the angle to the closest point from a line in multiple cases within and across time. I have a data set that looks something like this. Four points in group 1, four in group 2 and one in group 3.

   x <- sample(1:50, 27)
    y <- sample(1:50, 27)
    group <- c(1,1,1,1,2,2,2,2,3,1,1,1,1,2,2,2,2,3,1,1,1,1,2,2,2,2,3)
    id <- rep(seq(1,9,1), 3)
    time <- rep(1:3, each = 9)
    
    df <- as.data.frame(cbind(x, y, group, id, time))


    x  y group id time
1  25 36     1  1    1
2  49 35     1  2    1
3  41 27     1  3    1
4  28 47     1  4    1
5   7  3     2  5    1
6  46 25     2  6    1
7  15  7     2  7    1
8  32 15     2  8    1
9  38 29     3  9    1
10 19  4     1  1    2
11 18 14     1  2    2
12  8 37     1  3    2
13 29  8     1  4    2
14  6  1     2  5    2
15 30  6     2  6    2
16 10 19     2  7    2
17 45 49     2  8    2
18 40 43     3  9    2
19 17 48     1  1    3
20 27 21     1  2    3
21 26 20     1  3    3
22 33 50     1  4    3
23 16 16     2  5    3
24 23 46     2  6    3
25 21 26     2  7    3
26 13 31     2  8    3
27 11 41     3  9    3

the item in group 3 is used to identify which point is the base of all of the lines. in this example for time 1 - id 3 in group 1 in closest. this signals that a line should be made to all other points in group 1 (3-1, 3-2 and 3-4). I then need to identify which id in group 2 is closest to each of the 3 lines. for example, point 6 might be closest to the line 3-2 and from that I would calculate the angle in points 6-3-2. I need to calculate this for all other lines in this time, and then perform this again across all other times.

The following code identifies the base point for the lines (it is not optimal but I need the other data it calculates for other uses)

#### calculate distance between all points
distance = function(x1,x2,y1,y2) sqrt(((x2-x1)^2)+((y2-y1)^2)) #distance function
distance2 = function(x,y,.pred) distance(x, x[.pred], y, y[.pred]) #   
distance3 = function(x, y, id){
  dists = map(1:9, ~distance2(x,y, which(id == .x)))
}

#use distance formula
df2 <- df %>% 
  group_by(time) %>% 
  mutate(distances=distance3(x, y, id))
  
  
distances <- df2$distances # extract distance list
distances <- do.call(rbind.data.frame, distances) # change list to dataframe
colnames(distances) <- c(paste0("dist", 1:9)) # change column names
df <- cbind(df,distances) # merge dataframes


group3 <- df %>% filter(group == 3) 
df <- df %>%  filter(group == 1 | group == 2) #remove group 3 (id 9 from data as no longer needed)

#new columns with id and group as closest to position of id 9
df <- df %>% group_by(time) %>% mutate(closest = id[which.min(dist9)]) %>% 
  mutate(closest.group = group[which.min(dist9)]) %>% ungroup 
  

This is about as far as I can get on my own. I have found the following formula on here which I can use to calculate the distance of a point to a line. in an individual case but I have no idea how to integrate it across the multiple time periods and with conditions.

dist2d <- function(a,b,c) {
  v1 <- b - c
  v2 <- a - b
  m <- cbind(v1,v2)
  d <- abs(det(m))/sqrt(sum(v1*v1))
}

for clarification, the line only goes between the two points and does not extend to infinity.

r

time

distance

spatial

angle

0 Answers

Your Answer

Accepted video resources