【计算几何】确定两条连续线段向左转还是向右转

确定两条连续线段向左转还是向右转

目录

  • 一、说明
  • 二、算法
    • 2.1 两点的叉积
    • 2.2 两个段的叉积
  • 三、旋转方向判别
    • 3.1 左转
    • 3.2 右转
    • 3.3 共线判别

一、说明

   如果是作图,或者是判别小车轨迹。为了直观地了解,从当前点到下一个点过程中,什么是左转、什么是右转,或者方向不变,这在现场实时运算中是很重要的。本篇描述其快速算法。

   请考虑下面所示的示例。
在这里插入图片描述

   两图中,共有三点p1,p2和p3和两条线段 p 1 p 2 ‾ \overline{p_1p_2} p1p2 p 2 p 3 ‾ \overline{p_2p_3} p2p3。中途点 p 2 p_2 p2是两条线段共有的。在图(a)中,线段 p 2 p 3 ‾ \overline{p_2p_3} p2p3 p 2 p_2 p2该点右转而在图(b)中,段 p 2 p 3 ‾ \overline{p_2p_3} p2p3在公共点 p 2 p_2 p2左转。我们的眼睛更容易通过观察图形来快速识别路段是左转还是右转,因为您的眼睛天生具有快速识别事物的能力。在这篇文章中,我将讨论计算机如何使用几何算法来识别这一点。

二、算法

