首页 > 解决方案 > Calculate coordinates of a point based on sine/cosine

问题描述

let me begin by saying that I've read through 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, and especially How to get coordinates of a point in a coordinate system based on angle and distance and none of them managed to lift the veil of confusion, surrounding me.

What I am doing: I want to create a sort of Instantaneous Field of View (FOV) for a bunch of sequences of points; the FOVs would represent what is visible from each point, depending of course, on the direction at which we are looking at ( 0 - North; 90 - East; 180 - South; 270 - West; 360 - North). The FOV is essentially a triangle, where the central (C) vertex is the point itself, vertex A and vertex B, whose coordinates I am looking for, being the ones connected to the base of the triangle.

The code snippet: I am essentially approaching this via leveraging two right triangles, that together constitute the FOV, like so:

enter image description here

--------- 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) 
}

The result: the code produces the triangle as one would expect, yet it does so only when the angle (ca) is between 0-90 degrees:

enter image description here

The Problem

This formula doesn't seem to work for other camera angles. To my mind (and according to the provided links to topics) the formula should be universally applicable for any angle measure. Can someone provide some input on whether I am a) using the right formula and b) using it in the correct way.

UPDATE: link to the spatial points data frame in shapefile format: https://drive.google.com/file/d/1ax5OG8c8Cl-Hz3N16ye9OoG4z7l8HSAQ/view?usp=sharing

UPDATE 2: The process of getting from the pnpover (the shared spdf) to pnp.90.deg is just a spatial subset:

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

I decided to bucket looking angles in ranges of 0-90; 91-180; 181-270; 271-360 in order to test what was going wrong.

Thank you kindly!

标签: rgeometrytrigonometry

解决方案


看这张图片:

在此处输入图像描述

和:

  • ca是相机指向的方向。它是从北开始并顺时针方向的角度,因此 0 = 北,90 = 东,等等。

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

  • C是相机位置。

  • A并且B是要计算的坐标。他们的距离Cd

您可能已经知道从极坐标到笛卡尔坐标的转换:
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

推荐阅读