python之二维几何学习笔记

一、概要

资料来源《机械工程师Python编程:入门、实战与进阶》安琪儿·索拉·奥尔巴塞塔 2024年6月

  • 点和向量:向量的缩放、范数、点乘、叉乘、旋转、平行、垂直、夹角
  • 直线和线段:线段中点、离线段最近的点、线段的交点、直线交点、线段的垂直平分线
  • 多边形:一般多边形、圆、矩形
  • 仿射变换

书中强调了单元测试的重要性。

二、点和向量

数字比较

# geom2d/nums.pyimport mathdef are_close_enough(a,b,tolerance=1e-10):return math.fabs(a-b)<tolerancedef is_close_to_zero(a,tolerance=1e-10):return are_close_enough(a,0.0,tolerance)def is_close_to_one(a,tolerance=1e-10):return are_close_enough(a,1.0,tolerance)

# geom2d/point.pyimport mathfrom geom2d import nums
from geom2d.vector import Vectorclass Point:def __init__(self, x, y):self.x = xself.y = y# 计算两点间的距离def distance_to(self, other):delta_x = other.x - self.xdelta_y = other.y - self.yreturn math.sqrt(delta_x ** 2 + delta_y ** 2)# 对点进行加操作def __add__(self, other):return Point(self.x + other.x,self.y + other.y)# 对点进行减操作def __sub__(self, other):return Vector(self.x - other.x,self.y - other.y)# 用向量移动点def displaced(self, vector: Vector, times=1):scaled_vec = vector.scaled_by(times)return Point(self.x + scaled_vec.u,self.y + scaled_vec.v)# 比较点是否相等def __eq__(self, other):if self is other:return Trueif not isinstance(other, Point):return Falsereturn nums.are_close_enough(self.x, other.x) and \nums.are_close_enough(self.y, other.y)def __str__(self):return f'({self.x},{self.y})'

向量

# geom2d/vector.pyimport mathfrom geom2d import numsclass Vector:def __init__(self, u, v):self.u = uself.v = v# 向量的加法def __add__(self, other):return Vector(self.u+other.u,self.v+other.v)# 向量的减法def __sub__(self, other):return Vector(self.u-other.u,self.v-other.v)# 向量的缩放def scaled_by(self,factor):return Vector(factor*self.u,factor*self.v)# 计算向量的范数@propertydef norm(self):return math.sqrt(self.u**2+self.v**2)# 验证向量是否为单位向量@propertydef is_normal(self):return nums.is_close_to_one(self.norm)# 计算单位长度的向量def normalized(self):return self.scaled_by(1.0/self.norm)# 计算指定长度的向量def with_length(self,length):return self.normalized().scaled_by(length)# 向量的投影def projection_over(self,direction):return self.dot(direction.normalized())# 向量点乘def dot(self,other):return (self.u*other.u)+(self.v*other.v)# 向量叉乘def cross(self,other):return (self.u*other.v)-(self.v*other.u)# 检验两向量是否平行,即叉乘是否为0def is_parallel_to(self,other):return nums.is_close_to_zero(self.cross(other))# 检验两向量是否垂直,即点乘是否为0def is_perpendicular_to(self,other):return nums.is_close_to_zero(self.dot(other))# 向量的夹角(角度值)def angle_value_to(self,other):dot_product=self.dot(other)  # 计算点乘值norm_product=self.norm*other.norm # 范数的乘积return math.acos(dot_product/norm_product) # (点乘值/范数乘积)取反余弦,即角度值# 向量的夹角(带叉乘符号的角度值)def angle_to(self,other):value=self.angle_value_to(other)cross_product=self.cross(other)return math.copysign(value,cross_product) #math.copysign(x, y)函数返回x的大小和y的符号# 向量的旋转,旋转一定角度def rotated_radians(self,radians):cos=math.cos(radians)sin=math.sin(radians)return Vector(self.u*cos-self.v*sin,self.u*sin+self.v*cos)# 垂直向量,旋转90度def perpendicular(self):return Vector(-self.v,self.u)# 相反向量,旋转180度def opposite(self):return Vector(-self.u,-self.v)# 向量的正旋和余弦@propertydef sine(self):return self.v/self.norm@propertydef cosine(self):return self.u/self.norm# 比较向量是否相等def __eq__(self, other):# 检查是否在比较相同的实例if self is other:return True# other不是Vector类的实例if not isinstance(other,Vector):return Falsereturn nums.are_close_enough(self.u,other.u) and \nums.are_close_enough(self.v,other.v)def __str__(self):return f'({self.u},{self.v}) with norm {self.norm}'
#geom2d/vectors.py
# 向量工厂from geom2d.point import Point
from geom2d.vector import Vector# 创建一个从点p到点q的向量
def make_vector_between(p:Point,q:Point):return q-p# 创建单位方向向量
def make_versor(u:float,v:float):return Vector(u,v).normalized()# 在两点之间创建一个单位方向向量
def make_versor_between(p:Point,q:Point):return make_vector_between(p,q).normalized()

