3D坐标下,一点在某一线段上的左右方向的判定

server/2024/12/29 6:28:23/

3D坐标下,一点在某一线段上的左右方向的判定

  • 代码

代码

#include <iostream>
#include <Eigen/Dense>#define M_PI 3.1415926// 计算三点组成平面的参数和变换到XOY平面的变换矩阵
void computePlaneAndTransform(const Eigen::Vector3d& P1, const Eigen::Vector3d& P2, const Eigen::Vector3d& P3,Eigen::Vector4d& planeParams, Eigen::Matrix4d& transformMatrix) {// 确保P1在原点assert((P1 - Eigen::Vector3d::Zero()).norm() < 1e-6);// 计算平面的法向量Eigen::Vector3d normal = P2.cross(P3);normal.normalize();std::cout << "z = " << normal.z() << std::endl;if (normal.z() < 0) {normal = -1 * normal;}std::cout << "z2 = " << normal.z() << std::endl;// 平面方程为 Ax + By + Cz + D = 0,这里P1在原点,D = 0planeParams << normal.x(), normal.y(), normal.z(), 0;// 计算旋转矩阵,使得平面的法向量与Z轴对齐Eigen::Vector3d zAxis(0, 0, 1);double cosTheta = normal.dot(zAxis);Eigen::Vector3d crossProduct = normal.cross(zAxis);double sinTheta = crossProduct.norm();if (sinTheta < 1e-6) {// 特殊情况,法向量与Z轴平行或反平行if (cosTheta < 0) {// 法向量与Z轴反平行transformMatrix = Eigen::Matrix4d::Identity();transformMatrix.block<3, 3>(0, 0) = Eigen::AngleAxisd(M_PI, Eigen::Vector3d(1, 0, 0)).toRotationMatrix();} else {// 法向量与Z轴平行transformMatrix = Eigen::Matrix4d::Identity();}} else {crossProduct.normalize();Eigen::Matrix3d rotationMatrix;rotationMatrix << cosTheta + crossProduct.x() * crossProduct.x() * (1 - cosTheta),crossProduct.x()* crossProduct.y()* (1 - cosTheta) - crossProduct.z() * sinTheta,crossProduct.x()* crossProduct.z()* (1 - cosTheta) + crossProduct.y() * sinTheta,crossProduct.y()* crossProduct.x()* (1 - cosTheta) + crossProduct.z() * sinTheta,cosTheta + crossProduct.y() * crossProduct.y() * (1 - cosTheta),crossProduct.y()* crossProduct.z()* (1 - cosTheta) - crossProduct.x() * sinTheta,crossProduct.z()* crossProduct.x()* (1 - cosTheta) - crossProduct.y() * sinTheta,crossProduct.z()* crossProduct.y()* (1 - cosTheta) + crossProduct.x() * sinTheta,cosTheta + crossProduct.z() * crossProduct.z() * (1 - cosTheta);transformMatrix.setIdentity();transformMatrix.block<3, 3>(0, 0) = rotationMatrix;}
}// 判断点在向量的哪一侧
int determineSide(const Eigen::Vector3d& p4, const Eigen::Vector3d& p5, const Eigen::Vector3d& p6) {// 投影到XOY平面Eigen::Vector2d p4_2d = p4.head<2>();Eigen::Vector2d p5_2d = p5.head<2>();Eigen::Vector2d p6_2d = p6.head<2>();// 计算向量 P4->P5 和 P4->P6Eigen::Vector2d v1 = p5_2d - p4_2d;Eigen::Vector2d v2 = p6_2d - p4_2d;double crossResult = v1.x() * v2.y() - v1.y() * v2.x();std::cout << "crossResult = " << crossResult << std::endl;if (crossResult < 0) {// 右侧return 1;} else if (crossResult > 0) {// 左侧return 2;} else {// 共线return 0;}
}int main() {Eigen::Vector3d P1 = Eigen::Vector3d::Zero();Eigen::Vector3d P2(10, -10, -13);Eigen::Vector3d P3(0, 15, 0);Eigen::Vector4d planeParams;Eigen::Matrix4d mat;computePlaneAndTransform(P1, P2, P3, planeParams, mat);// 将点变换到XOY平面Eigen::Vector3d P4 = (mat * Eigen::Vector4d(P1.x(), P1.y(), P1.z(), 1)).head<3>();Eigen::Vector3d P5 = (mat * Eigen::Vector4d(P2.x(), P2.y(), P2.z(), 1)).head<3>();Eigen::Vector3d P6 = (mat * Eigen::Vector4d(P3.x(), P3.y(), P3.z(), 1)).head<3>();std::cout << "x, y, z = " << P4.x() << ", " << P4.y() << ", " << P4.z() << std::endl;std::cout << "x, y, z = " << P5.x() << ", " << P5.y() << ", " << P5.z() << std::endl;std::cout << "x, y, z = " << P6.x() << ", " << P6.y() << ", " << P6.z() << std::endl;int side = determineSide(P4, P5, P6);std::cout << "P3在向量P1->P2的";if (side == 1) {std::cout << "右侧" << std::endl;} else if (side == 2) {std::cout << "左侧" << std::endl;} else {std::cout << "共线" << std::endl;}system("pause");return 0;
}

