python如何判断点是否在旋转矩形内部矢量

1. 简介

在计算机图形学和计算几何中,经常会遇到判断一个点是否在一个旋转矩形内部的问题。本项目方案旨在使用Python提供一种高效准确的算法来解决这个问题。

2. 算法原理

方法一:

为了判断一个点是否在一个旋转矩形内部,我们可以将问题转化为判断点是否在一个未旋转的矩形内部。首先,我们需要了解旋转矩形的属性和特点:

  • 旋转矩形的中心点坐标(xc, yc)
  • 旋转矩形的宽度w和高度h
  • 旋转矩形的旋转角度θ

接下来,我们需要将旋转矩形坐标系转换为以矩形中心为原点的笛卡尔坐标系。将点的坐标(x, y)也进行坐标系转换,得到相对于中心点的坐标(x’, y’):

xc, yc = center_x, center_y  # 旋转矩形中心坐标
x, y = point_x, point_y  # 待判断点坐标# 将点坐标转换为相对于中心点的坐标
x_prime = x - xc
y_prime = y - yc

接下来,我们需要进行旋转矩形的逆旋转操作,将旋转矩形恢复为未旋转的矩形,即将旋转角度θ变为0。这个操作可以通过坐标系变换实现,具体变换矩阵如下:

cosθ  -sinθ
sinθ  cosθ

旋转矩形的4个顶点在逆旋转之后会变成未旋转矩形的4个顶点。我们可以根据矩形的宽度和高度计算出这4个顶点的坐标,然后将这4个顶点的坐标表示为向量的形式。

import math# 计算旋转矩形的顶点坐标
w, h = width, height  # 旋转矩形的宽度和高度
theta = rotation_angle  # 旋转角度cos_theta = math.cos(theta)
sin_theta = math.sin(theta)# 计算旋转矩形的顶点坐标
v1 = [-w/2, -h/2]
v2 = [w/2, -h/2]
v3 = [w/2, h/2]
v4 = [-w/2, h/2]# 逆旋转操作,恢复未旋转的矩形
def inverse_rotation(v):x = v[0] * cos_theta - v[1] * sin_thetay = v[0] * sin_theta + v[1] * cos_thetareturn [x, y]v1 = inverse_rotation(v1)
v2 = inverse_rotation(v2)
v3 = inverse_rotation(v3)
v4 = inverse_rotation(v4)

完整代码

import mathdef inverse_rotation(v, cos_theta, sin_theta):x = v[0]*cos_theta - v[1]*sin_thetay = v[0]*sin_theta + v[1]*cos_thetareturn x, yif __name__ == "__main__":center_x, center_y, w, h, theta = 10, 15, 20, 10, math.pi/4x, y = 15, 15xc, yc = center_x, center_yx_prime = x - xcy_prime = y - ycv1 = [-w/2, h/2]v2 = [w/2, -h/2]cos_theta = math.cos(theta)sin_theta = math.sin(theta)v1 = inverse_rotation(v1, cos_theta, sin_theta)v2 = inverse_rotation(v2, cos_theta, sin_theta)if v1[0] < x_prime < v2[0] and v1[1] < y_prime < v2[1]:print("point yes!!!")else:print("point no!!!")

方法二

找到旋转矩形的四个顶点: 通过已知的矩形中心点、宽度、高度和旋转角度,可以计算出旋转矩形的四个顶点的坐标。

使用射线法进行判断: 从待判断的点出发,向任意方向发射一条射线,计算这条射线与旋转矩形的边的交点数。如果交点数为奇数,则点在矩形内;如果交点数为偶数,则点在矩形外。

具体步骤如下:

  • 首先,计算矩形的四个顶点的坐标。
  • 然后,对于每条边,检查射线是否与其相交。
  • 如果与某条边相交,且交点在射线上方(或下方),则计数加一。
    最后,判断交点数的奇偶性,确定点是否在矩形内。
