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

news2025/1/2 22:07:43

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 = 0
    planeParams << 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->P6
    Eigen::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.coloradmin.cn/o/2268016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单片机与MQTT协议

MQTT 协议简述 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布 / 订阅&#xff08;publish/subscribe&#xff09;模式的 “轻量级” 通讯协议&#xff0c;该协议构建于 TCP/IP 协议上&#xf…

Debian-linux运维-docker安装和配置

腾讯云搭建docker官方文档&#xff1a;https://cloud.tencent.com/document/product/213/46000 阿里云安装Docker官方文档&#xff1a;https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance 天翼云常见docker源配置指导&#xff1a;htt…

使用Docker-compose部署SpringCloud项目

docker编写dockfile遇到的问题&#xff1a; 需要在docker-compose.yml文件下执行命令 docker-compose.yml文件格式的问题 1和2处空2格&#xff0c;3处空1格&#xff0c;4为本地配置文件目录&#xff0c;5为docker容器的目录&#xff0c;version为自己安装的docker-compose版本 …

KG4Diagnosis 分层多代理的医疗诊断框架,结合大模型与知识图谱构建,覆盖362种常见疾病

KG4Diagnosis 分层多代理的医疗诊断框架&#xff0c;结合大模型与知识图谱构建&#xff0c;覆盖362种常见疾病 论文大纲理解1. 提出背景是什么&#xff1f;2. 概念的性质是什么&#xff1f;是什么导致这个性质&#xff1f;3. 请举一个正例、一个反例&#xff0c;对比4. 请使用类…

【LLM综述】29种大模型Prompt Engineering技术

note 从零样本&#xff08;Zero-shot&#xff09;提示到最新进展的各种提示技术&#xff0c;包括推理和逻辑链&#xff08;Chain-of-Thought, CoT&#xff09;提示、自动链式思考&#xff08;Auto-CoT&#xff09;提示、自我一致性&#xff08;Self-Consistency&#xff09;提…

【黑马头条训练营】day02-黑马头条-App端文章展示

目录 描述app端首页从请求到数据显示的全部流程 描述文章微服务的组成及首页展示业务与实现 自己编写文章微服务关键逻辑 描述app端首页从请求到数据显示的全部流程 浏览器请求我们的app端 会通过nginx请求到我们app前端 app端输入手机号和密码 点击登录 请求 会到我们的…

DBeaver 咋手动配置sqlite 驱动

目录 1 问题2 下载 1 问题 离线安装了DBeaver 数据库软件&#xff0c;现在需要使用这个数据库打开sqlite 数据库&#xff0c;但是提示没有 驱动&#xff0c;那么我们就需要手动下载驱动&#xff0c;在这个软件里面导入 2 下载 https://repo1.maven.org/maven2/org/xerial/sql…

Linux 的历史与发展:从诞生到未来

Linux 的历史与发展&#xff1a;从诞生到未来 1. 起源之前&#xff1a;操作系统的历史背景 在 Linux 问世之前&#xff0c;操作系统的发展经历了多个重要阶段&#xff0c;这些阶段为 Linux 的诞生奠定了基础&#xff1a; 1940-1950 年代&#xff1a;计算机初期 早期计算机如 [[…

八爪鱼easyspider:

参考我的上一篇博客&#xff1a; scraper插件与软件&#xff0c; 主八爪鱼&#xff0c;easyspider 1&#xff0c;八爪鱼&#xff1a; 同时注意数据横向还是纵向&#xff0c;但是不好操作 二&#xff0c;easyspider&#xff1a; 其中1/2是不需要用户登入的&#xff0c;第3个…

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 …

llamafactory报错:双卡4090GPU,训练qwen2.5:7B、14B时报错GPU显存不足(out of memory),轻松搞定~~~

实际问题场景&#xff1a; 使用llamafactory进行微调qwen2.5 7B和14B的大模型时&#xff0c;会出现out of memory的报错。尝试使用降低batch_size&#xff08;原本是2&#xff0c;现在降到1&#xff09;的方式&#xff0c;可以让qwen2.5:7B跑起来&#xff0c;但时不时会不稳定…

七牛云—对象云存储Kodo(详解,文件上传和下载)

文章目录 七牛—对象云存储Kodo1.1 介绍1.2 使用注册账号创建bucket空间查询accessKey/secretKey查看官网SDK1.3 SpringBoot中使用七牛云上传引入依赖(在官方SDK文档中有)引入工具类servie层controller层postman测试下载引入工具类域名查询controller层七牛—对象云存储Kodo 1…

概率统计与随机过程--作业8

推导题 试给出图1中所有关于Z{e}与变量a条件独立的变量。 编程题 有一个美国医生使用Bayes网络诊断胸部疾病&#xff0c;其掌握的数据信息如图2所示&#xff0c;其中包括&#xff1a; 有50%的病人吸烟&#xff08;smoking&#xff09;&#xff0c;1%患有肺结核(Tuberculosis…

Java设计模式 —— 【结构型模式】享元模式(Flyweight Pattern) 详解

文章目录 概述结构案例实现优缺点及使用场景 概述 享元模式也叫蝇量模式&#xff1a;运用共享技术有效地支持大量细粒度的对象&#xff1b; 常用于系统底层开发&#xff0c;解决系统的性能问题。像数据库连接池&#xff0c;里面都是创建好的连接对象&#xff0c;在这些连接对象…

Linux实验报告7-文件管理

目录 一&#xff1a;实验目的 二&#xff1a;实验内容 (1)查看/etc/inittab文件的权限属性&#xff0c;并指出该文件的所有者以及文件所属组群。 (2)新建文件test&#xff0c;设置文件权限为r--r-----。 (3)新建文件test2&#xff0c;设系统中有用户study和用户组studygr…

机器学习DAY7: 特征工程和特征选择(数据预处理)(完)

本文通过特征提取、特征转换、特征选择三个过程介绍数据预处理方法&#xff0c;特征提取将原始数据转换为适合建模的特征&#xff0c;特征转换将数据进行变换以提高算法的准确性&#xff0c;特征选择用来删除无用的特征。 知识点 特征提取特征转换特征选择 本次实验的一些示…

AE Dressler CESAR 1312 Generator Model User Manual

AE Dressler CESAR 1312 Generator Model User Manual

科大讯飞超拟人合成python

1、进入自己的项目 复制APPID、APISecret、APIKey 2、添加好听发音人 复制参数 3、需要替换代码部分&#xff1a; 换自己喜欢的发声人的参数 4、完整代码&#xff1a; import _thread as thread import base64 import datetime import hashlib import hmac import json fro…

关于缓冲文件系统和文件控制块的介绍

缓冲文件系统 缓冲文件系统的定义与原理 应用程序是如何进行文件数据的访问的呢&#xff1f;由于系统对磁盘文件数据的存取速度与内存数据存取的速度不同&#xff0c;而且文件数据量较大&#xff0c;数据从磁盘读到内存或从内存写到磁盘不可能瞬间完成&#xff0c;所以为了提高…

Llama系列关键知识总结

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构&#xff1a;Llama2分组查询注意力 (GQA) Llama3关键信息 引用&#xff1a; Ll…