计算几何学

2023-11-13

问题描述

对于线段s1、s2,如果相交则输出“1”,否则输出“0”。
设s1的端点为p0、p1、,s2的端点为p2、p3。

输入:
第1行输入问题数q。接下来q行给出q个问题。各问题线段s1、s2的坐标按照以下格式给出:
x p 0 x_{p0} xp0 y p 0 y_{p0} yp0 x p 1 x_{p1} xp1 y p 1 y_{p1} yp1 x p 2 x_{p2} xp2 y p 2 y_{p2} yp2 x p 3 x_{p3} xp3 y p 3 y_{p3} yp3
输出:
根据各问题输出1或0,每个问题占1行。
限制:
1 ≤ q ≤ 1000
-10000 ≤ x p i , y p i x_{p_i},y_{p_i} xpi,ypi ≤ 10000
p0、p1不是同一个点
p2、p3不是同一个点。

输入示例

3
0 0 3 0 1 1 2 -1
0 0 3 0 3 1 3 -1
0 0 3 0 3 -2 5 0

输出示例

1
1
0

讲解

这些情况均视为相交:

普通相交
一条线段的端点位于另一条线段上
两条线段公用一个端点
两条线段平行重合

前面讲的ccw用于检查点线间的位置关系(ccw详细解释:计算几何学 | 逆时针方向 | Counter-Clockwise | C/C++实现),只要对其加以应用,我们就能轻松判断出两条线段是否相交。

分别检查两条线段,如果双方都符合“另一条线段的两个端点分别位于当前线段的顺时针方向和逆时针方向”,则两条线段相交。

判断线段p1p2与线段p3p4是否相交的程序可以像下面这样写

判断线段p1p2和线段p3p4是否相交:

bool intersect(Point p1, Point p2, Point p3, Point p4) {
	return ( ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
			ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0 );
}

bool intersect(Segment s1, Segment s2) {
	return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

上述程序以四个点p1、p2、p3、p4为参数,判断线段p1p2与线段p3p4是否相交,若相交则返回true。

ccw(p1, p2, p3) * ccw(p1, p2, p4)用来分别检查p3、p4相对于线段p1p2的位置,然后求出结果的积。只要实现将ccw的返回值定义为
COUNTER_CLOCKWISE = -1;
CLOCKWISE = 1;
ON_SEGMENT = 0;
ccw(p1, p2, p3) * ccw(p1, p2, p4)在p3、p4位于不同侧时就会得出-1,p3或p4位于线段p1p2上时得出0.点p1、p2相对于线段p3p4的位置也是同理。接下来,只要线段p1p2、p3p4的判断均小于等于0,即可确定它们相交。

AC代码如下

#include<stdio.h>
#include<iostream>
#include<cmath>
using namespace std;

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

class Point {//Point类,点 
	public:
		double x, y;
		
		Point(double x = 0, double y = 0): x(x), y(y) {}

		Point operator + (Point p) { return Point(x + p.x, y + p.y); }
		Point operator - (Point p) { return Point(x - p.x, y - p.y); }
		Point operator * (double a) { return Point(a * x, a * y); }
		Point operator / (double a) { return Point(x / a, y / a); }

		double abs() { return sqrt(norm()); }
		double norm() { return x * x + y * y; }
		
		bool operator < (const Point &p) const {
			return x != p.x ? x < p.x : y < p.y;
		}

		bool operator == (const Point &p) const {
			return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
		}
};

typedef Point Vector;//Vector类,向量 

struct Segment{//Segment 线段 
	Point p1, p2;
};
double dot(Vector a, Vector b) {//内积 
	return a.x * b.x + a.y * b.y;
}

double cross(Vector a, Vector b) {//外积 
	return a.x*b.y - a.y*b.x;
}

Point reflect(Segment s, Point p) {//映像 以线段s为对称轴与点p成先对称的点
//对于三个点p1、p2、p,设以通过p1、p2的直线为对称轴与点p成线对称的点为x,
//求点x的坐标(点p对于直线p1p2的映像) 
	return p + (project(s, p) - p) * 2.0;
} 
*/
static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0, Point p1, Point p2) {
	Vector a = p1 - p0;
	Vector b = p2 - p0;
	if( cross(a, b) > EPS ) return COUNTER_CLOCKWISE;
	if( cross(a, b) < -EPS ) return CLOCKWISE;
	if( dot(a, b) < -EPS ) return ONLINE_BACK;
	if( a.norm() < b.norm() ) return ONLINE_FRONT;

	return ON_SEGMENT;
}

