几何相关计算

目录

一、判断两个矩形是否相交

二、判断两条线段是否相交

三、判断点是否在多边形内

四、垂足计算

五、贝塞尔曲线

六、判断多边形顺时针还是逆时针

七、判断凹多边形


一、判断两个矩形是否相交

当矩形1的最大值比矩形2的最小值都小,那矩形1和矩形2一定不相交,其他同理。

struct Point {double x;double y;
};
struct Rec {Point min;Point max;
};
bool is_rec_overlap(const Rec& r1, const Rec& r2) {if(r1.max.x < r2.min.x|| r1.max.y < r2.min.y|| r2.max.x < r1.min.x|| r2.max.y < r1.min.y) {return false;} else {return true;}	
}

二、判断两条线段是否相交

排斥实验+跨立实验

#include<iostream>
#include<vector>struct Point {double x;double y;Point(double _x, double _y) : x(_x),y(_y) {}
};struct Edge {Point s;Point e;Edge(const Point& _s, const Point& _e) : s(_s),e(_e) {}
};// 判断点在直线的左右侧:计算叉积(p_e_p_s) × (p-p_s)
// 若返回结果>0,则点p在线段ps_p_e的左侧;
// 若返回结果<0,则点p在线段ps_p_e的右侧;
// 若返回结果=0,则点p与ps、p_e共线;
double is_left(const Point& p, const Point& p_s, const Point& p_e) {return (p_e.x - p_s.x)*(p.y - p_s.y) - (p_e.y - p_s.y)*(p.x - p_s.x);
}bool edges_intersect(const Edge& edge1, const Edge& edge2) {// 排斥实验:最小外包框不想交,edges不可能相交if(std::min(edge1.s.x, edge1.e.x) > std::max(edge2.s.x, edge2.e.x)|| std::min(edge1.s.y, edge1.e.y) > std::max(edge2.s.y, edge2.e.y)|| std::min(edge2.s.x, edge2.e.x) > std::max(edge1.s.x, edge1.e.x)|| std::min(edge2.s.y, edge2.e.y) > std::max(edge1.s.y, edge1.e.y)) {return false;}// 跨立实验:edge1的两个端点在edge2的两侧,且edge2的两个端点在edge1的两侧,则edges相交。if(is_left(edge1.s, edge2.s, edge2.e) * is_left(edge1.e, edge2.s, edge2.e) <= 0&& is_left(edge2.s, edge1.s, edge1.e) * is_left(edge2.e, edge1.s, edge1.e) <= 0) {return true;}return false;
}

参考:https://www.cnblogs.com/TangMoon/p/7611115.html

三、判断点是否在多边形内

简单版

