代码改变世界

求点是否在三角形内

2011-09-06 23:37  x_feng  阅读(374)  评论(0编辑  收藏  举报

问题:

在一个屏幕上如何判断一次点击,在一个三角形的按钮内?

解决方法:

在编程之美上提供了2种方法,一种是求面积的方法,一种是点关系的矢量方法。其实两种方法的代码实现几乎相同,但考虑到效率问题,矢量法比较合适。在求面积的方法中用到了除法和开平方运算,矢量法却没有,但它有一个非常要注意的地方,即三角形的三个顶点必须是按逆时针顺序方向排列传入函数体。

矢量法:如果一个点在三角形内,则按照逆时针方向,这个点都在3条边的左边。判断一个点D,是否在一条射线a,b的左边,可以通过a->b,a->D两个向量叉积的正负来判断,叉积为正D在ab的左边,叉积为0在射线ab上,否则在外。

具体代码如下:

#include <iostream>
using namespace std;

typedef struct _Point{
	double x;
	double y;
};
//A,B,C是一个三角形顶点的逆时针顺序,其位置顺序不能更改
//如果D在三角形之外,就是没有点中这个三角形的按钮,函数返回false,否则为true
double PhasorCompare(const _Point& A, const _Point& B, const _Point& C){
	return (B.x - A.x)*(C.y - A.y) - (B.y - A.y)*(C.x - A.x);
}
bool IsInTriangle(const _Point& pointA, const _Point& pointB, const _Point& pointC, const _Point& pointD){
	if (PhasorCompare(pointA, pointB, pointD) >= 0.0 && PhasorCompare(pointB, pointC, pointD) >= 0.0 && PhasorCompare(pointC, pointA, pointD) >= 0.0){
		return true;
	}
	return false;
}

ps:发现在手持设备上很多游戏的按钮都设计成方型或圆形,至于其它形状的按钮确很少见,当然按钮的形状越复杂,估计计算量会大吧。如果需要对一个不规则形状的按钮进行精确判断是否点击中时,该如何做呢?希望以后能找到很好的方法。