0

Problem:Skalierung eines Polygons auf einem map- die Breite maßstabs weigert

Ich versuche, ein Polygon auf einer Karte zu skalieren, und es erscheint in der horizontalen (Längengrad) zu arbeiten, aber die Vertikale (Breite) bleibt unverändert.

Wie ich es genähert

Eine Transformation mit diesen Schritten:

1) Umwandeln der Breite und Länge in cartesianischen Punkte

2) Punkte Bewegungsraum zum Objekt durch einen Unterschied machen mit jeder Punkt und der Polygonschwerpunkt

3) Skalierung jedes Punktes um einen Faktor

4) Bewegen Sie sie zurück in den Weltbereich, indem Sie den Schwerpunkt wieder hinzufügen.

A Mögliche Ursache:

Während der Übersetzungs- und Skalierung ich nur die x- und y-Werte zu manipulieren. Da die Skalierung von nur eine 2D-Form hat, dachte ich, dass sie ignoriert werden könnte, aber vielleicht muss ich sie auch irgendwo während des Prozesses manipulieren.

Mein Code: Main Execution Stack gefolgt von allen Funktionen, die sie verwenden.

var originalLatLngs = [{lat:45.250589,lon:-116.653149},{lat:45.250603,lon:-116.651856},{lat:45.250269,lon:-116.651845},{lat:45.250261,lon:-116.653146}]; 
var cartesianPoints = bounds.map(function(bound){ 
    return toCartesian(bound.lat,bound.lon); 
}); 
var centriod = getPolygonCentroid(cartesianPoints); 
var objectCoordinates = toObjectSpace(centriod,cartesianPoints); 
var scaledCoordinates = scaleCoordinates(2,objectCoordinates); 
var marginCoordinates = toWorldSpace(centriod,scaledCoordinates); 
var newLatLngs = marginCoordinates.map(function(marginCoordinate){ 
    return toLatLng(marginCoordinate.x,marginCoordinate.y,marginCoordinate.z); 
}); 


function getPolygonCentroid(vertices){ 
    var centroid = {x:0,y:0}; 
    var signedArea = 0; 
    var x0 = 0; 
    var y0 = 0; 
    var x1 = 0; 
    var y1 = 0; 
    var a = 0; 

    for (var i=0; i<vertices.length-1; i++){ 
     x0 = vertices[i].x; 
     y0 = vertices[i].y; 
     x1 = vertices[i+1].x; 
     y1 = vertices[i+1].y; 
     a = x0*y1 - x1*y0; 
     signedArea += a; 
     centroid.x += (x0 + x1)*a; 
     centroid.y += (y0 + y1)*a; 
    } 
    x0 = vertices[i].x; 
    y0 = vertices[i].y; 
    x1 = vertices[0].x; 
    y1 = vertices[0].y; 
    a = x0*y1 - x1*y0; 
    signedArea += a; 
    centroid.x += (x0 + x1)*a; 
    centroid.y += (y0 + y1)*a; 

    signedArea *= 0.5; 
    centroid.x /= (6.0*signedArea); 
    centroid.y /= (6.0*signedArea); 

    return centroid; 
} 

function toObjectSpace(centroid,worldCoordinates){ 
    var objectCoordinates = []; 
    worldCoordinates.forEach(function(worldCoordinate){ 
    var newXCoordinate = worldCoordinate.x - centroid.x; 
    var newYCoordinate = worldCoordinate.y - centroid.y; 
    var orginalZCoordinate = worldCoordinate.z; 
    objectCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate}); 
    }); 
    return objectCoordinates; 
} 

function scaleCoordinates(factor,coordinates){ 
    var scaledCoordinates = []; 
    coordinates.forEach(function(coordinate){ 
    var newXCoordinate = coordinate.x * factor; 
    var newYCoordinate = coordinate.y * factor; 
    var orginalZCoordinate = coordinate.z; 
    scaledCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate}); 
    }); 
    return scaledCoordinates; 
} 

function toWorldSpace(centroid,objectCoordinates){ 
    var worldCoordinates = []; 
    objectCoordinates.forEach(function(objectCoordinate){ 
    var newXCoordinate = objectCoordinate.x + centroid.x; 
    var newYCoordinate = objectCoordinate.y + centroid.y; 
    var orginalZCoordinate = objectCoordinate.z; 
    worldCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate}); 
    }); 
    return worldCoordinates; 
} 

var toCartesian = function(lat,lon){ 
    const R = 6371; 

    var x = R * Math.cos(deg2rad(lat)) * Math.cos(deg2rad(lon)); 
    var y = R * Math.cos(deg2rad(lat)) * Math.sin(deg2rad(lon)); 
    var z = R * Math.sin(deg2rad(lat)); 

    return { 
    x: x, 
    y: y, 
    z: z 
    } 
} 

var toLatLng = function(x,y,z){ 
    const R = 6371; 
    var lat = Math.asin(z/R); 
    var lon = Math.atan2(y, x); 
    return { 
    lat:rad2deg(lat), 
    lon:rad2deg(lon) 
    } 
} 

var deg2rad = function(deg) { 
    return deg * (Math.PI/180) 
} 

var rad2deg = function(radians) { 
    return radians * 180/Math.PI; 
}; 
+0

Haben Sie Werte nach 'toCartesian' überprüft? Sie arbeiten mit 3D-Punkten wie mit 2D-Punkten – MBo

Antwort

0

Was man braucht ist Slerp (sphärische lineare Interpolation): https://en.wikipedia.org/wiki/Slerp. Einfach "zwischen" jedem Punkt des Polygons und dem gewählten Vergrößerungs- zentrum einfügen, mit dem Parameter t als Skalierungsfaktor.