Android如何判斷一個點在不在多邊形區(qū)域內(nèi)
有人問我,怎么判斷一個點是不是在多邊形內(nèi),本來想著把這個多邊形分成一個又一個三角形,如圖,

然后判斷這個點是不是在某個三角形中,如果在,那就肯定在這個多邊形中,那問題接下來就轉(zhuǎn)化成判斷這個點是不是在三角形中了,只要這個點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)) {// 若面積之和等于原三角形面積,證明點在三角形內(nèi),這里做了一個約等于小數(shù)點之后沒有算(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;
}
一切看起來那么合情合理,代碼寫完了,也測試了都沒有問題啦!但是最后我發(fā)現(xiàn)忽略了一個問題,還有一種多邊形的情況沒有考慮到,那就是香蕉形的多邊形,如圖:

這個問題一出來,我立刻蒙圈啦,這個應(yīng)該怎么做,最后在網(wǎng)上找到了解決辦法,那就是沿著這個點做平行線,如果這個點單側(cè)和多邊形相交的點為奇數(shù),就說明這個點在這個多邊形中,如圖:

代碼如下:
/**
* 功能:判斷點是否在多邊形內(nèi) 方法:求解通過該點的水平線與多邊形各邊的交點 結(jié)論:單邊交點為奇數(shù),成立!
*
* @param point
* 指定的某個點
* @param APoints
* 多邊形的各個頂點坐標(biāo)(首末點可以不一致)
* @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 坐標(biāo)
// --------------------------------------------------------------
double x = (double) (point.getY() - p1.getY())
* (double) (p2.getX() - p1.getX())
/ (double) (p2.getY() - p1.getY()) + p1.getX();
if (x > point.getX())
nCross++; // 只統(tǒng)計單邊交點
}
// 單邊交點為偶數(shù),點在多邊形之外 ---
return (nCross % 2 == 1);
}
項目下載:一個點是否在多邊形中
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ImageView的屬性android:scaleType的作用分析
本篇文章是對ImageView的屬性android:scaleType的作用進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Flutter自定義下拉刷新時的loading樣式的方法詳解
Flutter中的下拉刷新,我們通常RefreshIndicator,可以通過color或strokeWidth設(shè)置下拉刷新的顏色粗細等樣式,但如果要自定義自己的widget,RefreshIndicator并沒有暴露出對應(yīng)的屬性,那如何修改呢,文中給大家介紹的非常詳細,需要的朋友可以參考下2024-01-01
Android實現(xiàn)中國象棋游戲(局域網(wǎng)版)
這篇文章主要為大家詳細介紹了Android實現(xiàn)局域網(wǎng)版的中國象棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
Android自定義ViewGroup實現(xiàn)標(biāo)簽流容器FlowLayout
這篇文章主要介紹了Android自定義ViewGroup實現(xiàn)FlowLayout標(biāo)簽流容器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
AndroidStudio 設(shè)置格式化斷行寬度教程
這篇文章主要介紹了AndroidStudio 設(shè)置格式化斷行寬度教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android?webView加載數(shù)據(jù)時內(nèi)存溢出問題及解決
這篇文章主要介紹了Android?webView加載數(shù)據(jù)時內(nèi)存溢出問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12

