test

public class AdvancedAzimuthRangeChecker {
/**
* 标准化经度差,处理跨越180°经线的情况
* 确保经度差在[-π, π]弧度范围内
*/
private static double normalizeLongitudeDifference(double degrees) {
double radians = Math.toRadians(degrees);
// 将角度标准化到[-π, π]范围
while (radians > Math.PI) radians -= 2 * Math.PI;
while (radians < -Math.PI) radians += 2 * Math.PI;
return radians;
}

public static double calculateAzimuth(double lat1, double lon1, double lat2, double lon2) {
// 处理经度跨越180°的情况
double dLon = normalizeLongitudeDifference(lon2 - lon1);

double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);

// 使用标准化后的经度差
double y = Math.sin(dLon) * Math.cos(lat2Rad);
double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);

double azimuthRad = Math.atan2(y, x);
double azimuthDeg = Math.toDegrees(azimuthRad);
return (azimuthDeg + 360) % 360;
}

/**
* 判断楼宇是否在指定方位角和距离范围内
*/
public static boolean isInAzimuthAndDistanceRange(double objectLat, double objectLon,
double buildingLat, double buildingLon,
double targetAzimuth, double azimuthTolerance,
double maxDistance) {
// 计算方位角
double actualAzimuth = calculateAzimuth(objectLat, objectLon, buildingLat, buildingLon);

// 计算距离
double distance = calculateDistance(objectLat, objectLon, buildingLat, buildingLon);

// 检查方位角偏差
double azimuthDiff = Math.abs(actualAzimuth - targetAzimuth);
azimuthDiff = Math.min(azimuthDiff, 360 - azimuthDiff);

return azimuthDiff <= azimuthTolerance && distance <= maxDistance;
}

/**
* 计算两点之间的距离(米)
*/
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
double earthRadius = 6371000; // 地球半径(米)

double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);

double dLat = lat2Rad - lat1Rad;
double dLon = lon2Rad - lon1Rad;

double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(dLon/2) * Math.sin(dLon/2);

double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

return earthRadius * c;
}

// calculateAzimuth 方法同上



public static void main(String[] args) {
// 监控摄像头位置
double cameraLat = 39.9087;
double cameraLon = 116.3975;

// 重要楼宇列表
double[][] importantBuildings = {
{39.9095, 116.3980}, // 银行
{39.9070, 116.3960}, // 政府大楼
{39.9100, 116.3950} // 医院
};

String[] buildingNames = {"银行", "政府大楼", "医院"};

// 监控方向:正东方向(90°)±20°
double monitorAzimuth = 90;
double tolerance = 20;

System.out.println("监控范围内的楼宇:");
for (int i = 0; i < importantBuildings.length; i++) {
boolean inRange = AzimuthRangeChecker.isInAzimuthRange(
cameraLat, cameraLon,
importantBuildings[i][0], importantBuildings[i][1],
monitorAzimuth, tolerance
);

if (inRange) {
double azimuth = AzimuthRangeChecker.calculateAzimuth(
cameraLat, cameraLon,
importantBuildings[i][0], importantBuildings[i][1]
);
System.out.printf("%s: 方位角=%.2f°%n", buildingNames[i], azimuth);
}
}
}
}











import java.lang.Math;

public class AzimuthCalculator {

/**
* 计算两点之间的方位角(从正北方向顺时针角度)
* @param lat1 起点纬度(度)
* @param lon1 起点经度(度)
* @param lat2 终点纬度(度)
* @param lon2 终点经度(度)
* @return 方位角(度),范围0-360
*/
public static double calculateAzimuth(double lat1, double lon1, double lat2, double lon2) {
// 将角度转换为弧度
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);

double dLon = lon2Rad - lon1Rad;
/**
*
* sin(dLon):经度差的正弦值,影响东西方向的分量
*
* cos(dLon):经度差的余弦值,影响距离计算中的校正因子
*/
double y = Math.sin(dLon) * Math.cos(lat2Rad);
double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);

double azimuthRad = Math.atan2(y, x);

// 将弧度转换为度,并确保角度在0-360范围内
double azimuthDeg = Math.toDegrees(azimuthRad);
return (azimuthDeg + 360) % 360;
}

/**
* 计算反向方位角(从终点到起点的方位角)
*/
public static double calculateReverseAzimuth(double lat1, double lon1, double lat2, double lon2) {
return calculateAzimuth(lat2, lon2, lat1, lon1);
}

public static void main(String[] args) {
// 测试示例
double lat1 = 39.9087; // 北京纬度
double lon1 = 116.3975; // 北京经度

double lat2 = 31.2304; // 上海纬度
double lon2 = 121.4737; // 上海经度

double azimuth = calculateAzimuth(lat1, lon1, lat2, lon2);
double reverseAzimuth = calculateReverseAzimuth(lat1, lon1, lat2, lon2);

System.out.println("从北京到上海的方位角: " + String.format("%.2f", azimuth) + "°");
System.out.println("从上海到北京的方位角: " + String.format("%.2f", reverseAzimuth) + "°");

// 更多测试用例
System.out.println("\n更多测试:");
testAzimuth(0, 0, 0, 1); // 正东方向
testAzimuth(0, 0, 1, 0); // 正北方向
testAzimuth(0, 0, 0, -1); // 正西方向
testAzimuth(0, 0, -1, 0); // 正南方向
}

