编程之美 4.4点是否在三角形内
问题:如果一个二维坐标系中,已知三角形三个点的坐标,那么对于任意一点,如何判断其在三角形内呢?(点在三角形边上也算在三角形内)
解法一:面积法
S=Area(ABC)、S1=Area(ABP)、S2=Area(BCP)、S3=Area(CAP)
若P点在三角形内,S=S1+S2+S3
若P在三角形外,S1+S2+S3>S
计算三角形的面积可以使用海伦公式
而公式里的p为半周长(周长的一半):
但注意了我们可以利用向量积的几何意义以两个向量为邻边的平行四边形的面积(即三角形面积的2倍)
若 |AB×BP| + |BC×CP| + |CA×AP| = |AB×BC|,则得点 P 在 △ABC 内。
解法二:叉乘法
沿 △ABC 各有向边按一定方向走(顺时针或逆时针),判断点 P 是否在该边的某侧(右侧或左侧),若点 P 在三条边的同侧,则点 P 在 △ABC 内。
分别计算向量 AB、BC、CA 与向量 AP、BP、CP 的向量积(叉乘),若三个结果均同号(正或负,为零表示 P 在边上),则可得点 P 在 △ABC 内。
其中AB = B - A,AB×AP = AB.x*AP.y - AB.y*AP.x即 x1y2-y1x2。
其实不止三角形对于凸多边形也是可以通过叉乘法来判断的。
补充知识:
所谓凸多边形,就是把一个多边形任意一边向两方无限延长成为一条直线,如果多边形的其他各边均在此直线的同旁,那么这个多边形就叫做凸多边形。
下面是示例代码:注意面积法对输入的点序没要求,叉乘法就要按逆时针的顺序。
#include <iostream> #include <cmath> using namespace std;struct point {double x,y;point(double _x=0,double _y=0){x=_x;y=_y;} };inline double VecProduct(point A,point B,point P) {return (B.x-A.x)*(P.y-A.y)-(B.y-A.y)*(P.x-A.x); }double TriArea(point A,point B,point P) {return abs((B.x-A.x)*(P.y-B.y)-(B.y-A.y)*(P.x-B.x)); }//method:Area bool isInTriangle1(point A,point B,point C,point P) {double sABP,sBCP,sCAP,sABC;sABP=TriArea(A,B,P);sBCP=TriArea(B,C,P);sCAP=TriArea(C,A,P);sABC=TriArea(A,B,C);if (sABC==sABP+sBCP+sCAP){return true;}return false; } //method:Vector Product,ABC anticlockwise bool isInTriangle2(point A,point B,point C,point P) {if (VecProduct(A,B,P)>=0 && VecProduct(B,C,P)>=0 && VecProduct(C,A,P)>=0){return true;}return false; }void main() {point A(0,2);point B(0,0);point C(2,0);point P1(1,1);//in the Trianglepoint P2(4,4);//outside the Triangle point P3(2,0);//on the edge of the Triangle cout<<boolalpha<<isInTriangle1(A,B,C,P1)<<endl;cout<<boolalpha<<isInTriangle1(A,B,C,P2)<<endl;cout<<boolalpha<<isInTriangle1(A,B,C,P3)<<endl;cout<<boolalpha<<isInTriangle2(A,B,C,P1)<<endl;cout<<boolalpha<<isInTriangle2(A,B,C,P2)<<endl;cout<<boolalpha<<isInTriangle2(A,B,C,P3)<<endl; }
转载于:https://www.cnblogs.com/Linkabox/p/3357768.html
编程之美 4.4点是否在三角形内相关推荐
- 《编程之美》读书笔记19: 3.9 重建二叉树
<编程之美>读书笔记19: 3.9 重建二叉树 对根节点a以及先序遍历次序P和中序遍历次序I,查找a在I中的位置,将I分为两部分,左边部分的元素都在a的左子树上,右边的元素都在a的右子树上 ...
- 编程之美计算0到N中包含数字1的个数
转自:http://blog.csdn.net/hongjuntu123/article/details/8743266 有这样一个函数f(n),对于任意正整数n,它表示从 0 到 n 之间出现&qu ...
- 《编程之美》读书笔记08:2.9 Fibonacci序列
<编程之美>读书笔记08:2.9 Fibonacci序列 计算Fibonacci序列最直接的方法就是利用递推公式 F(n+2)=F(n+1)+F(n).而用通项公式来求解是错误的,用浮点数 ...
- [搜索]字符串的相似度问题-从编程之美说起
在<编程之美>之3.3讲到了计算字符串的相似度,请看下图 原文作者做了很详细的解释,有兴趣的朋友可以参考原文. 其实,总结为一点,是求两个字符的编辑距离,关于编辑距离,可以参考这儿 htt ...
- 编程之美系列之一——阶乘的运算
前言: 本人一直以来都对算法很有兴趣,前些日子拿到<编程之美>这本书,爱不释手,遂有意将书中的一些本人觉得较有意思的题目以及自己的心得拿出来与大家分享,共同讨论,共同进步. 需 ...
- java并发编程之美-阅读记录1
1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...
- 【编程之美】金刚坐飞机问题
题目描述 现在有一架飞机要起飞,乘客们正准备按机票号码(1,2,3...,N)一次排队登机.突然来了一只大猩猩(金刚).他也有机票,但是他插队第一个登上了飞机,然后随意的选择了一个座位坐下了.根据社 ...
- 编程之美之控制cpu线
其实这也没什么值得惊讶的,因为在理解了操作系统调度,以及cpu的指令周期后,都可以用程序模拟出来 下面是编程之美给出的正弦曲线,在一定间隔内,一半时间运行,一半时间sleep.Windows自带的pe ...
- 《编程之美》读书笔记(十):“链表相交”扩展问题
感谢azuryy提供<编程之美>3.6节"链表相交"扩展问题答案 (原博客地址:http://hi.baidu.com/azuryy/blog/item/18e85b0 ...
- 编程之美 求数组中的最长递增子序列
如题,例如:存在数组 1,-1,2,-3,4,-5,6,-7 ,则最长的递增子序列是:1,2,4,6. 法一: 蛮力法 int Lis(int* arr,int n) {int iCount=0;// ...
最新文章
- channelinboundhandler中都包含了哪一类的方法_备考CMA考试有哪些方法技巧?
- git reset用法
- c++程序设计原理与实践_课程思政水资源系统优化原理与方法课程思政元素的探索...
- 用户测评 | EDAS Serverless 上手体验 1
- ASP.NET Session详解
- 如何理解和运用策略模式
- informix数据库 java 增删改查
- 冲刺第二阶段工作总结01
- 右键菜单 GenericMenu
- soapui直接下载响应内容为本地的文件
- 第六届蓝桥杯--奇妙的数字和移动距离
- matlab根据脉冲计算转速,求不规则脉冲之前的时间间隔,进而求出电机转速
- ssa/ass字幕格式全解析
- 数据可视化工具在医疗领域的应用
- 计算机wifi共享usb设备,手机设置wifi热点如何通过usb和电脑共享网络
- go语言interface用法
- 防火墙——L2TP基础知识
- Pr 入门教程如何向影片中的剪辑添加过渡效果?
- 华为服务体系:ITR流程体系详解
- android ui设计最新字体,ui用什么字体_安卓ui设计用什么字体
热门文章
- 匈牙利算法求最大匹配
- c#解析json字符串数组_在C#中解析Json字符串
- java alder32,[java][io][ZIP]应用GZIP进行压缩和解压缩
- 软件测试 vb,使用VB6.0进行自动化测试
- 关于EasyUI在Datagrid里面将某一列设置为超链接并传递当前行的某一参数传递给打开的对话框。
- html没建站点,网页前端之HTML+CSS+JS
- office2010 反应慢_office2010打开时间太慢。怎么办?
- java是否安装outlook,Java程序定期检查ms Outlook是否有新邮件
- c语言 stm32结构体赋值,STM32学习笔记9——结构体赋值问题
- C#中,接口继承、基类继承中父类与基类的执行顺序