http://www.ppmy.cn/server/154119.html

相关文章

Visual Studio 2017 配置 OpenCV 4.5.5 及二次配置的导入

重点参考&#xff1a; Visual Studio 2017 OpenCV_4.5.0安装_opencv4.5.0下载-CSDN博客 VS2017配置OpenCV4.5_vs2017 opencv4.5.4-CSDN博客 下载准备工作就不说了&#xff0c;直接从官网下载就行了。 关键就两步&#xff1a; 1&#xff09;将OpenCV的bin目录添加到环境变量…

leetcode热题100(240. 搜索二维矩阵 II)c++

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

编译openssl遇到错误Parse errors: No plan found in TAP output的解决方法

在编译openssl时 tar -zxvf openssl-1.1.1p.tar.gz cd openssl-1.1.1p ./config --prefix/usr --openssldir/etc/ssl --shared zlib make make test 遇到错误 Parse errors: No plan found in TAP output 解决方法&#xff1a; yum install perl-Test-Simple

Binoculars——分析证实大语言模型生成文本的检测和引用量按学科和国家明确显示了使用偏差的多样性和对内容类型的影响

摘要 论文地址&#xff1a;https://www.biorxiv.org/content/10.1101/2024.03.25.586710v2.full.pdf 人工智能技术的进步正在改变数字内容生产和消费的格局。尤其值得注意的是生成式人工智能的快速发展&#xff0c;包括大规模语言模型&#xff0c;如 ChatGPT&#xff0c;它出现…

【Halcon】例程讲解:基于形状匹配与OCR的多图像处理(附图像、程序下载链接)

1. 开发需求 在参考图像中定义感兴趣区域&#xff08;ROI&#xff09;&#xff0c;用于形状匹配和文本识别。通过形状匹配找到图像中的目标对象位置。对齐多幅输入图像&#xff0c;使其与参考图像保持一致。在对齐后的图像上进行OCR识别&#xff0c;提取文本和数字信息。以循环…

AIGC实践|AI/AR助力文旅沉浸式互动体验探索

前言&#xff1a; 本篇文章的创作灵感来源于近期热门话题——让文物“动起来”&#xff0c;各大博物馆成为新进潮流打卡地。结合之前创作的AI文旅宣传片良好的流量和反馈&#xff0c;外加最近比较感兴趣的AR互动探索&#xff0c;想尝试看看自己能不能把这些零碎的内容整合起来…

Jenkins 持续集成部署

Jenkins的安装与部署 前言 当我们在实施一个项目时&#xff0c;从新代码中获得反馈的速度越快&#xff0c;问题越早得到解决&#xff0c;获得反馈的一种常见方法是在新代码之后运行测试&#xff0c;但这就导致了当代码正在编译并且正在运行测试时&#xff0c;开发人员无法在测…

王佩丰24节Excel学习笔记——第二十一讲:经典Excel动态图表实现原理

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 使用公式记得要绝对引用&#xff1b;定义好的名称&#xff0c;引用时要使用文件名!定义名&#xff0c;不能写错&#xff0c;否则无结果&#xff1b;利用offset 函数解决数据透视表做好…