使用Eigen将经纬度、高程、偏北角转成变换矩阵

目录

1、前言

2、示例

3、代码解析

4、垂直于给定点的切平面变换

5、代码解析


1、前言

在地球表面进行刚体变换时候,要将具有经纬度、高程和偏北角的坐标信息转换为变换矩阵表达,首先需要了解坐标系之间的转换关系。

通常,我们会将经纬度坐标转换为地心坐标系(ECEF坐标系),然后再根据高程和偏北角进行变换。

2、示例

#include <iostream>
#include <Eigen/Dense>
#include <cmath>

// 定义常量
constexpr double PI = 3.14159265358979323846;
constexpr double EARTH_RADIUS = 6378137.0; // 地球半径,单位:米

// 经纬度转ECEF坐标
Eigen::Vector3d geodeticToECEF(double latitude, double longitude, double altitude) {
    double cosLat = cos(latitude * PI / 180);
    double sinLat = sin(latitude * PI / 180);
    double cosLon = cos(longitude * PI / 180);
    double sinLon = sin(longitude * PI / 180);

    double N = EARTH_RADIUS / sqrt(1 - pow(0.08181919, 2) * pow(sinLat, 2));

    double x = (N + altitude) * cosLat * cosLon;
    double y = (N + altitude) * cosLat * sinLon;
    double z = ((1 - pow(0.08181919, 2)) * N + altitude) * sinLat;

    return Eigen::Vector3d(x, y, z);
}

int main() {
    // 假设经纬度坐标为纽约市的中心,高程为0,偏北角为30度
    double latitude = 40.7128; // 纬度,单位:度
    double longitude = -74.0060; // 经度,单位:度
    double altitude = 0; // 高程,单位:米
    double heading_angle = 30; // 偏北角,单位:度

    // 经纬度转换为ECEF坐标
    Eigen::Vector3d ecef = geodeticToECEF(latitude, longitude, altitude);

    // 构造变换矩阵
    Eigen::Affine3d transformation_matrix = Eigen::Affine3d::Identity();
    transformation_matrix.translation() = ecef;

    // 对Z轴进行旋转,旋转角度为偏北角
    transformation_matrix.rotate(Eigen::AngleAxisd(heading_angle * PI / 180, Eigen::Vector3d::UnitZ()));

    // 输出变换矩阵
    std::cout << "Transformation matrix:" << std::endl << transformation_matrix.matrix() << std::endl;

    return 0;
}

3、代码解析

  • 经纬度转笛卡尔坐标

经纬度转笛卡尔坐标_经纬度转笛卡尔坐标系-CSDN博客

  • 仿射变换

同样,拓展到三维,也有一样的规律。

拓展:

细心的小伙伴,肯定会注意到,此时计算出来的变换矩阵不是我们地球表面物体的变换矩阵,为什么的?因为物体都是在给定点的切平面上摆放的,so......

4、垂直于给定点的切平面变换

// 输入经纬度、高程和偏北角
Vector3d latLonAlt(37.7749, -122.4194, 10.0); // 纬度、经度、高程
double heading = 45.0 / RAD_TO_DEG; // 偏北角

// 构造仿射变换矩阵
Affine3d transformMatrix = buildTransformMatrix(latLonAlt, heading);

// 添加垂直切平面变换
Vector3d normalVector = transformMatrix.linear().col(2); // 取仿射变换矩阵的第三列作为法向量
Vector3d pointOnPlane = transformMatrix.translation(); // 平移部分即是平面上的一点

Affine3d verticalPlaneTransform = Affine3d::Identity();    

verticalPlaneTransform.translation() = pointOnPlane; // 平移至给定点

verticalPlaneTransform.linear().col(0) = normalVector; // 设置 x 轴方向为法向量方向

// 设置 y 轴方向为法向量与 x 轴叉乘的结果,即平面上的一个方向向量
verticalPlaneTransform.linear().col(1) = Vector3d::UnitX().cross(normalVector).normalized(); 
// z 轴方向为法向量方向,保证右手坐标系
verticalPlaneTransform.linear().col(2) = normalVector; 

