已知四边形的四个点,求一个点是否在四边形之内的解决方法

已知四边形(凸四边形)的四个点A、B、C、D(按逆时针顺序)的坐标,求点P是否在ABCD所围成的四边形内,可以通过向量叉乘的方法实现。


http://www.dewen.io/q/5805/Android

先提供一种简单情景(假定四边形是一个凸四边形)的解决方法:

原理:凸多边形内部的点都在凸多边形的边所在的向量的同一侧(前提是计算边所在的向量时采用的是同一个方向,同为顺时针或者同为逆时针),利用叉积求解。
假设四边形四个顶点依次为A(x1,y1),B(x2,y2),C(x3,y3),D(x4,y4),待判断的点为P(x,y),如果点P在四边形内部,则向量AB * AP(注意:1.这是求叉积;2.AB、AP均为向量,也就等于(x2-x1) * (y-y1)-(y2-y1) * (x-x1))的值与BC*BP、CD * CP、DA * DP的值同号(若有等于零的情况,则表示P在边上,可以根据自己的喜好把它当做是内部或者外部),即四个值同为正或者同为负,则点P在ABCD内部,否则在外部。
如果是凹四边形还要做一些其他处理,就是找到导致四边形为凹的那个顶点,也是借助于叉积(可以参考我的博客:http://tristan-xi.org/?p=113 ,只需记录中间哪个点所求的向量叉积与其它几点异号即可),然后把四边形分成两个三角形(三角形肯定是凸的了),再按照上面的方法计算叉积,即可解决。
总结:叉积是判断多边形凹凸性以及点是否在凸多边形内部的利器。


向量AB(B.x - A.x , B.y - A.y);

向量AP(P.x - A.x , P.y - A.y);

向量叉乘ABxAP = (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x);

	private boolean isPointInRect(int x, int y) {
		final Point A = mLBPoint;
		final Point B = mLTPoint;
		final Point C = mRTPoint;
		final Point D = mRBPoint;
		final int a = (B.x - A.x)*(y - A.y) - (B.y - A.y)*(x - A.x);
		final int b = (C.x - B.x)*(y - B.y) - (C.y - B.y)*(x - B.x);
		final int c = (D.x - C.x)*(y - C.y) - (D.y - C.y)*(x - C.x);
		final int d = (A.x - D.x)*(y - D.y) - (A.y - D.y)*(x - D.x);
		if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
			return true;
		}
		
//		AB X AP = (b.x - a.x, b.y - a.y) x (p.x - a.x, p.y - a.y) = (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x);
//		BC X BP = (c.x - b.x, c.y - b.y) x (p.x - b.x, p.y - b.y) = (c.x - b.x) * (p.y - b.y) - (c.y - b.y) * (p.x - b.x);
		return false; 
	}


  • 21
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值