bool intersect(Point p1, Point p2, Point p3, Point p4) {
	return ( ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
			ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0 );
}

bool intersect(Segment s1, Segment s2) {
	return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

int main(){
	int q;
	cin>>q;
	
	Segment s1, s2;
	
	while(q--){
		cin>>s1.p1.x>>s1.p1.y>>s1.p2.x>>s1.p2.y>>s2.p1.x>>s2.p1.y>>s2.p2.x>>s2.p2.y;
		cout<<intersect(s1, s2)<<endl;
	}
} 

注:以上本文未涉及代码的详细解释参见:计算几何学

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算几何学 的相关文章

  • 微信开发者工具调试大法

    由于小程序的火爆 于是去开源中国接了个私活 开发一个小程序 于是开始学习微信小程序开发文档 下载微信开发者工具 进行开发了 开发过程中需要调试 开始只是打日志或者断言 觉得很不方便 希望跟IDEA一样的调试器 于是摸索如下 第一步 打断点
  • 异步系统级错误处理

随机推荐

  • IDEA远程调试程序

    一 服务端 本次实验服务端配置 Tomcat Apache Tomcat 8 5 32 查看命令 sh Tomcat安装目录 bin version sh JVM 1 8 0 131 b11 jdk 8 System 3 10 0 693
  • range的用法,pycharm的快捷键格式对其,和多变量赋值在一行

    python range 函数可创建一个整数列表 一般用在 for 循环中 range start stop step start 计数从 start 开始 默认是从 0 开始 例如range 5 等价于range 0 5 stop 计数到
  • 上周AI热点回顾:AI“模拟”出暗物质、AI挖掘毕加索秘密、CPU在大型神经网络超越V100 GPU...

    01 全球首个AI宇宙模拟器跑出了暗物质 Space Engine是一款宇宙模拟游戏 它包含数千个真实的天体 包括来自HIP目录的恒星 来自NGC和IC目录的星系 几个知名的星云 以及所有已知的系外行星和它们的恒星 它采用星表与程序化生成创
  • Mac 环境现有项目集成 RN环境

    开发环境 mac rn版本 0 62 2 xcode版本 11 6 一 集成cocopods 参考文档 https www jianshu com p 6d51362b7e64 1 查看当前Ruby版本 ruby v 2 升级Ruby环境
  • 48-输入和显示-进度条控件QProgressBar

    进度条控件QProgressBar 进度条控件QProgressBar 通常用来显示一项任务完成的进度例如复制文件导出数据的进度 进度条QProgressBar是从QWidget 继承而来的 用QProgressBar类创建实例对象的方法如
  • [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决

    这篇文章主要讲述Python如何安装Numpy Scipy Matlotlib Scikit learn等库的过程及遇到的问题解决方法 最近安装这个真是一把泪啊 各种不兼容问题和报错 希望文章对你有所帮助吧 你可能遇到的问题包括 Impor
  • android父元素,Android之布局

    LinearLayout 线性布局 线性布局 最常用的布局之一 所有包含在线性布局里的控件在线性方向上依次排列 注意 线性布局不会换行 当组件一个挨着一个地排列到头之后 剩下的组件将不会被显示出来 1 方向 在线性布局里面的控件 是按照线性
  • vue axios解决文件流下载乱码

    前端请求头 responseType blob 一定要加 是单独一个对象 不能放在请求参数里面 new Blob res type application vnd ms excel charset utf 8 一定要设置类型 和后端resp
  • JDK、JRE、JVM三者间的关系

    JDK Java Development Kit 是针对Java开发员的产品 是整个Java的核心 包括了Java运行环境JRE Java工具和Java基础类库 Java Runtime Environment JRE 是运行JAVA程序所
  • Go语言简介

    一 Go编程语言概述 Go语言也叫Golang 是由谷歌 Google 公司在2007年推出的一款静态编译型语言 主要将其用于服务端开发 并发编程和网络编 程等 1 1 Go语言特性及应用场景 1 容易上手 2 编程速度快 3 原生支持并发
  • iPhone手机屏幕尺寸分辨率一览

    机型 物理像素 逻辑像素 规格 对角线 iPhone 12 Pro Max 1284 2778px 428 926pt 3x 6 7英寸 iPhone 12 Pro 1170 2532px 390 844pt 3x 6 1英寸 iPhone
  • 吃货联盟订餐系统(用对象和数组来写的)

    目录 一 自我介绍 2 吃货联盟订餐系统 1 首先创建一个订单类 2 创建一个餐品类 3 创建一个操作类 作用是添加订单 删除订单等操作 三 未来的发展规划 四 图书管理系统 用数组写的 一 自我介绍 我目前还是正在上学的学生 现在正在学习
  • Cpolar内网穿透+HadSky:搭建私密高效的轻量化论坛网站

    文章目录 前言 1 网站搭建 1 1 网页下载和安装 1 2 网页测试 1 3 cpolar的安装和注册 2 本地网页发布 2 1 Cpolar临时数据隧道 2 2 Cpolar稳定隧道 云端设置 2 3 Cpolar稳定隧道 本地设置 2
  • arduino舵机达180不到_【舵机初动】基于Mind+ Ardunio入门教程10

    点击上方 蘑菇云创造 可以关注我们哦 本项目要接触到舵机 舵机是一种电机 它使用一个反馈系统来控制电机的位置 可以很好掌握电机角度 大多数舵机是可以最大旋转180 的 也有一些能转更大角度 甚至360 舵机比较多的用于对角度有要求的场合 比
  • 【Basis】变分推断以及VIEM

    在包含隐变量 latent variables 的推断问题中 针对连续性随机变量的情况 隐变量的高维以及被积函数 intergrand 的复杂度使积分 intergration 无法进行 而针对离散型随机变量 隐变量呈指数 exponent
  • Git 本地代码上传到远程仓库

    Git本地代码上传到远程仓库 1 进入项目地址 通过命令git init将项目初始化成git本地仓库 git init 2 将项目内所有文件都添加到暂存区 git add 3 该命令会将git add 存入暂存区修改内容提交至本地仓库中 若
  • 寒假:HTML

    gt 框架的主要作用是使页面中的部分内容实现框架实现 一般用于在页面中引用站外的页面内容 1 在被打开的框架上加name属性 代码如下 2 在超链接上设置target目标窗口属性为希望显示的框架窗口名 lt a href target ma
  • dbeaver无法修改表数据_解决MDL锁导致无法操作数据库表的问题

    背景信息 MYSQL的MDL锁 用于解决或者保证DDL操作与DML操作之间的一致性 但是在部分场景下会出现阻塞 例如执行DML操作时执行ALTER操作 存在长时间查询时执行ALTER操作等等 表象如下 出现 Waiting for tabl
  • STM32 电机教程 20 - 基于ST MC Workbench 无感FOC

    前言 磁场定向控制又称矢量控制 FOC 本质上为控制定子电流的幅度和相位 使之产生的磁场和转子的磁场正交 以产生最大的扭矩 PMSM的磁场定向控制框图如下图所示 第19讲成功实现了基于NUCLEO F103RB和X NUCLEO IHM07
  • 计算几何学

    问题描述 对于线段s1 s2 如果相交则输出 1 否则输出 0 设s1的端点为p0 p1 s2的端点为p2 p3 输入 第1行输入问题数q 接下来q行给出q个问题 各问题线段s1 s2的坐标按照以下格式给出 x p 0 x p0