2
votes

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!

1
Posting problem code without data is a cause for question closure.IRTFM
Apologies for that, I updated the post to include the spdf I am using.Momchill
You need to show the R code that takes you from 0_DemoGrassland_MetaData to pnp.90.deg@dataIRTFM
@42- the operations are a few and consist of harvesting said points (that actually represent images) and performing some buffer and intersect to only keep points(images) within a certain area. The next step is the FOV generation. and pnp.90.deg is just a spatial subset of the file I shared that holds only the 0-90 degree images.Momchill
What exactly does "doesn't seem to work" mean? As far as I see, alfa1 is always +- 60 and does not depend on pnp.90.deg@data$ca. Is this correct?Nico Schertler

1 Answers

1
votes

Look at this picture:

enter image description here

with:

  • ca is the direction where the camera points to. It is angle that starts at North and goes clockwise, so 0=North, 90=East, etc.

  • fa is the inner angle for the field of view (FOV).

  • C is the camera position.

  • A and B are the coordinates to calculate. Their distance to C is d.

You may already know the conversion from polar to Cartesian coordinates:
x = cx + d * cos(alpha) and y = cy + d * sin(alpha)

But we have said that ca goes clockwise. It means that we must change sin/cos usage.

The needed formulas are:

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

So, for A, B coordinates:

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)

These are valid formulas for the whole of {0, 360} range. Or {0, 2PI} as you prefer.
If the origin was different from North (say 0=East) then we would need some sign corrections.

Likely the compiler is able to use any angle, even out of {0, 2PI} range. If not, you must first clamp the angle into the range. I don't speak r, so I write it in general form:

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