从旧坐标和x和y计算新坐标

时间:2013-03-12 18:02:25

标签: java math coordinates

我在现实生活中有以下项目设置:

My setup

雷达是静止的,这意味着它始终具有相同的位置。 A - 项可以移动,其位置可以是任何位置。从雷达中我可以读取与x相关的yA坐标。我写了以下几个类来描述每个项目的位置:

public class Position {
    public enum Direction {
        EAST, WEST, NORTH, SOUTH
    };

    public final Direction latitudeDirection, longitudeDirection;
    public final float latitude, longitude, altitude;

    public Position(Direction latitudeDirection, Direction longitudeDirection,
            float latitude, float longitude, float altitude) {
        this.latitudeDirection = latitudeDirection;
        this.longitudeDirection = longitudeDirection;
        this.latitude = latitude;
        this.longitude = longitude;
        this.altitude = altitude;
    }

    public Position(float radarX, float radarY) {
        // TODO: Implement the question here
        this.altitude = Config.RADAR_POSITION.altitude;
    }

}

class Config {
    // Position of the radar
    public static final Position RADAR_POSITION = new Position(
            Position.Direction.NORTH, // Latitude direction
            Position.Direction.EAST, // Longitude direction
            55.0f, // Latitude
            13.0f, // Longitude
            60.0f); // Altitude

    // Facing direction of the radar in degrees. 0° is north, advancing
    // clockwise.
    public static final float RADAR_FACING_DIRECTION = 10.0f;
}

现在给定雷达的地理坐标,x相对于雷达的yA坐标以及雷达相对于北方的面向方向,我该怎么办?计算A的绝对地理坐标?

地球的曲率不是问题,因为x和/或y的最大值不能超过几百米。

6 个答案:

答案 0 :(得分:3)

例如,您可以使用三角函数创建三角形以查找A:

的坐标

Example of using trigonometric functions

在这种情况下,Ax =(y)(cos 10) - (x)(cos 80),你可以类似地计算出Ay。

这样,你就不会陷入学位,你只是以米为单位工作。

强大的解决方案是Vishal在OP中的评论,该评论是在我绘图和扫描时发布的:

xnew = x * cos(theta) - y * sin(theta); 
ynew = x * sin(theta) + y * cos(theta);

答案 1 :(得分:2)

通常,您可以使用以下步骤:

  1. 将您的雷达位置(纬度,经度,高度)转换为公制地球中心地球固定xyz系统(ECEF)
  2. 然后,您可以在此度量系统中使用/组合任何描述雷达旋转和对象位置的旋转和平移参数/矩阵
  3. 将新获取的xzy坐标转换为lat / lon / h
  4. 这种转换有很多资源,请检查一下,例如:http://www.gmat.unsw.edu.au/snap/gps/clynch_pdfs/coordcvt.pdf

    如果需要,您还可以引入场景坐标系(ENU)。以下是描述UTM,ECEF,ENU和地理坐标(Lat / lon / h)关系的相当好的概述: http://www.dirsig.org/docs/new/coordinates.html

    如果您需要ECEF到/来自大地测量转换的示例代码,请查看matlab代码http://www.mathworks.de/de/help/map/ref/ecef2geodetic.html, 或使用像GDAL(http://www.gdal.org/

    这样的库

答案 2 :(得分:1)

我认为应该可以这样做:将xy坐标转换为极坐标rtheta,(将雷达作为起源)。减去雷达的旋转,然后转换回笛卡尔坐标。然后你只需要转换为纬度和经度并添加雷达的坐标。

double r = Math.hypot(radarX, radarY);
double theta = Math.atan2(radarY, radarX);
theta -= Math.toRadians(Config.RADAR_FACING_DIRECTION);
float x = (float) r * Math.cos(theta);
float y = (float) r * Math.sin(theta);
longitude = metersToLongitude(Config.RADAR_POSITION, y) + Config.RADAR_POSITION.longitude;
latitude = metersToLatitude(Config.RADAR_POSITION, x) + Config.RADAR_POSITION.latitude;

我在维基百科上找到了纬度和经度长度的公式。纬度在任何地方都是相同的,但经度在极点附近变小。

static float metersToLatitude(Position near, float meters) {
    return meters / 110.6*1000;
}

static float metersToLongitude(Position near, float meters) {
    float lat = Math.toRadians(near.latitude);
    return meters /
        (111132.954 - 559.822 * Math.cos(2*lat) + 1.175 * Math.cos(4*lat));
}

不幸的是,这似乎不起作用,我无法弄清楚原因。

如果你想以东/西/北/南的正度表示你的坐标,你还必须检查它们是否为负并反转它们和那个方向的方向。

答案 3 :(得分:1)

答案 4 :(得分:1)

最后我解决了。代码附在下面。由于Samuel Edwin Ward的回答是启发我的回答,我会接受他的回答。

public Position(float radarX, float radarY) {

    // Convert A's position to distance and bearing in relation to the North 
    double objDistance = (Math.hypot(radarX, radarY) / 6367500 /* Mean earth radius */);
    double objBearing = (Math.atan2(radarY, radarX) + Math.toRadians(Config.RADAR_BEARING));

    // Convert the Radar's geographic coordinates to radians
    double latitudeRadar = Math.toRadians(Config.RADAR_POSITION.latitude);
    double longitudeRadar = Math.toRadians(Config.RADAR_POSITION.longitude);

    // Calculate A's geographic coordinates in radians
    double latitudeObject = Math.asin(Math.sin(latitudeRadar)*Math.cos(objDistance) + 
            Math.cos(latitudeRadar)*Math.sin(objDistance)*Math.cos(objBearing));
    double longitudeObject = longitudeRadar + Math.atan2(Math.sin(objBearing)*Math.sin(objDistance)*Math.cos(latitudeRadar), 
            Math.cos(objDistance)-Math.sin(latitudeRadar)*Math.sin(latitudeObject));

    // Normalize to -180 ... +180 degrees
    longitudeObject = (longitudeObject+3*Math.PI) % (2*Math.PI) - Math.PI;  

    // Set the A's coordinates in degrees
    this.latitude = (float) Math.toDegrees(latitudeObject);
    this.longitude = (float) Math.toDegrees(longitudeObject);

    // Set the rest of the arguments
    this.latitudeDirection = Config.RADAR_POSITION.latitudeDirection;
    this.longitudeDirection = Config.RADAR_POSITION.longitudeDirection;
    this.altitude = Config.RADAR_POSITION.altitude;
}

答案 5 :(得分:0)

您可以旋转雷达本地系统中的所有坐标-10°,然后只需将雷达的x / y坐标添加到A对象坐标。