// 打印变换矩阵
std::cout << "Transform Matrix:" << std::endl << transformMatrix.matrix() << std::endl;
std::cout << "Vertical Plane Transform Matrix:" << std::endl << verticalPlaneTransform.matrix() << std::endl;

5、代码解析

  • 怎么定切平面的法向量

从仿射变换矩阵中提取法向量,您可以简单地提取矩阵的旋转部分的第三列(或者第三行,根据矩阵的定义)。在仿射变换中,旋转矩阵描述了变换的旋转部分,而第三列(或第三行)代表了变换后的 z 轴方向,因此它也是平面的法向量。

对于仿射变换矩阵来说,通常我们使用列向量表示基向量的变换。在三维仿射变换中,通常情况下,矩阵的前三列描述了变换后的基向量在原基向量上的坐标,其中第一列是 x 轴方向,第二列是 y 轴方向,第三列是 z 轴方向。

因此,对于一个仿射变换矩阵,第三列描述了变换后的 z 轴方向,这也就是平面的法向量。而平面的法向量描述了平面的法线方向,因此我们可以从仿射变换矩阵的第三列提取出平面的法向量。

// 定义一个仿射变换矩阵
    Affine3d transformMatrix = Affine3d::Identity();
    transformMatrix.translation() << 1.0, 2.0, 3.0;
    transformMatrix.linear() << 1.0, 0.0, 0.0,
                                 0.0, 1.0, 0.0,
                                 0.0, 0.0, 1.0;

// 提取法向量
Vector3d normalVector = transformMatrix.linear().col(2);

// 打印法向量
std::cout << "Normal Vector:" << std::endl << normalVector << std::endl;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/622410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

攻防演练-防守单位常见防守策略

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 防守单位常见防守策略 01 防守单位常见防守策略 为普及网络安全知识&#xff0c;提高网络安全防范意识&#xff0c;和网络安全工作技能。我们将向大家介绍网络安全攻防演练中防守单位的一些关键策…

自回归模型的优缺点及改进方向

在学术界和人工智能产业中&#xff0c;关于自回归模型的演进与应用一直是一个引发深入讨论和多方观点交锋的热门议题。尤其是Yann LeCun&#xff0c;这位享誉全球的AI领域学者、图灵奖的获得者&#xff0c;以及被誉为人工智能领域的三大巨擘之一&#xff0c;他对于自回归模型持…

2.三极管

2.习题 3.知识补充

ssm125四六级报名与成绩查询系统+jsp

四六级报名与成绩查询系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对四六级报名信息管理混乱&am…

最短路(图论学习总结部分内容)

文章目录 前言二、最短路多源最短路 F l o y d Floyd Floyd​ 算法例题及变形 e g 1 &#xff1a; S o r t i n g I t A l l O u t eg1&#xff1a;Sorting\ It\ All\ Out eg1&#xff1a;Sorting It All Out ( 蓝书例题&#xff0c;传递闭包 ) (蓝书例题&#xff0c;传递闭包…

pytest教程-44-钩子函数-pytest_report_collectionfinish

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_report_header钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_report_collectionfinish钩子函数的使用方法。 pytest_report_collectionfinish 钩子函数在 pytest 完成所有测…

python智能电力监控与资费电费缴纳管理系统vue+django

本系统的设计与实现共包含6个表:分别是配置文件信息表&#xff0c;电力记录信息表&#xff0c;故障报修信息表&#xff0c;缴费订单信息表&#xff0c;用户表信息表&#xff0c;用户信息表&#xff0c; 本文所设计的电费缴纳系统的设计与实现拥有前端和后端&#xff0c;前端使…

C++入门必读-Qt的菜单控件