import mathdef point_inside_rotated_rectangle(point, rectangle_center, width, height, rotation_angle):# 计算矩形的四个顶点坐标angle_rad = math.radians(rotation_angle)dx = width / 2dy = height / 2cos_theta = math.cos(angle_rad)sin_theta = math.sin(angle_rad)vertices = [(rectangle_center[0] + dx * cos_theta - dy * sin_theta, rectangle_center[1] + dx * sin_theta + dy * cos_theta),(rectangle_center[0] - dx * cos_theta - dy * sin_theta, rectangle_center[1] + dx * sin_theta - dy * cos_theta),(rectangle_center[0] - dx * cos_theta + dy * sin_theta, rectangle_center[1] - dx * sin_theta - dy * cos_theta),(rectangle_center[0] + dx * cos_theta + dy * sin_theta, rectangle_center[1] - dx * sin_theta + dy * cos_theta)]# 使用射线法判断点是否在矩形内intersections = 0for i in range(4):x1, y1 = vertices[i]x2, y2 = vertices[(i + 1) % 4]# 判断射线是否与边相交if (point[1] > min(y1, y2)) and (point[1] <= max(y1, y2)) and (point[0] <= max(x1, x2)):x_intersect = (point[1] - y1) * (x2 - x1) / (y2 - y1) + x1if x_intersect > point[0]:intersections += 1# 如果交点数为奇数,则点在矩形内return intersections % 2 == 1# 示例
point = (1, 1)  # 待判断的点坐标
rectangle_center = (0, 0)  # 矩形中心点坐标
width = 4  # 矩形宽度
height = 2  # 矩形高度
rotation_angle = 45  # 旋转角度# 判断点是否在旋转矩形内
result = point_inside_rotated_rectangle(point, rectangle_center, width, height, rotation_angle)
print(f"Point {point} is inside the rotated rectangle: {result}")

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

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

相关文章

最坏情况为线性时间的第k大元素

在统计和数据分析中&#xff0c;我们经常会遇到求最大值、最小值、中位数、四分位数、Top K等类似需求&#xff0c;其实它们都属于顺序统计量&#xff0c;本文将对顺序统计量的定义和求解算法进行介绍&#xff0c;重点介绍如何在最差时间复杂度也是线性的情况下求解第k大元素。…

在Debian 12系统上安装Docker

Docker 在 Debian 12 上的安装 安装验证测试更多信息引言 在现代的开发环境中,容器技术发挥着至关重要的作用。Docker 提供了快速、可靠和易于使用的容器化解决方案,使开发人员和 DevOps 专业人士能够以轻松的方式将应用程序从一个环境部署到另一个环境。 Docker 的安装过程在…

实用运维工具(转载)

1、查看进程占用带宽情况-Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽。 下载&#xff1a;http://sourceforge.net/projects/nethogs/files/nethogs/0.8/nethogs-0.8.0.tar.gz/download [rootlocalhost ~]#yum -y install libpcap-deve…

C语言—每日选择题—Day68

第一题 1、运行以下C语言代码&#xff0c;输出的结果是&#xff08;&#xff09; #include <stdio.h> int main() {char *str[3] {"stra", "strb", "strc"};char *p str[0];int i 0;while(i < 3){printf("%s ",p);i;} retur…

在win10上虚拟一个LoongOS系统(类似虚拟机)作为开发环境

文章目录 1.安装1.1.下载这三个东西1.2.安装好qemu。1.3.创建一个启动脚本startup_mate.bat&#xff0c;然后把三部分东西放到一起1.4.然后双击startup.bat就可以启动了。 2.文件的传输2.1.使能虚拟机系统的ssh2.2.连接ssh 3.Qt相关安装Qt安装opencv 1.安装 注意&#xff0c;一…

ClickHouse--17--argMin() 和argMax()函数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 argMin() 和argMax()函数业务场景使用案例1.准备表和数据&#xff1a;业务场景一&#xff1a;查看salary 最高和最小的user业务场景二&#xff1a;根据更新时间获取…

再也不怕面试官问 OOM了,一次生产环境 Metaspace OOM 排查流程实操!

问题背景 小奎公司的运维同时今天反映核心业务一个服务目前 CPU 的使用率、堆内存、非堆内存的使用率有点高。刚反映没有过多久该服务就直接 OOM 了&#xff0c;以下是生产监控平台监控信息。 CPU 使用率监控 堆内存和非堆内存使用率 OOM 产生的日志报错信息 问题分析 根…

Go第三方框架--ants协程池框架

1. 背景介绍 1.1 goroutine ants是站在巨人的肩膀上开发出来的&#xff0c;这个巨人是goroutine&#xff0c;这是连小学生都知道的事儿&#xff0c;那么为什么不继续使用goroutine(以下简称go协程)呢。这是个思考题&#xff0c;希望讲完本文大家可以有个答案。 go协程只涉及用…

