根据正弦/余弦计算点的坐标
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据正弦/余弦计算点的坐标相关的知识,希望对你有一定的参考价值。
让我首先说我读过Calculate point A from given point E and angle and afterwards calculate Point A from E and angle,Calculate point, given x, y, angle, and distance,a 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为了测试出了什么问题。
非常感谢你!
看这张图片:
有:
ca
是相机指向的方向。它是从北方开始并顺时针方向转动的角度,因此0 =北,90 =东等。fa
是视场(FOV)的内角。C
是相机的位置。A
和B
是要计算的坐标。他们与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
以上是关于根据正弦/余弦计算点的坐标的主要内容,如果未能解决你的问题,请参考以下文章