/*
点是否在三角形内:
如果一个二维坐标系中,已知三角形顶点的坐标,那么对于坐标系中的任意一点,如何判断该点是否在三角形内(点在三角形边线上也可)?
假设三角形顶点的坐标为ABC(逆时针),需要判断点D是否在该三角形内。
分析:
利用垂涎的交点可以判断。如果点D在三角形内,所有的垂线交点都在三角形的边线之内。如果点D在三角形之外,则垂线的交点就会在三角形边线的延长线上。
但是钝角三角形是不可取的,此方法错误。
解法1:
研究点与线段之间的关系,考虑把点D和其他的三个点连接起来。将问题转化为比较三角形ABC的面积 与 三角形ABD BCD CAD的面积之和
如果Sabc = Sabd + Sbcd + Scad,那么点D在三角形ABC的内部或者边上,如果 Sabc < Sabd + Sbcd + Scad ,则点D在三角形外部。
计算三角形面积用海伦公式
计算出三边的边长分别为a,b,c,
p = (a + b + c)/2;
S = 根号下(p-a)*(p-b)*(p-c)*p
解法2:
因为三角形是凸的,所以如果有一个D在三角形ABC内,那么沿着三角形的边界逆时针走,点D一定保持在边界的左边,也就是说点D在边AB,BC,CA的左边。
判断一个点P3是否在射线P1,P2的左边,可以通过P1P2,P1P3两个向量叉积的正负判断
如果叉积为正,则P3在P1P2的左边
负, 右
0, 射线上
输入:
3 2(输入测试点的坐标)
1 1(输入三角形三个顶点的坐标)
5 1
3 3
2 3
1 1
5 1
3 3
输出:
Yes
No
*/
/*
关键:
1 if(dSabd + dSbcd + dScda > dSabc)//如果三个小三角形的面积大于原三角形面积,那么说明测试点不再原三角形内
2 return sqrt( (dP - dA) * (dP - dB) * (dP - dC) * dP);//计算面积采用海伦公式,计算出三边的边长分别为a,b,c,p = (a + b + c)/2;S = 根号下(p-a)*(p-b)*(p-c)*p
3 bool isInRectangle_vector(const Point& testPoint,Point* recPoint)//通过向量来判断测试点是否在另外两点所形成射线的左边,需要计算
//BD*BC >0 ,CD * CA > 0,AD * AB > 0
4 doubleT dRet = (point2._iX - point3._iX) * (point1._iX - point3._iX) + (point2._iY - point3._iY) * (point1._iY - point3._iY);
//我们以第三个点为主点,判断一个点P3是否在射线P1,P2的左边,可以通过P1P2,P1P3两个向量叉积的正负判断,如果叉积为正,则P3在P1P2的左边
*/
#include <stdio.h>
#include <math.h>
typedef float doubleT;
typedef struct Point
{
doubleT _iX;
doubleT _iY;
}Point;
doubleT distance(const Point& point1,const Point& point2)
{
return sqrt( (point1._iX - point2._iX) * (point1._iX - point2._iX) + (point1._iY - point2._iY) * (point1._iY - point2._iY) );
}
doubleT area(const Point& point1,const Point& point2,const Point& point3)
{
doubleT dA = distance(point1,point2);
doubleT dB = distance(point1,point3);
doubleT dC = distance(point2,point3);
doubleT dP = (dA + dB + dC)/2.0;
return sqrt( (dP - dA) * (dP - dB) * (dP - dC) * dP);//计算面积采用海伦公式,计算出三边的边长分别为a,b,c,p = (a + b + c)/2;S = 根号下(p-a)*(p-b)*(p-c)*p
}
bool isInRectangle(const Point& testPoint,Point* recPoint)
{
doubleT dSabd = area(testPoint,recPoint[0],recPoint[1]);
doubleT dSbcd = area(testPoint,recPoint[1],recPoint[2]);
doubleT dScda = area(testPoint,recPoint[2],recPoint[0]);
doubleT dSabc = area(recPoint[0],recPoint[1],recPoint[2]);
if(dSabd + dSbcd + dScda > dSabc)//如果三个小三角形的面积大于原三角形面积,那么说明测试点不再原三角形内
{
return false;
}
else
{
return true;
}
}
bool product(const Point& point1,const Point& point2,const Point& point3)
{
doubleT dRet = (point2._iX - point3._iX) * (point1._iX - point3._iX) + (point2._iY - point3._iY) * (point1._iY - point3._iY);
//我们以第三个点为主点,判断一个点P3是否在射线P1,P2的左边,可以通过P1P2,P1P3两个向量叉积的正负判断,如果叉积为正,则P3在P1P2的左边
return dRet > 0.0 ? true : false;
}
bool isInRectangle_vector(const Point& testPoint,Point* recPoint)//通过向量来判断测试点是否在另外两点所形成射线的左边,需要计算
//BD*BC >0 ,CD * CA > 0,AD * AB > 0
{
bool bRet1 = product(testPoint,recPoint[0],recPoint[1]);
bool bRet2 = product(testPoint,recPoint[1],recPoint[2]);
bool bRet3 = product(testPoint,recPoint[2],recPoint[0]);
return bRet1 && bRet2 && bRet3;
}
void process()
{
Point testPoint;
Point rectanglePoint[3];
while(EOF != scanf("%f %f",&testPoint._iX,&testPoint._iY))
{
for(int i = 0 ; i < 3 ; i++)
{
scanf("%f %f",&rectanglePoint[i]._iX,&rectanglePoint[i]._iY);
}
//if(isInRectangle(testPoint,rectanglePoint))
if(isInRectangle_vector(testPoint,rectanglePoint))
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
}
int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}
编程之美:第四章 数字之趣 4.4点是否在三角形内
原文作者:天地一扁舟
原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/47187873
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/47187873
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。