【STL】队列(queue)

队列 queue没有迭代器 Queue所有元素的进出都必须符合”先进先出”的条件&#xff0c;只有queue的顶端元素&#xff0c;才有机会被外界取用。Queue不提供遍历功能&#xff0c;也不提供迭代器。 头文件&#xff1a; #include <queue>queue<T> queT;//queue采用模…

Docker部署minio集群

1.基本定义 由于是非常轻量级的软件&#xff0c;所以架构上也没有这么复杂&#xff0c;他使用操作系统的文件系统作为存储介质&#xff0c;我们在向任意节点写数据的时候&#xff0c;minio会自动同步数据到另外的节点&#xff0c;而机制叫做erasure code&#xff08;纠删码&am…

Java基础知识总结(48)

&#xff08;1&#xff09;super关键字 1. super代表父类对象 2. 在构造器中访问父类的构造器&#xff08;创建子类对象时会先创建父类对象&#xff09; 3. super访问父类的实例变量 4. 访问父类的实例方法 如&#xff1a;/*** 父类* author Ray**/public class Animal {String…

linux内核驱动-在内核代码里添加设备结点

linux中&#xff0c;一切皆文件 我们在用户层用一些系统函数&#xff08;如&#xff1a;fopen等等&#xff09;时&#xff0c;会进入内核&#xff0c;内核会在字符注册了的设备号链表中查找。如果找到就运行我们写的设备文件的&#xff08;驱动&#xff09;函数 我们在前面已经…

【滑动窗口】无重复字符的最长字串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串的长度 示例 1: 输入: s "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 示例 2: 输入: s "bbbbb"输出: 1解释: 因为无重复字…

day54 买卖股票的最佳时机含冷冻期 买卖股票的最佳时机含手续费

题目1&#xff1a;309 买卖股票的最佳时机含冷冻期 题目链接&#xff1a;309 买卖股票的最佳时机含冷冻期 题意 整数数组prices中prices[i]表示第i天的股票价格&#xff0c;可以进行多次交易&#xff0c;但是在卖出股票后&#xff0c;无法在第二天买入股票&#xff08;冷冻期…

设计模式(017)行为型之责任链模式

责任链模式&#xff0c;它允许你将请求沿着处理者链传递&#xff0c;直到有一个处理者能够处理该请求为止。在责任链模式中&#xff0c;有三个核心角色&#xff1a;请求者&#xff08;Client&#xff09;、处理者&#xff08;Handler&#xff09;、以及具体处理者&#xff08;C…

RuoYi-Vue若依框架-vue前端给对象添加字段

处理两个字段的时候有需求都要显示在下拉框的同一行&#xff0c;这里有两种解决方案&#xff0c;一是后端在实体类添加一个对象&#xff0c;加注解数据库忽略处理&#xff0c;在接口处拼接并传给前端&#xff0c;二是在前端获取的数据数组内为每个对象都添加一个字段&#xff0…

cannal的使用

搭建MySQL 安装canal 1.新建文件夹logs, 新建文件canal.properties instance.properties docker.compose.yml instance.properties ################################################# ## mysql serverId , v1.0.26 will autoGen # canal.instance.mysql.slaveId0# enable g…

06 Php学习:字符串

PHP 中的字符串变量 在 PHP 中&#xff0c;字符串是一种常见的数据类型&#xff0c;用于存储文本数据。字符串变量可以包含字母、数字、符号等字符&#xff0c;并且可以进行各种操作和处理。以下是关于 PHP 中字符串变量的一些重要信息&#xff1a; 定义字符串变量&#xff1…

【SpringBoot3】Bean管理

1.Bean扫描 1.1传统Spring 标签&#xff1a;<context:component-scan base-package"com. example "/>注解&#xff1a;ComponentScan(basePackages "com.example") 1.2SpringBoot SpringBoot默认扫描启动类所在的包及其子包 2.Bean注册 如果要注…

Linux从入门到精通 --- 1.初始Linux

文章目录 第一章&#xff1a;1.1 Linux的诞生1.2 Linux系统内核1.3 Linux系统发行版 第一章&#xff1a; 1.1 Linux的诞生 1991年由林纳斯 托瓦兹创立并发展至今称为服务器操作系统领域的核心系统。 1.2 Linux系统内核 Linux内核提供了系统的主要功能&#xff0c;甚至是开源…