向量范数

向量的范数(norm)是指它的长度。单位范数的长度为一个单位。拥有单位范数的向量在确认向量方向时非常有用,因此,我们经常会想知道一个向量的范数是否为单位范数(它是否是单位向量)​。我们也经常需要归一化(normalize)一个向量:方向不变,长度变为1。

向量点乘

点乘(dot product)会得到一个标量,它可以反映两个向量方向的差异

图上有一个参考向量\vec{v}和另外三个向量:\vec{a}\vec{b}\vec{c}。一条垂直于\vec{v}的直线将空间分成两个半平面。向量\vec{b}在直线上,因此\vec{v}\vec{b}的夹角θ等于90°。而cos(90°)=0,因此\vec{v}\cdot\vec{b}=0。垂直向量的点乘为零。向量\vec{a}所在的半平面和\vec{v}相同,因此,\vec{v}\cdot\vec{a}> 0。最后,\vec{c}在与\vec{v}相对的半平面上,因此,\vec{v}\cdot\vec{c}< 0

向量叉乘

向量叉乘(cross product)会得到一个垂直于这两个向量所在平面的新向量。向量的顺序很重要,它决定了结果向量的方向。可以使用右手法则得到叉乘的方向。

叉乘不满足交换律:\vec{u}\times \vec{v}= - \vec{v}\times \vec{u}

二维向量叉乘的一个重要应用是确定角度的旋转方向\vec{u}\times \vec{v}> 0,因为从\vec{u}\vec{v}的角度为正(逆时针)​。相反,从\vec{v}\vec{u}的角度为负,因此叉乘\vec{v}\times \vec{u}< 0。最后,平行向量的叉乘为0,这很显然,因为sin 0=0。

向量旋转

cos(π/2)=0, sin(π/2)=1,cos(π)=-1, sin(π)=0

向量的正弦和余弦

三、直线和线段 

线段

# geom2d/segment.pyfrom geom2d.point import Point
from geom2d.vectors import make_vector_between,make_versor_between
from geom2d import tparamclass Segment:def __init__(self,start:Point,end:Point):self.start=startself.end=end# 线段的方向向量@propertydef direction_vector(self):return make_vector_between(self.start,self.end)# 线段的单位方向向量@propertydef direction_versor(self):return make_versor_between(self.start,self.end)# 垂直于线段方向的向量,法向量# 调用self的direction_versor来得到线段的方向向量,同时也是Vector类的实例# 调用perpendicular方法,返回垂直于线段方向的向量def normal_versor(self):return self.direction_versor.perpendicular()# 线段的长度@propertydef length(self):return self.start.distance_to(self.end)# 使用参数t获取线段上的任意一点def point_at(self,t:float):tparam.ensure_valid(t)  # 验证t值return self.start.displaced(self.direction_vector,t)# 线段的中点@propertydef middle(self):return self.point_at(tparam.MIDDLE)# 线段上的最近点# 计算从线段的端点S到外部点P的向量v# 计算在线段方向上投影的单位向量d# 将投影的长度设为vsdef closest_point_to(self,p:Point):v=make_vector_between(self.start,p)d=self.direction_versorvs=v.projection_over(d)if vs<0:return self.startif vs>self.length:return self.endreturn self.start.displaced(d,vs)

线段的方向向量

方向(direction)是线段的一个重要性质,定义为从起点S到终点E的向量。用\vec{d}来表示该向量。

方向向量(direction vector)是一个与线段平行且长度相同的向量,其方向是从起点到终点。

单位方向(direction versor)是方向向量的归一化版本,即与方向向量的方向相同,但长度为一个单位。

垂直于线段的方向也同样重要。将单位方向向量\hat{d}旋转方向π/4 rad(90°),就可以得到线段的单位法向量(normalversor)。

线段上最接近外部点的点

如果外部点没有与线段对齐,穿过该点且垂直于线段的直线不与线段相交,那么最近的点必然是两个端点S或E中的一个。

如果该点与该段对齐,则垂直线与线段的交点就是最近的点。

如图:点S≡A'是离A最近的点,点E≡B'是最接近B的点,C'是最接近C的点。

线段的交点

四、多边形

一般多边形——用它们的顶点来定义;

圆是平面内与指定点(圆心)的距离(半径)相同的所有点的集合。因此,圆由圆心C的位置和半径R的值定义

