软件编程
位置:首页>> 软件编程>> Android编程>> Android如何判断一个点在不在多边形区域内

Android如何判断一个点在不在多边形区域内

作者:呆呆的小木头  发布时间:2023-07-06 14:06:13 

标签:Android,判断,多边形

有人问我,怎么判断一个点是不是在多边形内,本来想着把这个多边形分成一个又一个三角形,如图,

 Android如何判断一个点在不在多边形区域内

然后判断这个点是不是在某个三角形中,如果在,那就肯定在这个多边形中,那问题接下来就转化成判断这个点是不是在三角形中了,只要这个点D和三角形的三个点A、B、C组合的三角形a、b、c的面积之和等于这个三角形的面积,就说明这个点在三角形中,如图。

Android如何判断一个点在不在多边形区域内

代码如下:


public boolean isInTriangle(Point A, Point B, Point C, Point P) {
double ABC = triAngleArea(A, B, C);
double ABp = triAngleArea(A, B, P);
double ACp = triAngleArea(A, C, P);
double BCp = triAngleArea(B, C, P);
if ((int) ABC == (int) (ABp + ACp + BCp)) {// 若面积之和等于原三角形面积,证明点在三角形内,这里做了一个约等于小数点之后没有算(25714.25390625、25714.255859375)
 return true;
} else {
 return false;
}
}

private double triAngleArea(Point A, Point B, Point C) {// 由三个点计算这三个点组成三角形面积
double result = Math.abs((A.getX() * B.getY() + B.getX() * C.getY()
  + C.getX() * A.getY() - B.getX() * A.getY() - C.getX()
  * B.getY() - A.getX() * C.getY()) / 2.0D);
return result;
}

一切看起来那么合情合理,代码写完了,也测试了都没有问题啦!但是最后我发现忽略了一个问题,还有一种多边形的情况没有考虑到,那就是香蕉形的多边形,如图:

Android如何判断一个点在不在多边形区域内

这个问题一出来,我立刻蒙圈啦,这个应该怎么做,最后在网上找到了解决办法,那就是沿着这个点做平行线,如果这个点单侧和多边形相交的点为奇数,就说明这个点在这个多边形中,如图:

Android如何判断一个点在不在多边形区域内

代码如下:


/**
* 功能:判断点是否在多边形内 方法:求解通过该点的水平线与多边形各边的交点 结论:单边交点为奇数,成立!
*
* @param point
*   指定的某个点
* @param APoints
*   多边形的各个顶点坐标(首末点可以不一致)
* @return
*/
public boolean PtInPolygon(Point point, List<Point> APoints) {
int nCross = 0;
for (int i = 0; i < APoints.size(); i++) {
 Point p1 = APoints.get(i);
 Point p2 = APoints.get((i + 1) % APoints.size());
 // 求解 y=p.y 与 p1p2 的交点
 if (p1.getY() == p2.getY()) // p1p2 与 y=p0.y平行
  continue;
 if (point.getY() < Math.min(p1.getY(), p2.getY())) // 交点在p1p2延长线上
  continue;
 if (point.getY() >= Math.max(p1.getY(), p2.getY())) // 交点在p1p2延长线上
  continue;
 // 求交点的 X 坐标
 // --------------------------------------------------------------
 double x = (double) (point.getY() - p1.getY())
   * (double) (p2.getX() - p1.getX())
   / (double) (p2.getY() - p1.getY()) + p1.getX();
 if (x > point.getX())
  nCross++; // 只统计单边交点
}
// 单边交点为偶数,点在多边形之外 ---
return (nCross % 2 == 1);
}

项目下载:一个点是否在多边形中

来源:https://blog.csdn.net/u014544193/article/details/50698015

0
投稿

猜你喜欢

  • 本文实例为大家分享了OpenCV实现人脸识别程序的具体代码,供大家参考,具体内容如下//Haar特征检测,人脸识别算法,是用xml作为训练后
  • springboot项目启动慢的问题排查springboot项目,随着时间的推移,启动耗时逐步增加,从几分钟慢慢的达到30多分钟,有点恐怖!
  • 最近在看《.NET游戏编程入门经典 C#篇》 第一章介绍了如何制作俄罗斯方块,自己试了试按照书上的步骤,可算是完成了。于是写下这篇文章留作纪
  • 本文实例为大家分享了C# GDI+实现时钟表盘的具体代码,供大家参考,具体内容如下一、设计如下图界面按键&ldquo;打开时钟&am
  • 这篇文章主要介绍了spring boot如何实现切割分片上传,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
  • 本篇给大家详细讲解了MTKAndroid平台开发流程,大致分为44个步骤,我们把每个步骤的命令详细讲解了下,一起来学习下。1.拷贝代码仓库从
  • 今天讲解一下Fragment的控制,主要是切换View和页面替换等操作。还有就是如何获取Fragment的管理对象,以及与Activity的
  • 本文实例讲述了C#创建临时文件的方法。分享给大家供大家参考。具体分析如下:C#可以通过Path.GetTempFileName获得一个临时文
  • Navigator 的 push 和 pop方法Navigator 导航器的 push 和 pop 方法可以携带参数在页面间传递,其他变形的
  • 1.ArrayList 是基数组结构的,需要连续的内存空间从构造函数可以看出,ArrayList内部用一个Object数组来保存数据。对于无
  • 前言最近在工作中需要编译android下的动态库,本以为是一件简单的事,没想到因为工具,以及google本身被墙的原因,折腾了好久。在win
  • 在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较
  • 本文实例讲述了C#获取网页源代码的方法。分享给大家供大家参考。具体如下:public string GetPageHTML(string u
  • 前言为什么用动静态库我们在实际开发中,经常要使用别人已经实现好的功能,这是为了开发效率和鲁棒性(健壮性);因为那些功能都是顶尖的工程师已经写
  • 目录Android 集成Flutter1, Hello Flutter2, 引入 Flutter 模块3,使用Flutter3.1 添加依赖
  • 在谈 JVM 内存区域划分之前,我们先来看一下 Java 程序的具体执行过程,我画了一幅图。Java 源代码文件经过编译器编译后生成字节码文
  • PS:本文包含了大部分strings函数的说明,并附带举例说明。本来想自己整理一下的,发现已经有前辈整理过了,就转了过来。修改了原文一些源码
  • 背景实际开发中,常常需要将比较复杂的 JSON 字符串转换为对应的 Java 对象。这里记录下解决方案。如下所示,是入侵事件检测得到的 JS
  • 一、Monkey 是什么?Monkey 就是SDK中附带的一个工具。二、Monkey 测试的目的?:该工具用于进行压力测试。 然后开发人员结
  •  IOS与网页JS交互随着移动APP的快速迭代开发趋势,越来越多的APP中嵌入了html网页,但在一些大中型APP中,尤其是电商类
手机版 软件编程 asp之家 www.aspxhome.com