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

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

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

代码如下:

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;
}

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

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

代码如下:

/**
 * 功能:判断点是否在多边形内 方法:求解通过该点的水平线与多边形各边的交点 结论:单边交点为奇数,成立!
 *
 * @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);
} 

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android使用Path绘制出多边形

    在讲使用path绘制多边形时,讲下Canvas的translate(),rotate()方法的使用,本博客中会使用这方面的知识,先单独讲下,搞懂了这个,下面讲path绘制多边形就简单的多,我们知道每次我们使用canvas.draw...()绘制什么图形的时候,都是创建了一个新的图层,如果不知道图层是啥意思,就去看下我之前写的关于canvas基础,有讲这方面的,其实你可以理解成每次新创建了一个activity,然后把这个activity压入栈中,translate()是画布平移,其实每次画布还是同

  • Android自定义View实现多边形统计图示例代码

    前言   最近利用空闲时间学习了自定义View的一些知识,为了巩固,写了一个小东西,顺便分享出来,下面话不多说了,来一起看看详细的介绍吧. 简介   一个多边形统计图.边数,每个方向的值,每个点的文字等等都是可以设置的. 下面就来分析一下这个自定义View 这个view由以下几个部分组成 M层N边形 中心到各顶点的连线 填充区域 文字 @Override protected void onDraw(Canvas canvas) { if (!canDraw()) { return; } canv

  • Android编程之canvas绘制各种图形(点,直线,弧,圆,椭圆,文字,矩形,多边形,曲线,圆角矩形)

    本文实例讲述了Android编程之canvas绘制各种图形的方法.分享给大家供大家参考,具体如下: 1.首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into

  • Android多边形区域扫描线种子填充算法的示例

    1.3扫描线种子填充算法 1.1和1.2节介绍的两种种子填充算法的优点是非常简单,缺点是使用了递归算法,这不但需要大量栈空间来存储相邻的点,而且效率不高.为了减少算法中的递归调用,节省栈空间的使用,人们提出了很多改进算法,其中一种就是扫描线种子填充算法.扫描线种子填充算法不再采用递归的方式处理"4-联通"和"8-联通"的相邻点,而是通过沿水平扫描线填充像素段,一段一段地来处理"4-联通"和"8-联通"的相邻点.这样算法处理过程

  • Android多边形区域递归种子填充算法的示例代码

    平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充).区域填充中最常用的是多边形填色,本文中我们就讨论几种多边形区域填充算法. 一.种子填充算法(Seed Filling) 如果要填充的区域是以图像元数据方式给出的,通常使用种子填充算法(Seed Filling)进行区域填充.种子填充算法需要给出图像数据的区域,以及区域内的一个点,这种算法比较适合人机交互方式

  • Android开发之绘制平面上的多边形功能分析

    本文实例讲述了Android开发之绘制平面上的多边形功能.分享给大家供大家参考,具体如下: 计算机里的3D图形其实是由很多个平面组合而成的.所谓"绘制3D"图形,其实是通过多个平面图形形成的.调用GL10图形绘制2D图形的步骤如下: i. 调用GL10的glEnableClientState(GL10.GL_VERTEX_ARRAY);方法启用顶点坐标数组. ii. 调用GL10的glEnableClientState(GL10.GL_COLOR_ARRAY);方法启用顶点颜色数组.

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

    有人问我,怎么判断一个点是不是在多边形内,本来想着把这个多边形分成一个又一个三角形,如图, 然后判断这个点是不是在某个三角形中,如果在,那就肯定在这个多边形中,那问题接下来就转化成判断这个点是不是在三角形中了,只要这个点D和三角形的三个点A.B.C组合的三角形a.b.c的面积之和等于这个三角形的面积,就说明这个点在三角形中,如图. 代码如下: public boolean isInTriangle(Point A, Point B, Point C, Point P) { double ABC

  • Android开发判断一个app应用是否在运行的方法详解

    本文实例讲述了Android开发判断一个app应用是否在运行的方法.分享给大家供大家参考,具体如下: 在一个应用中,或一个Service .Receiver中有时候需要判断一个应用是否正在运行,以便进行一些相关的处理,这个时候我们需要得到一个ActivityManager,这个Manager顾名思意就是管理Activity的,它有一个方法叫getRunningTasks,可以得到当前系统正在运行的Task的列表,代码如下: ActivityManager am = (ActivityManage

  • 用vbs判断一个日期是否在指定的时段内

    问: 您好,脚本专家! 如何判断一个日期是否在指定的时段内? -- JW 答: 您好,JW. 真是巧啊,今天早上在上班的路上,我们听到有两个不同公司的不同的广告,他们都用"七月中的圣诞节"招揽顾客. 这促使着我们一到办公室就立即回答您的问题. 毕竟,如果这些公司都有一份您正在寻找的脚本,他们可能就会知道七月没有圣诞节. 注意: 当然,我们也可能记错了圣诞节的时间,所以也许您应该给所有的脚本专家送一份礼物,以防万一. 那么我们如何才能知晓圣诞节不在七月呢? 只需运行以下脚本即可: 复制代

  • php+mongodb判断坐标是否在指定多边形区域内的实例

    MongoDB是一个基于分布式文件存储的数据库,并提供创建基于地理空间的索引的能力,本文将提供使用PHP连接mongodb,判断坐标是否在指定多边形区域内的实例. 1.定义多边形区域 多边形的坐标点如下: 113.314882,23.163055 113.355845,23.167042 113.370289,23.149564 113.356779,23.129758 113.338238,23.13913 113.330979,23.124706 113.313588,23.140858 1

  • Android编程判断当前应用是否在后台运行的方法示例

    本文实例讲述了Android编程判断当前应用是否在后台运行的方法.分享给大家供大家参考,具体如下: /** 判断程序是否在后台运行 */ public static boolean isRunBackground(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProc

  • C#实现判断一个时间点是否位于给定时间区间的方法

    本文实例讲述了C#实现判断一个时间点是否位于给定时间区间的方法.分享给大家供大家参考.具体如下: 本文中实现了函数 复制代码 代码如下: static bool isLegalTime(DateTime dt, string time_intervals); 给定一个字符串表示的时间区间time_intervals: 1)每个时间点用六位数字表示:如12点34分56秒为123456 2)每两个时间点构成一个时间区间,中间用字符'-'连接 3)可以有多个时间区间,不同时间区间间用字符';'隔开 例

  • android判断一个Activity是否处于栈顶的实例

    实际开发中我们需要很多情况需要判断某个activity是否位于栈顶,也许会给新的小伙伴带来困扰,那么直接上代码吧,也没几行 /** * * 判断某activity是否处于栈顶 * @return true在栈顶 false不在栈顶 */ private boolean isActivityTop(Class cls,Context context){ ActivityManager manager = (ActivityManager) context.getSystemService(Cont

  • Android编程判断应用程序是否已安装的方法

    本文实例讲述了Android编程判断应用程序是否已安装的方法.分享给大家供大家参考,具体如下: 这里以twitter程序为例,假设twitter程序包名为"com.twitter.android".这时候可用以下代码来判断是否被安装. PackageInfo packageInfo; try { packageInfo = this.getPackageManager().getPackageInfo( "com.twitter.android", 0); } ca

  • Android Service判断设备联网状态详解

    首先,要想获得当前android设备是否处于联网状态,那么android本身给我们提供了一个服务. private ConnectivityManager connectivityManager;//用于判断是否有网络 connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);//获取当前网络的连接服务 NetworkInfo info = co

  • Android camera2 判断相机功能是否可控的实例

    Android Camera2 可调功能适配 首先获取到设备等级: Float hardwareLevel = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); LEGACY < LIMITED < FULL < LEVEL_3. 越靠右边权限越大 •INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2 •INFO_SUPPORTED_HARDWAR

随机推荐