菜单控件 QT提供的菜单控件&#xff0c;可以帮助我们完成如下菜单的制作。这在项目开发中非常有用。 移除默认的菜单 从头开发菜单控件&#xff0c;我们先移除默认的菜单栏。 创建菜单栏 在窗体空白处&#xff0c;鼠标右键点击选择《创建菜单栏》 添加菜单内容 继续输入子菜单,…

有哪些可以用电脑做的挣钱副业,有电脑就行

以下是一些可以用电脑做的挣钱副业 1. 写作和翻译 可以在各大网络平台上接单进行写作或者翻译。 2. 做任务 还在做致米宝库这个软件&#xff0c;软件每天会发布一些项目任务&#xff0c;也能学到一些网上赚钱的知识技术&#xff0c;我平时就做些简单任务和一个虚拟项目。 任…

FPGA+炬力ARM实现VR视频播放器方案,3D眼镜显示

3D眼镜显示&#xff1a; FPGA炬力ARM方案&#xff0c;单个视频源信号&#xff0c;同时驱动两个LCD屏显示&#xff0c;实现3D 沉浸式播放 客户应用&#xff1a;VR视频播放器 主要功能&#xff1a; 1.支持多种格式视频文件播放 2.支持2D/3D 效果实时切换播放 3.支持TF卡/U盘文…

日志的基本用法

目标 1. 掌握如何设置日志级别 2. 掌握如何设置日志格式 3. 掌握如何将日志信息输出到文件中 1. logging模块 Python中有一个标准库模块logging可以直接记录日志 1.1 基本用法 import logging logging.debug("这是一条调试信息") logging.info("这是一条…

【opencv】信用卡号识别实验

实验环境&#xff1a;anaconda、jupyter notebook&#xff08;其它的ide也行&#xff09; 实验用的包&#xff1a;numpy、matplotlib、opencv 实验目标&#xff1a; 识别信用卡的卡号 信用卡图片&#xff1a; 数字模板图片&#xff1a; 一、包引入 import cv2 import matplo…

Apollo9.0 Control模块算法源码学习

参考资料 Apollo控制算法_哔哩哔哩_bilibili

JSR303数据校验 —— @Valid嵌套校验、集合校验

1. 依赖版本 &#xff08;1&#xff09;SpringBoot 3.1.11 &#xff08;2&#xff09;JDK17 2. Valid、Validated 简介 说明&#xff1a;在Spring框架中Valid默认不会对集合&#xff08;List、Set等&#xff09;内部的元素进行校验&#xff0c;需要将Spring提供的Validated注…

电信网关配置管理系统 rewrite.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

力扣HOT100 - 118. 杨辉三角

解题思路&#xff1a; 每个数字等于上一行的左右两个数字之和。 class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> res new ArrayList<>();for (int i 0; i < numRows; i) {List<Integer> …

(done) Beam search

参考视频1&#xff1a;https://www.bilibili.com/video/BV1Gs421N7S1/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 &#xff08;beam search 视频&#xff09; 参考博客1&#xff1a;https://jasonhhao.github.io/2020/06/19/…

鸿蒙ArkUI开发:常用布局【主轴】

ArkUI中常用布局容器 线性布局&#xff08;Row/Column&#xff09; 线性布局的子元素在线性方向上&#xff08;水平方向和垂直方向&#xff09;依次排列线性布局容器包括[Row]和[Column]。Column容器内子元素按照垂直方向排列&#xff0c;Row容器内子元素按照水平方向排列开发…

vc小程序源码:利用opencv 实现九宫格切图

#include "stdafx.h" #include<opencv2/opencv.hpp> using namespace std; using namespace cv;int main() {Mat src imread("福利.png");if (src.empty()){cout << "No Image!" << endl;system("pause");return -…

PCIE协议-2-事务层规范-Completion Rules

2.2.9 完成规则 所有Read、Non-Posted Write和AtomicOp请求都需要完成&#xff08;Completion&#xff09;。完成包含一个完成头标&#xff0c;对于某些类型的完成&#xff0c;完成头标之后会跟随一定数量的DWs数据。完成头标的每个字段的规则在以下各节中定义。 完成通过ID路…