简体   繁体   中英

Computing angle between two vectors (with one vector having a specific X,Y position)

I am trying to compute the angle between two vectors, wherein one vector is fixed and the other vector is constantly moving. I already know the math in this and I found a code before:

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

I tried defining my a as:

a<-c(503,391)

and my b as:

b <- NM[, c("X","Y")]

When I apply the theta function I get:

Warning message:
In acos(sum(a * b)/(sqrt(sum(a * a)) * sqrt(sum(b * b)))) : NaNs produced

I would appreciate help to solve this.

And here is my sample data:

structure(list(A = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label =
c("1",  "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
"13",  "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
"24",  "25", "26", "27", "28", "29", "30", "31", "32", "33", "34",
"35",  "36", "37", "38", "39", "40", "41", "42", "43", "44", "45",
"46",  "47", "48", "49", "50", "51", "52", "53", "54", "55", "56",
"57",  "58", "59", "60", "61", "62", "63", "64", "65", "66", "67",
"68",  "69", "70", "71", "72", "73", "74", "75", "76", "77", "78",
"79",  "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
"90",  "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", 
"101", "102", "103", "104", "105", "106", "107", "108", "109", 
"110"), class = "factor"), T = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6 ), X =
c(528.04, 528.04, 528.04, 528.04, 528.04, 528.04), Y = c(10.32, 
10.32, 10.32, 10.32, 10.32, 10.32), V = c(0, 0, 0, 0, 0, 0), 
    GD = c(0, 0, 0, 0, 0, 0), ND = c(NA, 0, 0, 0, 0, 0), ND2 = c(NA, 
    0, 0, 0, 0, 0), TID = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = c("t1", 
    "t10", "t100", "t101", "t102", "t103", "t104", "t105", "t106", 
    "t107", "t108", "t109", "t11", "t110", "t12", "t13", "t14", 
    "t15", "t16", "t17", "t18", "t19", "t2", "t20", "t21", "t22", 
    "t23", "t24", "t25", "t26", "t27", "t28", "t29", "t3", "t30", 
    "t31", "t32", "t33", "t34", "t35", "t36", "t37", "t38", "t39", 
    "t4", "t40", "t41", "t42", "t43", "t44", "t45", "t46", "t47", 
    "t48", "t49", "t5", "t50", "t51", "t52", "t53", "t54", "t55", 
    "t56", "t57", "t58", "t59", "t6", "t60", "t61", "t62", "t63", 
    "t64", "t65", "t66", "t67", "t68", "t69", "t7", "t70", "t71", 
    "t72", "t73", "t74", "t75", "t76", "t77", "t78", "t79", "t8", 
    "t80", "t81", "t82", "t83", "t84", "t85", "t86", "t87", "t88", 
    "t89", "t9", "t90", "t91", "t92", "t93", "t94", "t95", "t96", 
    "t97", "t98", "t99"), class = "factor")), .Names = c("A",  "T", "X", "Y", "V", "GD", "ND", "ND2", "TID"), row.names = c(NA,  6L),
class = "data.frame")

Your function is not vectorized. Try this:

theta <- function(x,Y) apply(Y,1,function(y,x) acos( sum(x*y) / ( sqrt(sum(x^2)) * sqrt(sum(y^2)) ) ),x=x)
a<-c(503,391)
b <- DF[, c("X","Y")]

theta(a,b)
#        1         2         3         4         5         6 
#0.6412264 0.6412264 0.6412264 0.6412264 0.6412264 0.6412264 

There is a problem with the acos and atan functions in this application, as you cannot compute angles for the full circle, only for the plus quadrant. In 2D, you need two values to specify a vector, and you need two values (sin and cos) to define it in degrees/radians up to 2pi. Here is an example of the acos problem:

plot(seq(1,10,pi/20))              ## A sequence of numbers
plot(cos(seq(1,10,pi/20)))         ## Their cosines
plot(acos(cos(seq(1,10,pi/20))))   ## NOT Back to the original sequence

Here's an idea:

angle <- circular::coord2rad(x, y)
plot(angle)

where "(x,y)" has "angle"

as.numeric(angle)

gives the angle in radians (0,360). To report geographical directions, convert to degrees, and other things, you can use the added parameters for the circular function, eg:

x <- coord2rad(ea,eo,  control.circular = list(type = "directions",units = "degrees"))
plot(x)
as.numeric(x)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM