r - compute angle between moving vectors -


i have data frame looks this:

    structure(list(k = c(1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l,  1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l,  1l, 1l, 1l, 1l, 1l, 1l, 1l, 1l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l,  2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l,  2l, 2l, 2l, 2l, 2l, 2l, 2l, 2l), t = c(1l, 2l, 3l, 4l, 5l, 6l,  7l, 8l, 9l, 10l, 11l, 12l, 13l, 14l, 15l, 16l, 17l, 18l, 19l,  20l, 21l, 22l, 23l, 24l, 25l, 26l, 27l, 28l, 29l, 30l, 31l, 32l,  33l, 34l, 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l, 10l, 11l, 12l,  13l, 14l, 15l, 16l, 17l, 18l, 19l, 20l, 21l, 22l, 23l, 24l, 25l,  26l, 27l, 28l, 29l, 30l, 31l, 32l), x = c(26.892, 23.904, 23.904,  23.904, 23.904, 23.904, 23.904, 23.904, 23.904, 20.916, 20.916,  20.916, 20.916, 20.916, 20.916, 20.916, 20.916, 20.916, 20.916,  20.916, 29.88, 20.916, 14.94, 8.964, 8.964, 5.976, 5.976, 5.976,  5.976, 5.976, 5.976, 5.976, 5.976, 5.976, 857.56, 860.54, 857.56,  857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56,  857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56,  857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56, 857.56,  857.56, 857.56, 857.56, 857.56, 857.56), y = c(167.33, 167.33,  164.34, 164.34, 164.34, 164.34, 164.34, 164.34, 164.34, 143.42,  143.42, 143.42, 143.42, 143.42, 143.42, 143.42, 143.42, 143.42,  143.42, 143.42, 176.29, 182.27, 185.26, 188.24, 188.24, 188.24,  188.24, 188.24, 188.24, 188.24, 188.24, 188.24, 188.24, 188.24,  256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97,  256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97,  256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97,  256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97, 256.97 ), v = c(2.1128, 1.494, 0, 0, 0, 0, 0, 10.564, 10.564, 0, 0,  0, 0, 0, 0, 0, 0, 0, 17.034, 19.422, 8.7114, 6.6814, 3.3407,  1.494, 1.494, 0, 0, 0, 0, 0, 0, 0, 0, 20.1, 0, 1.494, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 1.494, 1.494), p = c(-135, -90, 0, 0, 0, 0, 0, -98.13,  -98.13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74.745, 90, 149.04, 153.43,  153.43, 180, 180, 0, 0, 0, 0, 0, 0, 0, 0, 41.987, 0, 180, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 90, 90)), .names = c("k", "t", "x", "y", "v",  "p"), row.names = c(na, 66l), class = "data.frame") 

since have x, y positions, make 2 vectors, should consider 3 x,y positions able compute angle. know that:

theta <- acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b)) ) ) 

from stackoverflow answer (angle between 2 vectors in r).

i need compute angle per t factor within each k. know use split in this.

but how define vector computation of angle , function angle itself? thanks.

on diagram, have x,y positions of movement , need compute angle of movement. hope helps. should noted there no angle possible first , last x,y positions. thanks

path of movement

so data frame has 6 rows. first 3 sets of (x,y) define right angle (th=90). next 3 sets of (x,y), rows 4-6, identical row 3. points sit on top of each other , there no angle. there 1 value of k it's kind of hard demonstrate aggregation k.

nevertheless, seems work:

df <- rbind(df,df,df)     # replicate original data 3 times df$k <- rep(1:3,each=6)   # k = 1, 2, 3 # theta in degrees theta <- function(a,b)(180/pi)*(acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b))))) # returns vector of angles between successive line segmeents get.angles <- function(df.split){   dx<- diff(df.split$x)   dy<- diff(df.split$y)   sapply(1:(nrow(df.split)-2),function(i){     <- c(dx[i],dy[i])     b <- c(dx[i+1],dy[i+1])     theta(a,b)   })  } # calls get.angles(...) each subset of df, based on k sapply(split(df,df$k),get.angles) #        1   2   3 # [1,]  90  90  90 # [2,] nan nan nan # [3,] nan nan nan # [4,] nan nan nan 

edit (response op's additional data, , comments)

so rather substantial change question, reworked solution seems work. using new definition of df,

theta <- function(a,b)(180/pi)*(acos(sum(a*b)/(sqrt(sum(a*a))*sqrt(sum(b*b))))) get.angles <- function(df.split){   dx<- diff(df.split$x)   dy<- diff(df.split$y)   stops <- which(dx^2+dy^2==0)   dx<- dx[-stops]   dy<- dy[-stops]   df<- df.split[-(stops+1),]   sapply(1:(length(dx)-1),function(i){     <- c(dx[i],dy[i])     b <- c(dx[i+1],dy[i+1])     return(cbind(df[i+1,],angle=180-theta(a,b)))   }) } result <- t(do.call(cbind,lapply(split(df,df$k),get.angles))) result #      k t  x      y      v      p      angle    # [1,] 1 2  23.904 167.33 1.494  -90    90       # [2,] 1 3  23.904 164.34 0      0      171.8714 # [3,] 1 10 20.916 143.42 0      0      7.125665 # [4,] 1 21 29.88  176.29 8.7114 149.04 108.4535 # [5,] 1 22 20.916 182.27 6.6814 153.43 172.8726 # [6,] 1 23 14.94  185.26 3.3407 153.43 179.9233 # [7,] 1 24 8.964  188.24 1.494  180    153.4963 # [8,] 2 2  860.54 256.97 1.494  180    0        

this version removes points dx2+dy2=0 (lines of length=0), in other words repeated points @ same location, , calculates angles remaining points. note i'm using "internal" angles (<180). finally, plot data show these indeed proper angles:

library(ggplot2) ggplot(df[df$k==1,],aes(x=x,y=y))+   geom_path()+geom_point(colour="red")+coord_fixed() 

note use of coord_fixed(). forces aspect ration 1:1. otherwise angles distorted.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

android - Keyboard hides my half of edit-text and button below it even in scroll view -

css - Make div keyboard-scrollable in jQuery Mobile? -