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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据正弦/余弦计算点的坐标相关的知识,希望对你有一定的参考价值。

让我首先说我读过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,如下所示:

--------- A 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度之间时才会这样做:

问题

此公式似乎不适用于其他摄像机角度。在我看来(并根据提供的主题链接),该公式应该普遍适用于任何角度测量。有人可以提供一些关于我是否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为了测试出了什么问题。

非常感谢你!

答案

看这张图片:

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

以上是关于根据正弦/余弦计算点的坐标的主要内容,如果未能解决你的问题,请参考以下文章

正弦计算比余弦慢几个数量级

提高正弦/余弦和大型阵列的计算速度

余弦相似度计算

Python:以高达 100 万位的精度计算正弦/余弦

MATLAB入门笔记

简单几何应用