根据正弦/余弦计算点的坐标

时间:2018-07-05 21:02:10

标签: r geometry trigonometry sin cosine

首先让我说我已经读过Calculate point A from given point E and angle and afterwards calculate Point A from E and angleCalculate point, given x, y, angle, and distancea problem involving trigonometry functions,尤其是How to get coordinates of a point in a coordinate system based on angle and distance,但没有一个人能揭开混乱的面纱,围绕着我。

我在做什么:我想为一连串的点序列创建一种瞬时视场(FOV); FOV将根据我们观察的方向(从0到北; 90到东; 180到南; 270到西; 360到北)代表从每个点可见的内容。 FOV本质上是一个三角形,其中中心(C)顶点是点本身,即顶点A和顶点B,我要查找的坐标是与三角形底边相连的坐标。

代码段:实际上,我是通过利用两个直角三角形来实现这一点的,它们共同构成了FOV,就像这样:

enter image description here

--------- VERTEX -------------

for (p in 1:nrow(pnp.90.deg@data)){   #pnp is the spatial points dataframe, containing attribute information such as lon/lat(coordinates) and ca(camera angle - showing the direction of sight/movement in degrees)
   a_alfa1 <- pnp.90.deg@data$ca - (pnp.90.deg@data$ca - 60)
   a_alfa1rad <- a_alfa1 * (pi/180)
   a_x1 <- pnp.90.deg@data$lon + 0.00035 * cos(a_alfa1rad)
   a_y1 <- pnp.90.deg@data$lat + 0.00035 * sin(a_alfa1rad) 
   avert1 <- cbind(a_x1, a_y1)
   colnames(avert1) <- c("lon", "lat") 
   avert.90<-SpatialPoints(avert1, proj4string=CRS("+proj=longlat +datum=WGS84      +no_defs +ellps=WGS84 +towgs84=0,0,0"), bbox=NULL) 
 }

--------- B VERTEX -------------

for (p in 1:nrow(pnp.90.deg@data)){
  b_alfa1 <- pnp.90.deg@data$ca - (pnp.90.deg@data$ca + 60)
  b_alfa1rad <- b_alfa1 * (pi/180)
  b_x1 <- pnp.90.deg@data$lon + 0.00035 * cos(b_alfa1rad)
  b_y1 <- pnp.90.deg@data$lat + 0.00035 * sin(b_alfa1rad)
  bvert1 <- cbind(b_x1, b_y1)
  colnames(bvert1) <- c("lon", "lat") 
  bvert.90<-SpatialPoints(bvert1, proj4string=CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"), bbox=NULL) 
}

结果:代码生成的三角形符合人们的预期,但是只有当角度(ca)在0-90度之间时,三角形才会生成:

enter image description here

问题

  

此公式似乎不适用于其他相机角度。在我看来(根据提供的与主题的链接),该公式应普遍适用于任何角度测量。有人可以提供一些关于我是否是a)使用正确公式和b)以正确方式使用它的信息。

更新:以shapefile格式链接到空间点数据框: https://drive.google.com/file/d/1ax5OG8c8Cl-Hz3N16ye9OoG4z7l8HSAQ/view?usp=sharing

更新2:从pnpover(共享的spdf)到pnp.90.deg的过程只是一个空间子集:

pnp.90.deg <- subset(pnpover, pnpover@data$ca <= 90)

我决定将视角范围设为0-90; 91-180; 181-270;为了测试出了什么问题,请使用271-360。

谢谢你!

1 个答案:

答案 0 :(得分:0)

看这张照片:

enter image description here

具有:

  • ca是相机指向的方向。角度是从北开始并顺时针旋转的,所以0 =北,90 =东,依此类推。

  • fa是视野(FOV)的内角。

  • C是摄像机位置。

  • AB是要计算的坐标。他们到C的距离是d

您可能已经知道从极坐标到笛卡尔坐标的转换:
x = cx + d * cos(alpha)y = cy + d * sin(alpha)

但是我们已经说过ca顺时针。这意味着我们必须更改sin/cos的用法。

所需的公式为:

x = cx + d * sin(alpha)
y = cy + d * cos(alpha)

因此,对于A,B坐标:

ax = cx + d * sin(ca - fa/2)
ay = cy + d * cos(ca - fa/2)
bx = cx + d * sin(ca + fa/2)
by = cy + d * cos(ca + fa/2)

这些是整个{0, 360}范围内的有效公式。或{0, 2PI},如您所愿。
如果原点与北部不同(例如0 =东部),则需要进行一些符号更正。

就像编译器一样,即使在{0, 2PI}范围之外,也可以使用任何角度。如果不是,则必须首先将角度夹在该范围内。我不会讲 r,所以我以一般形式写它:

float parts = angle / 360
float rest = parts - int(parts)
float cAngle = rest * 360
better cAngleRadians = rest * 2 *pi