Android如何判断一个点在不在多边形区域内
作者:呆呆的小木头 发布时间:2023-07-06 14:06:13
标签: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);
}
项目下载:一个点是否在多边形中
来源:https://blog.csdn.net/u014544193/article/details/50698015


猜你喜欢
- 前言空间分配要点有:一是空间分配的连续性;二是动态内存申请;三是防止程序执行中出现异常错误。提示:开始讲解了嗷~后续会根据精力持续更新嗷!!
- 当只需要两个图像合并的时候,可以简单的使用gdi+,把两个图像画到一个画布上面实现合并bitmap.当需要将许多bitmap合并时,由于bi
- 在一些场合,我们往往需要使用印章来给每页文档加盖一个印章,以表示该文档经过某个部门的认证的,常规的做法就是打印文档后盖章,如果需要电子档再行
- 我们使用Spring整合Quartz开发,本实例采用数据库模式的demo。xml文件配置如下:<?xml version="
- 进行数据源或者 FTP 服务器等资源配置时,我们可以将这些配置信息放到一个独立的外部属性文件中,并在 Spring 配置文件中通过形如 ${
- Android系统对所有的危险权限进行了分组,称为 权限组 。属于同一组的危险权限将自动合并授予,用户授予应用某个权限组的权限,则应用将获得
- 我们在打包的过程中,需要对代码进行混淆处理,可项目中需要混淆的地方很多,特别是添加依赖的,如果要我们一个一个添加,无疑这大大的添加了我们的工
- OAuth 简介OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordo
- 说明本项目采用 maven 结构,主要演示了 spring mvc + mybatis,controller 获取数据后以json 格式返回
- 前言在讲这两种方式之前,我们先来说明一下什么是java中的jar文件jar (Java Archive File),翻译过来就是java的档
- Java中四种访问权限总结一、Java中有四种访问权限, 其中三种有访问权限修饰符,分别为private、public、prot
- 现在很多电脑提供了蓝牙支持,很多笔记本网卡也集成了蓝牙功能,也可以采用USB蓝牙方便的连接手机等蓝牙设备进行通信。操作蓝牙要使用类库InTh
- 本实例主要实现下面三个基本功能1、C#开发windows服务2、禁止QQ等程序运行3、为windows服务创建自动安装程序下面针对这三个基本
- 重载1.构造器的重载因为构造器的名字必须与类名相同,所以同一个类的所有构造器名肯定相同,构成重载;为了让系统能区分不同的构造器,多个构造器的
- 废话就不多说了,直接上效果图和代码fry.Activity01package fry;import java.util.ArrayList;
- 1、pom.xml文件添加distributionManagement节点。模块项目中如果存在父子项目,且父子项目的jar包都需要上传到 *
- 修改整理的一个通用类,用来操作oracle数据库 十分的方便,支持直接操作sql语句和Hash表操作.现在修补MIS我都用这个类,节约了大
- 本文实例为大家分享了Android实现简单banner轮播图的具体代码,供大家参考,具体内容如下说明:想玩一个简单的轮播图效果
- 1)new 运算符:用于创建对象和调用构造函数。这种大家都比较熟悉,没什么好说的了。2)new 修饰符:在用作修饰符时,new 关键字可以显
- C#支持的位逻辑运算符如表2.9所示。运算符号意义运算对象类型运算结果类型对象数实例~位逻辑非运算整型,字符型整型1~a&位逻辑与运