// 判断点在多边形内部还是外部(射线法):
// 从待判断的点出发,向某一方向(这里假设水平向右)发射一条射线;
// 遍历多边形的每一条边,检查射线是否相交
// 统计交点数量,若为偶数,则点在外部,否则,点在内部。
// 这里交点的判断简化为:edge的两个端点y值一个大于pt.y,一个小于pt.y,同时统计pt所在水平直线与edge交点的x值小于pt.x的个数。
bool is_in_polygon(const Point& pt, const std::vector<Point>& polygon) {int count = polygon.size();if(count < 3) {return false;}int intersecting_count = 0;for(int i = 0; i < polygon.size(); i++) {Point edge_s = polygon.at(i);Point edge_e = polygon.at((i+1)%count);if((pt.y <= edge_s.y && pt.y > edge_e.y || pt.y <= edge_e.y && pt.y > edge_s.y)) {// 外层的if保证了edge_e.y != edge_s.ydouble pt_on_edge_x = (pt.y - edge_s.y) * (edge_e.x - edge_s.x) / (edge_e.y - edge_s.y) + edge_s.x;if(pt_on_edge_x < pt.x) {intersecting_count++;}}}return intersecting_count % 2 == 1;
}

参考:https://www.cnblogs.com/tgycoder/p/4901600.html

四、垂足计算

double cal_distance_square(const Point& pt1, const Point& pt2) {return (pt2.x - pt1.x) * (pt2.x - pt1.x) + (pt2.y - pt1.y) * (pt2.y - pt1.y);
}// 计算(p_e-p_s)和(p-p_s)的点积
double dot_product(const Point& p, const Point& p_s, const Point& p_e) {return (p_e.x - p_s.x)*(p.x - p_s.x) + (p_e.y - p_s.y)*(p.y - p_s.y);
}// 判断点pt到edge的投影点project_pt与edge的关系
/*  r = AP dot AB / ||AB||^2r=0 : project_pt = Ar=1 : project_pt = Br<0 : project_pt is on backward extension of ABr>1 : project_pt is on forward extension of AB0<r<1: project_pt is on AB
*/
double relation(const Point& pt, const Edge& edge) {double len_square = cal_distance_square(edge.s, edge.e);// 特殊情况处理if(len_square < EP) {if(cal_distance_square(pt, edge.s) < EP) {return 0;} else {return -1; // 随便给个<0或>1的值}}return dot_product(pt, edge.s, edge.e) / len_square;
}// 计算点pt到线段edge投影点.
// 若投影点在线段上,则project_pt赋值投影点,返回true
// 若投影点不在线段上,则project_pt赋值最近点,返回false。
bool calc_project_pt(const Point& pt, const Edge& edge, Point& project_pt) {double r = relation(pt, edge);if(r < 0) {project_pt = edge.s;return false;} else if (r > 1) {project_pt = edge.e;return false;}project_pt.x = edge.s.x + r * (edge.e.x - edge.s.x);project_pt.y = edge.s.y + r * (edge.e.y - edge.s.y);return true;
}

五、贝塞尔曲线

n阶贝塞尔曲线:B(t)=\sum_{i=0}^{n}\binom{n}{i}P_i(1-t)^{n-i}t^i

n阶贝塞尔曲线递归表达:P_0^n=(1-t)P_0^{n-1}+tP_1^{n-1},t\in [0,1]

二次贝塞尔曲线:B(t)=(1-t)^2P_0+2t(1-t)P_1+t^2P_2,t\in [0,1]

三次贝塞尔曲线:B(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3,t\in [0,1]

\binom{n}{i}表示从n个数中取i个数构成一个组合有多少种取法。

贝塞尔曲线(Bezier Curve)原理、公式推导及matlab代码实现-CSDN博客l

六、判断多边形顺时针还是逆时针

辛普森面积法

// 向量v1与向量v2的叉乘:
// 三维空间中为法向量,该向量垂直于向量v1与v2构成的平面。
// 二维空间中,有公式:v1×v2 = |v1||v2|sin(θ),该角度有正负,是指从v1到v2的角度
double cross_product(const Point& v1, const Point& v2) {return v1.x * v2.y - v1.y * v2.x;
}// 辛普森面积法判断多边形坐标点是顺时针还是逆时针存储
// 面积<0,则为顺时针;面积>0,则为逆时针
bool is_clockwise_polygon(const std::vector<Point>& polygon) {int n = polygon.size();if(polygon.size() < 3) {return false;}double area = 0.0;for(int i = 1; i < n-1; i++) {Point v1 = Point(polygon.at(i).x - polygon.at((i-1+n)%n).x,polygon.at(i).y - polygon.at((i-1+n)%n).y);Point v2 = Point(polygon.at((i+1)%n).x - polygon.at(i).x,polygon.at((i+1)%n).y - polygon.at(i).y);area += cross_product(v1, v2) / 2;std::cout << "i: " << i << ",area: " << area << std::endl;}return area < 0;
}

七、判断凹多边形

(1)角度法:判断每个顶点的角度是否大于180度,若存在这样的顶点,则多边形为凹多边形。

(2)叉乘法:假设多边形形点为逆时针存储,依次判断P_{i-1}P_i,P_iP_{i+1}叉乘结果是否存在负值,若存在则为凹多边形。

// 向量v1与向量v2的叉乘:
// 三维空间中为法向量,该向量垂直于向量v1与v2构成的平面。
// 二维空间中,有公式:v1×v2 = |v1||v2|sin(θ),该角度有正负,是指从v1到v2的角度
double cross_product(const Point& v1, const Point& v2) {return v1.x * v2.y - v1.y * v2.x;
}// 向量法判断多边形凹凸性。
// 以下代码要求:polygon的坐标点须为逆时针存储。
// 若坐标点为顺时针存储,代码中判断条件需要改为:cp>0。
bool is_convex_polygon1(const std::vector<Point>& polygon) {int n = polygon.size();if(polygon.size() < 3) {return false;}for(int i = 0; i < n; i++) {Point v1 = Point(polygon.at(i).x - polygon.at((i-1+n)%n).x,polygon.at(i).y - polygon.at((i-1+n)%n).y);Point v2 = Point(polygon.at((i+1)%n).x - polygon.at(i).x,polygon.at((i+1)%n).y - polygon.at(i).y);double cp = cross_product(v1, v2);std::cout << "i: " << i << ",cp: " << cp << std::endl;if(cp < 0 ) {return false;}}return true;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot开发的AI导航站技术架构剖析 —— 技术如何选型 - 第520篇

历史文章&#xff08;文章累计520&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

鸿蒙模拟器(HarmonyOS Emulator)Beta申请审核流程

文 | Promise Sun 一.背景&#xff1a; 鸿蒙项目开发需要使用模拟器进行开发测试&#xff0c;但目前想在DevEco Studio开发工具中使用模拟器就必须到华为官网进行报名申请&#xff0c;参加“鸿蒙模拟器&#xff08;HarmonyOS Emulator&#xff09;Beta活动申请”。 申请审核通…

Hi3861 OpenHarmony嵌入式应用入门--华为 IoTDA 设备接入

华为云物联网平台&#xff08;IoT 设备接入云服务&#xff09;提供海量设备的接入和管理能力&#xff0c;可以将自己的 IoT 设备 联接到华为云&#xff0c;支撑设备数据采集上云和云端下发命令给设备进行远程控制&#xff0c;配合华为云物联网平台的服 务实现设备与设备之间的控…

微信小程序---npm 支持

一、构建 npm 目前小程序已经支持使用 npm 安装第三方包&#xff0c;但是这些 npm 包在小程序中不能够直接使用&#xff0c;必须得使用小程序开发者工具进行构建后才可以使用。 为什么得使用小程序开发者工具需要构建呢❓ 因为 node_modules 目录下的包&#xff0c;不会参与…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十一)-无人机服务可用性用例需求

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

Study--Oracle-07-ASM自动存储管理(二)

一、ASM安装准备条件 1、ASM支持存储类型 本地祼设备(本地的磁盘和分区) 网络附加存储(NAS) 存储区域网络(SAN) 2、ASM使用本地裸设备,要点: 已经被挂载到操作系统上或者已经做了分区 映射裸设备为文件名 设置正确的权限(针对grid用户和asmadmin组,权限为660) 二、OR…

快速排序及归并排序的实现与排序的稳定性

目录 快速排序 一. 快速排序递归的实现方法 1. 左右指针法 步骤思路 为什么要让end先走&#xff1f; 2. 挖坑法 步骤思路 3. 前后指针法 步骤思路 二. 快速排序的时间和空间复杂度 1. 时间复杂度 2. 空间复杂度 三. 快速排序的优化方法 1. 三数取中优化 2. 小区…

贪心算法(2024/7/16)

1合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;inter…

每日练习,不要放弃

目录 题目1.下面叙述错误的是 ( )2.java如何返回request范围内存在的对象&#xff1f;3.以下代码将打印出4.下列类定义中哪些是合法的抽象类的定义&#xff1f;&#xff08;&#xff09;5.以下代码段执行后的输出结果为6.以下代码运行输出的是总结 题目 选自牛客网 1.下面叙述…

成为git砖家(1): author 和 committer 的区别

大家好&#xff0c;我是白鱼。一直对 git author 和 committer 不太了解&#xff0c; 今天通过 cherry-pick 的例子搞清楚了区别。 原理 例如我克隆了著名开源项目 spdlog 的源码&#xff0c; 根据某个历史 commit A 创建了分支&#xff0c; 然后 cherry-pick 了这个 commit …

DPU:值不值得托付下一代存储加速架构?

一、为什么需要DPU&#xff1f; 在信息爆炸的时代&#xff0c;数据处理单元&#xff08;DPU&#xff09;作为新兴的数据中心基础设施核心&#xff0c;正逐步崭露头角&#xff0c;成为提升数据处理效率、优化成本结构的关键角色。 传统的数据中心架构主要以CPU为中心&#xff…

【C#】已知有三个坐标点:P0、P1、P2,当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行且长度一致,该如何计算P3、P4?

问题描述 已知有三个坐标点&#xff1a;P0、P1、P2&#xff0c;当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行且长度一致&#xff0c;该如何计算P3、P4&#xff1f; 解决办法 思路一&#xff1a;斜率及点斜式方程 # 示例坐标 x0, y0 1, 1 # P0坐标 x1, y1 4, 4 # …

pytorch中一些最基本函数和类

1.Tensor操作 Tensor是PyTorch中最基本的数据结构&#xff0c;类似于NumPy的数组&#xff0c;但可以在GPU上运行加速计算。 示例&#xff1a;创建和操作Tensor import torch# 创建一个零填充的Tensor x torch.zeros(3, 3) print(x)# 加法操作 y torch.ones(3, 3) z x y pr…

SEO:6个避免被搜索引擎惩罚的策略-华媒舍

在当今数字时代&#xff0c;搜索引擎成为了绝大多数人获取信息和产品的首选工具。为了在搜索结果中获得良好的排名&#xff0c;许多网站采用了各种优化策略。有些策略可能会适得其反&#xff0c;引发搜索引擎的惩罚。以下是彭博社发稿推广的6个避免被搜索引擎惩罚的策略。 1. 内…

链接追踪系列-07.logstash安装json_lines插件

进入docker中的logstash 容器内&#xff1a; jelexbogon ~ % docker exec -it 7ee8960c99a31e607f346b2802419b8b819cc860863bc283cb7483bc03ba1420 /bin/sh $ pwd /usr/share/logstash $ ls bin CONTRIBUTORS Gemfile jdk logstash-core modules tools x-pack …

本地部署 EVE: Unveiling Encoder-Free Vision-Language Models

本地部署 EVE: Unveiling Encoder-Free Vision-Language Models 0. 引言1. 快速开始2. 运行 Demo 0. 引言 EVE (Encoder-free Vision-language model) 是一种创新的多模态 AI 模型&#xff0c;主要特点是去除了传统视觉语言模型中的视觉编码器。 核心创新 架构创新&#xff…

【python虚拟环境管理】【mac m3】 使用pipx安装poetry

文章目录 一. 安装 pipx二. 安装Poetry1. 安装2. advanced 操作 官网文档&#xff1a;https://python-poetry.org/docs/ pipx介绍文档&#xff1a;https://blog.51cto.com/u_15064632/2570626 一. 安装 pipx pipx 用于全局安装 Python 命令行应用程序&#xff0c;同时在虚拟环…

[ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)

2024年虚拟现实、图像和信号处理国际学术会议&#xff08;VRISP 2024&#xff09;将于2024年8月2-4日在中国厦门召开。 VRISP 2024将围绕“虚拟现实、图像和信号处理”的最新研究领域&#xff0c;为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供…

二次开发源码 借贷系统uniapp/借贷认证系统/小额信贷系统/工薪贷APP/资金贷系统h5

前端&#xff1a;UNIAPP 后端&#xff1a;ThinkPHP 数据库&#xff1a; Mysql 前端使用的uniapp 可以打包APP H5 小程序 系统提供了完善的网络借贷体系&#xff0c;为金融中介平台提供从获客到贷后管理全流程服务&#xff0c;解决了借贷手续繁琐、流程缓慢等问题 此源码为运营…

解决一下git clone失败的问题

1&#xff09;.不开梯子&#xff0c;我们用https克隆 git clone https://github.com 报错&#xff1a; Failed to connect to github.com port 443 after 2091 ms: Couldnt connect to server 解决办法&#xff1a; 开梯子&#xff0c;然后# 注意修改成自己的IP和端口号 gi…