private static void testAzimuth(double lat1, double lon1, double lat2, double lon2) {
double azimuth = calculateAzimuth(lat1, lon1, lat2, lon2);
System.out.println("从(" + lat1 + "," + lon1 + ") 到 (" +
lat2 + "," + lon2 + ") 的方位角: " +
String.format("%.2f", azimuth) + "°");
}
}







import java.lang.Math;

public class AzimuthRangeChecker {

/**
* 判断楼宇是否在物体方位角的正负范围内
* @param objectLat 物体纬度(度)
* @param objectLon 物体经度(度)
* @param buildingLat 楼宇纬度(度)
* @param buildingLon 楼宇经度(度)
* @param targetAzimuth 目标方位角(度,0-360)
* @param tolerance 容差范围(度,正负值)
* @return 是否在范围内
*/
public static boolean isInAzimuthRange(double objectLat, double objectLon,
double buildingLat, double buildingLon,
double targetAzimuth, double tolerance) {
// 计算从物体到楼宇的实际方位角
double actualAzimuth = calculateAzimuth(objectLat, objectLon, buildingLat, buildingLon);

// 计算方位角差值(考虑360°循环)
double diff = Math.abs(actualAzimuth - targetAzimuth);
diff = Math.min(diff, 360 - diff); // 处理跨越360°的情况

return diff <= tolerance;
}

/**
* 计算两点之间的方位角
*/
public static double calculateAzimuth(double lat1, double lon1, double lat2, double lon2) {
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);

double dLon = lon2Rad - lon1Rad;

double y = Math.sin(dLon) * Math.cos(lat2Rad);
double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);

double azimuthRad = Math.atan2(y, x);
double azimuthDeg = Math.toDegrees(azimuthRad);
return (azimuthDeg + 360) % 360;
}

/**
* 批量判断多个楼宇
*/
public static boolean[] areInAzimuthRange(double objectLat, double objectLon,
double[][] buildings, // [ [lat, lon], ... ]
double targetAzimuth, double tolerance) {
boolean[] results = new boolean[buildings.length];
for (int i = 0; i < buildings.length; i++) {
results[i] = isInAzimuthRange(objectLat, objectLon,
buildings[i][0], buildings[i][1],
targetAzimuth, tolerance);
}
return results;
}

/**
* 获取方位角偏差值
*/
public static double getAzimuthDeviation(double objectLat, double objectLon,
double buildingLat, double buildingLon,
double targetAzimuth) {
double actualAzimuth = calculateAzimuth(objectLat, objectLon, buildingLat, buildingLon);
double diff = Math.abs(actualAzimuth - targetAzimuth);
return Math.min(diff, 360 - diff);
}


public static void main(String[] args) {
// 物体位置(观察点)
double objectLat = 39.9087; // 北京
double objectLon = 116.3975;

// 多个楼宇位置
double[][] buildings = {
{39.9090, 116.3980}, // 楼宇1:很近,正北方向
{39.9200, 116.3975}, // 楼宇2:正北方向
{39.9087, 116.4075}, // 楼宇3:正东方向
{39.9000, 116.3975}, // 楼宇4:正南方向
{39.9087, 116.3875} // 楼宇5:正西方向
};

// 检查是否在正北方向(0°)的±10°范围内
double targetAzimuth = 0; // 正北方向
double tolerance = 10; // ±10°范围

System.out.println("检查楼宇是否在正北方向±10°范围内:");
for (int i = 0; i < buildings.length; i++) {
boolean inRange = AzimuthRangeChecker.isInAzimuthRange(
objectLat, objectLon,
buildings[i][0], buildings[i][1],
targetAzimuth, tolerance
);

double actualAzimuth = AzimuthRangeChecker.calculateAzimuth(
objectLat, objectLon, buildings[i][0], buildings[i][1]
);

System.out.printf("楼宇%d: 方位角=%.2f°, 在范围内=%b%n",
i+1, actualAzimuth, inRange);
}

// 检查是否在东北方向(45°)的±15°范围内
System.out.println("\n检查楼宇是否在东北方向45°±15°范围内:");
targetAzimuth = 45;
tolerance = 15;

for (int i = 0; i < buildings.length; i++) {
boolean inRange = AzimuthRangeChecker.isInAzimuthRange(
objectLat, objectLon,
buildings[i][0], buildings[i][1],
targetAzimuth, tolerance
);

double actualAzimuth = AzimuthRangeChecker.calculateAzimuth(
objectLat, objectLon, buildings[i][0], buildings[i][1]
);

System.out.printf("楼宇%d: 方位角=%.2f°, 在范围内=%b%n",
i+1, actualAzimuth, inRange);
}
}
}









posted @ 2025-08-28 23:25  good白  阅读(12)  评论(0)    收藏  举报