2.1 两点的叉积

   给定两点 p 1 ( x 1 , y 1 ) p_1(x_1,y_1) p1(x1,y1 p 2 ( x 2 , y 2 ) p_2(x_2,y_2) p2(x2,y2),我们首先需要判断点是否 p 1 p_1 p1从点开始是顺时针还是逆时针 p 2 p_2 p2就起源而言。解决这个问题的一种方法是计算两者所成的角度 p 1 ‾ \overline{p_1} p1 p 2 ‾ \overline{p_2} p2
和X轴和角度的差异可以判断一个点是顺时针还是逆时针。有一个比查找计算向量叉积的角度更简单有效的解决方案 p 1 ‾ \overline{p_1} p1 p 2 ‾ \overline{p_2} p2。数学上两个向量的叉积 p 1 ‾ \overline{p_1} p1 p 2 ‾ \overline{p_2} p2定义成:
p 1 × p 2 = x 1 y 2 − x 2 y 1 p_1×p_2=x_1y_2-x_2y_1 p1×p2=x1y2x2y1

   如果值p1×p2为正,则p1是沿逆时针到达p2,关于原点如下图所示。
在这里插入图片描述

   同样,如果p1×p2是负数,从p1到p2是顺时针过度。相对于原点,如果值为 0,则点p1,p2和原点共线。以下 python 代码实现了叉积。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def subtract(self, p):
    	return Point(self.x - p.x, self.y - p.y)

    def __str__(self):
        return '(' + str(self.x) + ', ' + str(self.y) + ')'

# calculates the cross product of vector p1 and p2
# if p1 is clockwise from p2 wrt origin then it returns +ve value
# if p2 is anti-clockwise from p2 wrt origin then it returns -ve value
# if p1 p2 and origin are collinear then it returs 0
def cross_product(p1, p2):
	return p1.x * p2.y - p2.x * p1.y

2.2 两个段的叉积

   考虑两个线段,其端点是p1(X1,y1),p2(X2,y2)和p1(X1,y1),p3(X3,y3)分别。为了计算两个线段的叉积,我们需要将它们转换为向量。这可以通过以下方式完成。

p 1 p 2 ‾ = ( x 2 − x 1 , y 2 − y 1 ) , p 1 p 3 ‾ = ( x 3 − x 1 , y 3 − y 1 ) \overline{p_1p_2} = (x_2 - x_1, y_2 - y_1), \overline{p_1p_3} = (x_3 - x_1, y_3 - y_1) p1p2=(x2x1,y2y1),p1p3=(x3x1,y3y1)

   一旦我们有了两个两个向量,我们就可以调用cross_product来计算叉积,如下面的代码所示。

# returns the cross product of vector p1p3 and p1p2
# if p1p3 is clockwise from p1p2 it returns +ve value
# if p1p3 is anti-clockwise from p1p2 it returns -ve value
# if p1 p2 and p3 are collinear it returns 0
def direction(p1, p2, p3):
	return  cross_product(p3.subtract(p1), p2.subtract(p1))

三、旋转方向判别

3.1 左转

   判断一个段是否 p 2 p 3 p_2p_3 p2p3从路段左转 p 1 p 2 p_1p_2 p1p2在点 p 2 p_2 p2,我们画下一个向量 p 1 p 3 ‾ \overline{p_1p_3} p1p3并检查新向量是否与向量逆时针方向 p 2 p 3 ‾ \overline{p_2p_3} p2p3。如下图所示。右图显示向量
在这里插入代码片在这里插入图片描述

   p 1 p 3 ‾ \overline{p_1p_3} p1p3从向量逆时针方向 p 1 p 2 ‾ \overline{p_1p_2} p1p2因此我们可以说该段p2p3
从路段左转p1p2在点p2。下面给出了 python 实现。

# checks if p3 makes left turn at p2
def left(p1, p2, p3):
	return direction(p1, p2, p3) < 0

3.2 右转

   这与左转相同,唯一的区别是向量 p 1 p 3 ‾ \overline{p_1p_3} p1p3从向量顺时针方向 p 2 p 3 ‾ \overline{p_2p_3} p2p3。下面给出了 python 实现。

# checks if p3 makes right turn at p2
def right(p1, p2, p3):
	return direction(p1, p2, p3) > 0

3.3 共线判别

   当该方法direction既不返回正值也不返回负值而是返回零时,就会出现一种特殊情况。在这种情况下,所有的点 p 1 p_1 p1, p 2 p_2 p2 p 3 p_3 p3位于同一条线上。在本例中段 p 2 p 3 p_2p_3 p2p3不转向任何方向。

# checks if p1, p2 and p3 are collinear
def collinear(p1, p2, p3):
	return direction(p1, p2, p3) == 0

参考
Cormen, TH、Leiserson, CE、Rivest, RL 和 Stein, C.(nd)。算法简介(第三版)。麻省理工学院出版社。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

树莓派4B(Raspberry Pi 4B)使用docker搭建阿里巴巴sentinel服务

树莓派4B&#xff08;Raspberry Pi 4B&#xff09;使用docker搭建阿里巴巴sentinel服务 由于国内访问不了docker hub&#xff0c;而国内镜像仓库又没有适配树莓派ARM架构的sentinel镜像&#xff0c;所以我们只能退而求其次——自己动手构建镜像。本文基于Ubuntu&#xff0c;Jav…

springboot169基于vue的工厂车间管理系统的设计

基于VUE的工厂车间管理系统设计与实现 摘 要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。本…

书生谱语-大语言模型测试demo

课程内容简介 1.作业 demo1 demo2 demo3 demo4

Makefile编译原理 make 中的路径搜索_1

一.make中的路径搜索 问题&#xff1a;在实际的工程项目中&#xff0c;所有的源文件和头文件都放在同一个文件夹中吗&#xff1f; 实验1 &#xff1a; VPATH 引子 mhrubuntu:~/work/makefile1/17$ ll total 28 drwxrwxr-x 4 mhr mhr 4096 Apr 22 00:46 ./ drwxrwxr-x 7 mhr m…

《UE5_C++多人TPS完整教程》学习笔记10 ——《P11 设置加入游戏会话(Setup for Joining Sessions)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P11 设置加入游戏会话&#xff08;Setup for Joining Sessions&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&…

Python远程控制工具的使用

本节我们对所编写的远程控制工具的功能进行测试。首先开启主控端程序&#xff0c; 如下所示&#xff1a; 接下来打开被控端程序。当被控端打开时&#xff0c;主控端会收到被控端的连接请 求。 开启被控端程序&#xff1a; 主控端接收到连接请求并显示被控端主机的信息&#xff…

MySQL-----DCL基础操作

▶ DCL简介 DCL英文全称是Data ControlLanguage(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 DCL--管理用户 ▶ 查询用户 use mysql; select * from user; ▶ 创建用户 ▶ 语法 create user 用户名主机名 identified by 密码 设置为在任意主机上访问…

Z-Stack一直卡在HAL_BOARD_INIT();

原因是Debugger没有配置好&#xff0c;因为默认是Simulator&#xff0c;不是TI的驱动&#xff0c;所以仿真出现一直卡在 HAL_BOARD_INIT(); 的情况&#xff0c;解决方法就是将Simulator改为Texas Instruments 改成下面的样子

MySQL篇----第二十篇

系列文章目录 文章目录 系列文章目录前言一、NULL 是什么意思二、主键、外键和索引的区别?三、你可以用什么来确保表格里的字段只接受特定范围里的值?四、说说对 SQL 语句优化有哪些方法?(选择几条)前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍…

Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)

文章目录 题目链接题意题解代码 题目链接 C. Digital Logarithm 题意 给两个长度位 n n n的数组 a a a、 b b b&#xff0c;一个操作 f f f 定义操作 f f f为&#xff0c; a [ i ] f ( a [ i ] ) a [ i ] a[i]f(a[i])a[i] a[i]f(a[i])a[i]的位数 求最少多少次操作可以使 …

单片机学习笔记---串口向电脑发送数据电脑通过串口控制LED

目录 串口向电脑发送数据 每隔一秒串口就发送一个递增的数给电脑 电脑通过串口控制LED 波特率的具体计算 HEX模式和文本模式 前两节是本节的理论基础&#xff0c;这节开始代码演示&#xff01; 串口向电脑发送数据 接下来先开始演示一下串口单向发送一个数字给电脑&…

【Git】上传本地文件到Git(以Windows环境为例)

Git 的下载参考&#xff1a;Git 安装及配置 一、Git 上传的整体流程 1、工作区 > 本地仓库 将本地文件上传到Git&#xff0c;需要先上传到本地仓库&#xff0c;然后再上传到远程仓库。要上传文件到本地仓库&#xff0c;不是直接拷贝进去的&#xff0c;而是需要通过命令一步…

2024-02-11 Unity 编辑器开发之编辑器拓展2 —— 自定义窗口

文章目录 1 创建窗口类2 显示窗口3 窗口事件回调函数4 窗口中常用的生命周期函数5 编辑器窗口类中的常用成员6 小结 1 创建窗口类 ​ 当想为 Unity 拓展一个自定义窗口时&#xff0c;只需实现继承 EditorWindow 的类即可&#xff0c;并在该类的 OnGUI 函数中编写面板控件相关的…

QT入门-信号与槽

1.QT基本框架 #include "myWindow.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);myWindow w;w.show();return a.exec(); } QApplicata&#xff1a;应用程序对象&#xff0c;必须有且只能有一个 Qwidget&#xff1…

过河卒(洛谷)

题目 原题 题目描述 棋盘上 A A A 点有一个过河卒&#xff0c;需要走到目标 B B B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C C C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。…

3秒实现无痛基于Stable Diffusion WebUI安装ComfyUI!无需重复安装环境!无需重复下载模型!安装教程

标题略有夸张的表达了接下来这一套确实很简单&#xff0c;相较于直接下载或者通过秋叶包更新而言。大大节省磁盘空间&#xff0c;和下载时间。 这篇教程不需要你有&#xff1a; 代码基础。都是复制粘贴就完事。魔法。 这篇教程默认你已经有&#xff1a; 1. 本地能够正常使用…

汽车出租管理系统

文章目录 汽车出租管理系统一、系统演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 汽车出租管理系统 一、系统演示 汽车租赁系统 二、项目介绍 语言&#xff1a;java 框架&#xff1a;SpringBoot、…

【2024年数据】67个“绿色金融”主题DID政策汇总(已去重)

DID”发文趋势和主题分布 数据来源&#xff1a;中国知网、各期刊官网 时间跨度&#xff1a;2017-2024年 数据范围&#xff1a;中国各省 数据指标&#xff1a; 序号 用于构建DID的政策 文献标题 1 “宽带中国” 数字技术创新与中国企业高质量发展——来自企业数字专利的证据…

陶陶摘苹果C++

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; int main(){//一、分析问题//已知&#xff1a;10 个苹果到地面的高度a[10],陶陶把手伸直的时候能够达到的最大高度height//未知&#xff1a;陶陶能够摘到的苹果的数目sum。//关系&#xff…

ncc匹配提速总结

我们ncc最原始的匹配方法是&#xff1a;学习模板w*h个像素都要带入ncc公式计算 第一种提速&#xff0c;学习模板是w*h&#xff0c;而我们支取其中的w/2*h/2,匹配窗口同理&#xff0c;计算量只有1/4。 另外一种因为ncc是线性匹配&#xff0c;我们在这上面也做了文章&#xff0…