1. cs::cartesian ------ 笛卡尔坐标系(直角坐标系)
原始描述翻译 :
定义笛卡尔(或称矩形)坐标系,其中点由两个、三个或更多维度的坐标表示,通常(但不总是)记作 x, y, z。
扩展说明 :
笛卡尔坐标系是最基础、最常用的坐标系统,适用于平面或欧几里得空间中的几何计算。在二维情形下,一个点由横坐标 x 和纵坐标 y 唯一确定;在三维情形下,增加高度坐标 z。该坐标系假设空间是平坦的(即无曲率),因此适用于局部区域的地图投影、工程建模、计算机图形学等场景。Boost.Geometry 中的许多算法(如距离、面积、交集等)默认基于笛卡尔坐标系实现,因其计算效率高且数学形式简洁。
适用场景:
- 城市地图、CAD 设计、2D 游戏引擎
- 小范围平面距离、面积、交集等计算
C++ 示例:计算两点间距离与多边形面积
cpp
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry;
int main() {
// 使用笛卡尔坐标系的 2D 点(默认即为 cartesian)
using point = bg::model::d2::point_xy<double>;
using polygon = bg::model::polygon<point>;
point p1(0.0, 0.0);
point p2(3.0, 4.0);
double dist = bg::distance(p1, p2);
std::cout << "笛卡尔距离: " << dist << " (应为 5.0)\n";
// 构建一个正方形
polygon poly;
bg::exterior_ring(poly).assign({
{0, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0}
});
double area = bg::area(poly);
std::cout << "笛卡尔面积: " << area << " (应为 4.0)\n";
return 0;
}
2. cs::geographic ------ 地理坐标系
原始描述翻译 :
定义地理坐标系,其中点由两个角度表示,通常称为纬度/经度(lat/long)、经度/纬度(lo/la)或 φ/λ(phi/lambda)。
扩展说明 :
地理坐标系用于在地球椭球体(或近似球体)表面定位点,使用**纬度(Latitude)和 经度(Longitude)两个角度参数。纬度范围为 -90° 到 +90°(南纬到北纬),经度范围为 -180° 到 +180°(西经到东经)。Boost.Geometry 支持以 度(degree)或弧度(radian)**为单位输入角度。
地理坐标系本身不包含投影信息,因此不能直接用于平面距离或面积计算------必须通过大地测量算法(如 Vincenty、Andoyer)或先投影到平面坐标系(如 UTM)再处理。Boost.Geometry 内置了对球面或椭球面距离、方位角等的高精度支持。
适用场景:
- GPS 轨迹分析、全球导航、GIS 系统
- 需要高精度大地测量距离(如 Vincenty 算法)
C++ 示例:计算两个城市间的球面距离(WGS84 椭球)
cpp
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace bg = boost::geometry;
namespace cs = bg::cs;
// 定义地理坐标系下的点(角度单位:度)
using point_geo = bg::model::point<double, 2, cs::geographic<bg::degree>>;
int main() {
// 北京 (39.9°N, 116.4°E) 与 上海 (31.2°N, 121.5°E)
point_geo beijing(116.4, 39.9);
point_geo shanghai(121.5, 31.2);
// 使用默认策略(Andoyer 近似,适用于球面)
double dist_meters = bg::distance(beijing, shanghai);
std::cout << "北京到上海距离(近似): " << dist_meters / 1000.0 << " km\n";
// 使用更精确的策略(需指定椭球)
bg::srs::spheroid<double> wgs84(6378137.0, 6356752.3142451793);
bg::strategy::distance::geographic<bg::strategy::vincenty> vincenty(wgs84);
double dist_vincenty = bg::distance(beijing, shanghai, vincenty);
std::cout << "Vincenty 精确距离: " << dist_vincenty / 1000.0 << " km\n";
return 0;
}
3. cs::spherical ------ 球面坐标系(极坐标形式)
原始描述翻译 :
定义球面坐标系,其中点由两个角度和一个可选半径表示,通常记作 r, θ, φ(半径、极角、方位角)。
扩展说明 :
这是数学和物理学中常见的球坐标系(Spherical Polar Coordinates) 。在 Boost.Geometry 的上下文中,通常用于单位球面上的点表示(即 r = 1 固定),仅用两个角度描述方向:
- θ(theta):极角(polar angle),从正 z 轴(北极)向下测量,范围 [0, π] 弧度(0°~180°);
- φ(phi):方位角(azimuthal angle),在 xy 平面内从正 x 轴逆时针测量,范围 [0, 2π) 弧度(0°~360°)。
注意:此系统中,θ = 0 对应北极,θ = π/2 对应赤道,θ = π 对应南极。这与地理坐标系中"纬度从赤道起算"不同。
适用场景:
- 天体物理方向、3D 图形光照、雷达波束建模
C++ 示例:计算单位球面上两点间的大圆距离
cpp
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace bg = boost::geometry;
namespace cs = bg::cs;
// 使用弧度单位的球面坐标(theta, phi)
using point_sph = bg::model::point<double, 2, cs::spherical<bg::radian>>;
int main() {
// 北极点:θ=0, φ任意
point_sph north_pole(0.0, 0.0);
// 赤道上某点:θ=π/2, φ=0
point_sph equator(1.5708, 0.0); // ≈ π/2
// 球面距离(单位球,结果为弧度)
double angular_dist = bg::distance(north_pole, equator);
std::cout << "球面角距离(弧度): " << angular_dist << "\n";
std::cout << "对应弧长(单位球): " << angular_dist << "\n"; // 半径=1
return 0;
}
4. cs::spherical_equatorial ------ 球面赤道坐标系
原始描述翻译 :
该坐标系类似于地理坐标系,纬度从赤道(0°)向上增至极点(90°),与球面(极)坐标系相反。常用于天文学和 GIS(但也存在地理坐标系)。
扩展说明 :
这是一种以赤道为基准的球面角度系统,结构上非常接近地理坐标系:
- 第一个角度为纬度(Latitude),从赤道(0°)向北(+90°)或向南(-90°)测量;
- 第二个角度为经度(Longitude),从本初子午线向东或向西测量。
关键区别在于:虽然形式类似 geographic,但 spherical_equatorial 明确假设地球为完美球体 (而非椭球体),且主要用于天文学中的赤道坐标系统 (如赤经/赤纬,但此处简化为角度对)。在 Boost.Geometry 中,它与 geographic 的主要差异在于内部算法假设 :geographic 可支持椭球模型,而 spherical_equatorial 始终按球面处理。
适用场景:
- 天文赤道坐标、教学演示、快速球面近似计算
C++ 示例:计算两点间球面距离(单位球)
cpp
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace bg = boost::geometry;
namespace cs = bg::cs;
// 使用度为单位的赤道球面坐标(lat, lon)
using point_eq = bg::model::point<double, 2, cs::spherical_equatorial<bg::degree>>;
int main() {
// 纽约 (40.7°N, 74.0°W) 与 伦敦 (51.5°N, 0.1°W)
point_eq ny(-74.0, 40.7); // 注意:经度在前!
point_eq london(-0.1, 51.5);
// 默认使用 haversine 公式(球面)
double dist_rad = bg::distance(ny, london);
double earth_radius_km = 6371.0;
std::cout << "纽约-伦敦距离(球面近似): "
<< dist_rad * earth_radius_km << " km\n";
return 0;
}
5. 坐标系对比总结
| 坐标系类型 | 维度 | 参数 | 单位 | 地球模型 | 典型用途 |
|---|---|---|---|---|---|
cartesian |
2D/3D | x, y (, z) | 长度(米等) | 平面(无曲率) | 局部地图、工程设计 |
geographic |
2D | 纬度, 经度 | 角度(° 或 rad) | 椭球(可选球) | GPS、全球定位 |
spherical |
2D(方向) | 极角 θ, 方位角 φ | 角度 | 单位球 | 物理、3D 图形 |
spherical_equatorial |
2D | 纬度, 经度 | 角度 | 完美球体 | 天文、简化 GIS |
使用建议
- 若处理真实地球上的位置 (如来自 GPS 的数据),优先使用
cs::geographic,并配合 WGS84 椭球参数。 - 若进行小范围平面计算 (如城市内路径规划),可将地理坐标投影为
cs::cartesian(如使用 UTM 投影)。 - 若仅需方向或单位球面上的点 (如卫星指向、星空模拟),可选用
cs::spherical或cs::spherical_equatorial,根据纬度定义习惯选择后者。