矩形——由原点、宽度和高度定义

多边形中一个重要性质是质心(centroid),即所有顶点坐标的算术平均值。

五、仿射变换

仿射变换:它使我们能够通过缩放、旋转、平移和剪切来改变几何形状。

六、单元测试

断言方法

断言方法描述
assertAlmostEqual定义在我们引用的类unittest.TestCase中,用指定的公差来检查浮点数是否相等,公差用小数点后的位数表示,默认是7。请记住,在比较浮点数时,必须有公差,或者像上述例子,给定小数点后的位数
assertEqual使用==操作符来比较这两个参数
assertTrue检验给定表达式的计算结果是否为True
assertFalse检验给定表达式的计算结果是否为False
assertRaises向其传入三个参数。首先是预期要触发的异常(TParamError)。其次,传入了期望触发异常的方法。最后,传入需要传递给前面的方法(在本例中为point_at)的实参。
assertIsNone检查传入的值是否是None(无)​

单元测试的三个规则

1、失败原因须唯一

单元测试应该有且仅有一个失败的原因。如果测试失败只有一个原因,那么很容易找到代码中的错误。如果一个测试失败可能有五个不同的原因。当测试失败时,你会发现自己花费太多时间去阅读错误消息和调试代码。

2、受控环境

测试的输入和输出应该是已知的。发生在测试中的一切都应该是确定的(deterministic),也就是说,不应该出现随机性或依赖任何你无法控制的东西:日期或时间、操作系统、未在测试中设置的机器环境变量,等等。

3、测试独立性

测试不应依赖于其他测试。每个测试都应该独立运行,绝不能依赖于其他测试所设置的运行测试的环境。这至少有三个原因。首先,你需要独立地运行或调试测试。其次,许多测试框架并不能保证测试的执行顺序。最后,不依赖于其他测试的测试要易读得多。

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

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

相关文章

AI编程工具使用技巧——通义灵码

活动介绍通义灵码1. 理解通义灵码的基本概念示例代码生成 2. 使用明确的描述示例代码生成 3. 巧妙使用注释示例代码生成 4. 注意迭代与反馈原始代码反馈后生成优化代码 5. 结合生成的代码进行调试示例测试代码 其他功能定期优化生成的代码合作与分享结合其他工具 总结 活动介绍…

国产编辑器EverEdit - 复制为RTF

1 复制为RTF 1.1 应用背景 在写产品手册或者其他文档时&#xff0c;可能会用到要将产品代码以样例的形式放到文档中&#xff0c;一般的文本编辑器拷贝粘贴到Word中也就是普通文本&#xff0c;没有语法着色&#xff0c;这样感观上不是太好&#xff0c;为了让读者的感观更好一点…

Python毕业设计选题:基于python的酒店推荐系统_django+hadoop

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 酒店客房管理 客房类型管理 客房预定管理 用户…

YoloV10改进策略:Neck层改进|EFC,北理提出的适用小目标的特征融合模块|即插即用

论文信息 论文题目:A Lightweight Fusion Strategy With Enhanced Interlayer Feature Correlation for Small Object Detection 论文链接:https://ieeexplore.ieee.org/abstract/document/10671587 官方github:https://github.com/nuliweixiao/EFC 研究贡献 为了解决上…

Re78 读论文:GPT-4 Technical Report

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;GPT-4 Technical Report 官方博客&#xff1a;GPT-4 | OpenAI appendix懒得看了。 文章目录 1. 模型训练过程心得2. scaling law3. 实验结果减少风险 1. 模型训练过程心得 模型结构还…

Linux中安装mysql8,很详细

一、查看系统glibc版本号&#xff0c;下载对应版本的MySQL 1、查看glibc版本号办法 方法一&#xff1a;使用ldd命令 在终端中输入ldd --version命令&#xff0c;然后按下回车键。这个命令会显示系统中安装的glibc版本号。例如&#xff0c;如果输出信息是ldd (GNU libc) 2.31&a…

springboot如何解析 Map 的泛型信息来确定要注入哪些 Bean?

我在学习策略模式的时候, 发现当SpringBoot注入一个Map的时候 &#xff0c;value泛型为T&#xff0c;则注入后Spring会将实例化后的bean放入value &#xff0c;key则为注入后bean的名字 Springboot如何解析Map中的Value Spring 通过解析 Map 的泛型信息来确定要注入哪些 Bean…

【NextJS】PostgreSQL 遇上 Prisma ORM

NextJS 数据库 之 遇上Prisma ORM 前言一、环境要求二、概念介绍1、Prisma Schema Language&#xff08;PSL&#xff09; 结构描述语言1.1 概念1.2 组成1.2.1 Data Source 数据源1.2.2 Generators 生成器1.2.3 Data Model Definition 数据模型定义字段(数据)类型和约束关系&…

