0

I am displaying in google maps (v3) markers with the position where the photograph was taken and position of the subject and tracing a line to show direction in which photo was taken. I have also calculated the distance and the angle from camera position.

What I am trying now is to show the view from camera with a triangle that opens, lets say 30 degrees toward the subject. Seem to me is a third grade math, but can't figure out after 25 years, I know how to draw the polygon/triangle but not really how to calculate the points at subject's distance about 30 degrees in both directions, of course taking in mind the heading angle.

Almost there...

Used the formula Red answered below to create a function (found I needed to convert: lat1, lon1 and bearing to radians before the math.
I call this function each time a marker changes to calculate again pos1 and pos2 of the triangle and change the paths to redraw it.

Thing now is that triangle shows up but facing all kind of directions but the proper one.

Question now is:

Google return the heading in degrees negative to West and positive to East (-180/180) and seems that the formula need the bearing (heading) in 360 degress? Right now function CameraView(75) display correctly but I am passing the angle as 75 degrees instead of 15 degrees (to have 15 degrees view left, and 15 to right).

function getVertex(brng) {

var R = 6366.707;
var d = parseFloat( getObj('GPSDestDistance').value ) * 1.5  //distance on form field

//position of Camera
var lat1 = deg2rad( markerCam.getPosition().lat() )
var lon1 = deg2rad( markerCam.getPosition().lng() )

var lat2 = Math.asin( Math.sin(lat1) * Math.cos(d/R) + Math.cos(lat1) * Math.sin(d/R) * Math.cos(brng) );
var lon2 = lon1 + Math.atan2( Math.sin(brng) * Math.sin(d/R) * Math.cos(lat1), Math.cos(d/R) - Math.sin(lat1) * Math.sin(lat2) );

lat2 = rad2deg( lat2 )
lon2 = rad2deg( lon2 )

var pos = new google.maps.LatLng(lat2, lon2)
return pos;
}
function CameraView(angle) {
var brng = deg2rad( parseFloat( getObj('GPSDestBearing').value ) );  //get heading from form
if(brng<0){
    //brng = Math.round(-brng / 360 + 180)
    }
var pos1 = markerCam.getPosition();
var pos2 = getVertex(brng - angle);
var pos3 = getVertex(brng + angle);
var paths = [ pos1, pos2, pos3 ];
poly.setPath(paths);
}

function deg2rad(x)     { return x * (Math.PI / 180); }
function rad2deg(x)     { return x * (180 / Math.PI); }
BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2033838
  • 153
  • 1
  • 10

2 Answers2

1

A simpler way: use google maps geometry library

  calculateAngle: function(subjectMarker, cameraMarker, angle) {
    var distance, heading, left, right;

    // Get the heading between two markers
    heading = google.maps.geometry.spherical.computeHeading(subjectMarker.getPosition(), cameraMarker.getPosition());

    // convert heading range from [-180,180] to [0,360]
    heading = ((heading - -180) * 360) / 360;

    // Get the distance between two markers
    distance = google.maps.geometry.spherical.computeDistanceBetween(cameraMarker.getPosition(), subjectMarker.getPosition());

    // Calculate angle
    left = new google.maps.geometry.spherical.computeOffset(cameraMarker.getPosition(), distance / Math.cos(Math.PI * (angle / 2) / 180), heading - (angle / 2));
    right = new google.maps.geometry.spherical.computeOffset(cameraMarker.getPosition(), distance / Math.cos(Math.PI * (angle / 2) / 180), heading + (angle / 2));

    // Return an array of `google.maps.LatLng` objects for use when drawing a polygon.
    return [cameraMarker.getPosition(), left, right];
  }
Ben
  • 695
  • 6
  • 12
0

The formula to get an endpoint latitude and longitude (lat 2,lon2) (in radians) from a starting location (lat1,lon1) (also in radians), range (d), radius of the Earth (R) and bearing (brng) is:

var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) + Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1), Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));

Your start point will be one of the points of the triangle polygon. The other two can be found using this code snippet, putting in your bearing +/- 15 degrees (for the 30 degree triangle example) and a range that depends entirely on how big you want the triangle.

RedPeasant
  • 536
  • 1
  • 8
  • 17
  • Thank you Red, it works. It took me a while to realize that coordinates lat1, lon1 should be converted into radians before, and results obviously are radians and must be converted to decimal. However I am missing the thing with range (r) which I don't see in the formula (and honestly have not real idea if that can give the length for points 2 and 3 to reach the subject horizon), right now I am using d * 1.5 to make the triangle shows beyond the subject point. – user2033838 Mar 27 '13 at 10:41
  • Whoops,forgot to specify radians. Also screwed up my notation. I've fixed it above. Range is d in the formulas, not r. If you're trying to get the triangle off the edge of the currently visible map, you'll have to look at the current map position and size to compute it, and do a whole lot of checks when near the poles or when way zoomed out. – RedPeasant Mar 27 '13 at 17:39
  • No problem Red, it was a big push toward. Good to know that (r) is not such a thing. I edited my question to find out about why triangle was displaying in opposite direction or wrong, finally corrected it somehow, since I am using the heading that google maps provide when tracing direction from Camera to Object as -180/180, so I convert to it radians and but then have to provide the bearing as -75/+75 degrees instead of -15/+15 to make the triagle shows in proper direction (I guess I should do something before like subtract to convert the heading to 360 angle or so, is this correct?) – user2033838 Mar 27 '13 at 18:28
  • About triangle off the edge not sure really, I use points for photos only with zoom 13 to start and guess fit.bounds can help when triangle goes off the edge. – user2033838 Mar 27 '13 at 18:56