0
$\begingroup$

In a web page using Google Maps JavaScript API v3 (including Geometry library) I currently draw an ellipse as a "diamond" with 4 corner points by the following JavaScript code:

map screenshot

var NORTH = 0;
var WEST  = -90;
var SOUTH = 180;
var EAST  = 90;

function drawEllipse(map, lat, lng, firstradius, secondradius, color) {

        var center = new google.maps.LatLng(lat, lng);

        var north = computeOffset(center, firstradius, NORTH); 
        var south = computeOffset(center, firstradius, SOUTH); 
        var east = computeOffset(center, secondradius, EAST); 
        var west = computeOffset(center, secondradius, WEST); 

        var corners = [ north, east, south, west ];

        var diamond = new google.maps.Polygon({
                paths: corners,
                strokeColor: color,
                strokeOpacity: 0.9,
                strokeWeight: 1,
                fillColor: color,
                fillOpacity: 0.3,
                map: map
        });
}

As you can see I use Google's computeOffset() method to move once to the north, south, west, east from the given center.

Here is jsFiddle web page - so that you can see the results immediately for yourself.

Could anybody please recommend a way to draw at least 4 more points for the polygon?

How to draw them with computeOffset(), when I am given firstradius, secondradius of the erllipse and latitude, longitude of its center point - and the ellipse is never rotated (it is always "pointing to north").

I think I need to add

var NORTH_WEST = -45;
var NORTH_EAST = 45;
var SOUTH_EAST = 135;
var SOUTHE_WEST = -135;

and then I probably need the distance - but how to calculate it out of firstradius and secondradius?

UPDATE:

I have tried the following thinking: an ellipse is defined by

ellipse

and at NORTH_EAST (which is at 45 degrees from NORTH) we have:

 x = y

So the distance from center to that point at ellipse should be:

   var distance = 1 / Math.sqrt(1 / (firstradius * firstradius) + 
                                1 / (secondradius * secondradius));

   var northEast = computeOffset(center, distance, NORTH_EAST); 

   var northWest = computeOffset(center, distance, NORTH_WEST); 

   var southEast = computeOffset(center, distance, SOUTH_EAST); 

   var southWest = computeOffset(center, distance, SOUTH_WEST); 

    var corners = [ northWest, north, northEast, east, 
                    southEast, south, southWest, west ];

Unfortunately, this does not work and draws a concave "diamond", which you can see (and change by clicking Run button) at the new jsFiddle.

UPDATE: I am copying the Naks' answer (thanks!) below - in case jsFiddle ever disappears:

var mapOptions = {
    zoom: 14,
    center: new google.maps.LatLng(23.12546, 113.26615),
    mapTypeId: google.maps.MapTypeId.TERRAIN
};

var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

function drawEllipse(map, lat, lng, firstradius, secondradius, color) {

    var center = new google.maps.LatLng(lat, lng);
    var center1 = new google.maps.LatLng(lat+0.1, lng);
    var center2 = new google.maps.LatLng(lat, lng+0.1);
    var latConv = google.maps.geometry.spherical.computeDistanceBetween(center,center1)*10;
    var lngConv = google.maps.geometry.spherical.computeDistanceBetween(center,center2)*10;
    var points = [];

    for (var angle = 0; angle < 360; angle += 10){
         var x = lat+((firstradius*Math.cos(angle*(Math.PI/180)))/latConv);
         var y = lng+((secondradius*Math.sin(angle*(Math.PI/180)))/lngConv);
         var point = new google.maps.LatLng(x,y);
         points.push(point);
    }

    var diamond = new google.maps.Polygon({
          paths: points,
          strokeColor: color,
          strokeOpacity: 0.9,
          strokeWeight: 1,
          fillColor: color,
          fillOpacity: 0.3,
          map: map
    });
}

drawEllipse(
    map,
    map.getCenter().lat(), 
    map.getCenter().lng(), 
    850, 
    450, 
    '#990000'
);
$\endgroup$
1
  • 1
    $\begingroup$ Have you tried using eccentric angle? Or try using a parameter, the ellipse would be $(a\cos\theta,b\sin\theta)$ $\endgroup$ – AvZ Feb 7 '15 at 10:18
2
+50
$\begingroup$

It would be difficult to draw an ellipse with only 8 points, as polygon method can only draw straight lines between two point, with 8 points you will end up getting an octagon.

For a smother ellipse I suggest you to use more than 8 points.

Below is the implementation done by calculating a point for every 1° step.

http://jsfiddle.net/z4om3x6s/7/

$\endgroup$
2
  • $\begingroup$ Thank you, this looks great. Do you mind to write few explanation words about center1, center2, latConv, lngConv? Why are those variables needed, what do they mean? $\endgroup$ – Alexander Farber Feb 10 '15 at 13:34
  • 1
    $\begingroup$ center1, center2 are some temporary variables, these variables are in turn used in calculation of latConv, and lngCov. This will give you the change in distance with you increment latitude or longitude. If you closely observe, center1 & center2 are obtained just by incrementing latitude or longitue by 0.1. Hope this explanation helps. $\endgroup$ – Naks Feb 10 '15 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.