一些常见的Java面试题及其答案

Java基础 1. Java中的基本数据类型有哪些&#xff1f; 答案&#xff1a;Java中的基本数据类型包括整数类型&#xff08;byte、short、int、long&#xff09;、浮点类型&#xff08;float、double&#xff09;、字符类型&#xff08;char&#xff09;和布尔类型&#xff08;boo…

Vue2+OpenLayers实现折线绘制功能(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、代码实现 3.1、初始变量 3.2、画一条折线 3.3、完整代码 四、Gitee源码 一、案例截图 二、安装OpenLayers库 npm install ol 三、代码实现 3.1、初始变量 关键代码&#xff1a; data() {return {map:null,// 定义路径坐…

【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)

&#xff1a; 羑悻的小杀马特.-CSDN博客羑悻的小杀马特.擅长C/C题海汇总,AI学习,c的不归之路,等方面的知识,羑悻的小杀马特.关注算法,c,c语言,青少年编程领域.https://blog.csdn.net/2401_82648291?spm1010.2135.3001.5343 在本篇文章中&#xff0c;博主将带大家去学习所谓的…

【服务治理中间件】consul介绍和基本原理

目录 一、CAP定理 二、服务注册中心产品比较 三、Consul概述 3.1 什么是Consul 3.2 Consul架构 3.3 Consul的使用场景 3.4 Consul健康检查 四、部署consul集群 4.1 服务器部署规划 4.2 下载解压 4.3 启动consul 五、服务注册到consul 一、CAP定理 CAP定理&#xff…

Linux命令行工具-使用方法

参考资料 Linux网络命令&#xff1a;网络工具socat详解-CSDN博客 arm-linux-gnueabihf、aarch64-linux-gnu等ARM交叉编译GCC的区别_aarch64-elf-gcc aarch64-linux-gnu-CSDN博客 解决Linux内核问题实用技巧之-dev/mem的新玩法-腾讯云开发者社区-腾讯云 热爱学习地派大星-CS…

5-1 创建和打包AXI Interface IP

创建和打包AXI Interface IP的前流程和后流程 step 1 &#xff1a; 选择类型 1&#xff1a; 将当前的工程打包成IP 2&#xff1a; 将当前的BD工程打包成IP 3&#xff1a; 将指定的源码打包成IP 4&#xff1a; 创建一个新的AXI 接口IP 其中3和4是比较常用的&#xff0c;本次…

贪心算法(题1)区间选点

输出 2 #include <iostream> #include<algorithm>using namespace std;const int N 100010 ;int n; struct Range {int l,r;bool operator <(const Range &W)const{return r<W.r;} }range[N];int main() {scanf("%d",&n);for(int i0;i&l…

攻防世界 unseping

开启场景 整体来说是创建了一个case类&#xff0c;然后可接受post传来的ctf的值&#xff0c;并对其进行base64解码以及反序列化。所以我们能控制ctf变量。 先看__wakeup方法&#xff0c;该方法使用waf方法对$arg中的内容进行了防护&#xff0c;过滤掉了| & ; 空格 / cat f…

光伏储能电解水制氢仿真模型Matlab/Simulink

今天更新的内容为光伏储能制氢技术&#xff0c;这个方向我之前在21年就系统研究并发表过相关文章&#xff0c;经过这几年的发展&#xff0c;绿色制氢技术也受到更多高校的注意&#xff0c;本篇博客也是在原先文章的基础上进行更新。 首先让大家熟悉一下绿氢制取技术这个概念&a…

java spring,uName,kValue,前端传值后端接不到

大神链接https://blog.csdn.net/qq_39327650/article/details/134419523本文是参考上述大神链接&#xff0c;自己写这个博客主要是给自己加深印象&#xff0c;大神链接里描述的很清晰&#xff0c;包括源码解析&#xff0c;详细描述参考大神。 由于springboot用的是jackson进行…

XML序列化和反序列化的学习

1、基本介绍 在工作中&#xff0c;经常为了调通上游接口&#xff0c;从而对请求第三方的参数进行XML序列化&#xff0c;这里常使用的方式就是使用JAVA扩展包中的相关注解和类来实现xml的序列化和反序列化。 2、自定义工具类 import javax.xml.bind.JAXBContext; import javax.x…

【时时三省】(C语言基础)柔性数组的使用

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 示例&#xff1a; 柔性数组是一次性开辟的一块空间&#xff0c;实际上后面arr的空间是通过预设的方式&#xff0c;给它增加了一块空间 用柔性数组得好处 第一个好处是&#xff1a;方便内存…