首先让我说我已经读过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,就像这样:
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)
}
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。
谢谢你!
答案 0 :(得分:0)
看这张照片:
具有:
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