using UnityEngine;
using System.Collections.Generic;

public class JudgePoint : MonoBehaviour
{

//多边形A 所有顶点
private float[,] dingdian = new float[4, 3] { { 6, 4, 0 }, { 3, 1, 0 }, { 2, 2, 0 }, { 3, 5, 0 } };
//P点 不确定是否在多边形内
private float[,] P = new float[1, 3] { { 3, 2, 0 } };
//O点 目标点
private float[,] O = new float[1, 3] { { 7, 10, 0 } };
//测试 不规则四边形 第一象限
private float[,] bianbian = new float[4, 3] { { 8, 0, 8 }, { 2, 2, 0 }, { 0, 5, 0 }, { 4, 8, 0 } };
private float[,] dian1 = new float[1, 3] { { 5, 8, 0 } };//坐标系中不在多边形内 unity测试 不在多边形内
private float[,] dian2 = new float[1, 3] { { 5, 2, 0 } };//坐标系中 在多边形内 unity测试 在多边形内
//测试 不规则五边形 410 260 480 770 830 第一象限
private float[,] bianFive = new float[5, 3] { { 4, 1, 0 }, { 2, 6, 0 }, { 4, 8, 0 }, { 7, 7, 0 }, { 8, 3, 0 } };
private float[,] dian3 = new float[1, 3] { { 2, 3, 0 } };//坐标系中 不在 unity测试 不在
private float[,] dian4 = new float[1, 3] { { 6, 3, 0 } };//坐标系中 在 unity测试 在
//7,8 不在 4,7在
//测试 多边形 不在第一象限内 180 650 520 -1-10 -820 -460
private float[,] bianSix = new float[6, 3] { { 1, 8, 0 }, { 6, 5, 0 }, { 5, 2, 0 }, { -1, -1, 0 }, { -8, 2, 0 }, { -4, 6, 0 } };
private float[,] dian7 = new float[1, 3] { { 5, 1, 0 } }; //坐标系 不在 unity不在
private float[,] dian8 = new float[1, 3] { { -4, -2, 0 } };//坐标系 不在 unity不在
private float[,] dian9 = new float[1, 3] { { 4, 5, 0 } }; //坐标系 在 unity在
//10000次 测试 不规则六边形 31毫秒
//10000次 测试 不规则四边形 15-16毫秒

//算法一:凹多边形测试 500 070 440 880 算法一 无法计算 凹多边形
private float[,] bianAo = new float[4, 3] { { 5, 0, 0 }, { 0, 7, 0 }, { 4, 4, 0 }, { 8, 8, 8 } };
private float[,] dian10 = new float[1, 3] { { 4, 5, 0 } }; //坐标系 不在 unity 不在
private float[,] dian11 = new float[1, 3] { { 5, 4, 0 } };//坐标系 在 unity 不在
//算法二:凹多边形测试 成功 10000次 凹四边形 15-16毫秒
//算法二测试:凹六边形 380 450 870 700 220 060 +判断点是否在边上
private float[,] bianAoSix = new float[6, 3] { { 3, 8, 0 }, { 4, 5, 0 }, { 8, 7, 0 }, { 6, 2, 0 }, { 2, 2, 0 }, { 0, 6, 0 } };
private float[,] dian12 = new float[1, 3] { { 8, 1, 0 } }; // 坐标系 不在 2 :0
private float[,] dian13 = new float[1, 3] { { 5, 6, 0 } };//坐标系 不在 3:2
private float[,] dian14 = new float[1, 3] { { 6, 1, 0 } };//坐标系 在 1 : 1
private float[,] dian15 = new float[1, 3] { { 3, 6, 0 } };//坐标系 在 2:3
//继续测试
private float[,] dian16 = new float[1, 3] { { 1, 2, 0 } };//坐标系 不在 0: 3
private float[,] dian17 = new float[1, 3] { { 3, 1, 0 } };//坐标系 不在 0: 2
private float[,] dian18 = new float[1, 3] { { 4, 8, 0 } };//不在 2: 0
private float[,] dian19 = new float[1, 3] { { 4, 7, 0 } };//不在 2: 2

//总结 算法一:适合任何凸多边形 任何象限 10000次 四边形 15-16毫秒
// 算法二:适合任何凹多边形 任何象限 10000次 四边形 0-15-16毫秒
// 算法二:加上判断点是否在边上 任何象限 10000次 六边形 15-16毫秒

private float[,] dian20 = new float[1, 3] { { 4, 4, 0 } };

void Start()
{
//ForJudgePoint(dingdian, P);
//ForJudgePoint(bianbian, dian);
//ForJudgePoint(bianFive, dian3);
//ForJudgePoint(bianFive, dian4);
//ForJudgePoint(bianSix, dian7);
//ForJudgePoint(bianSix, dian8);
//ForJudgePoint(bianSix, dian9);
float time = System.Environment.TickCount; //计时器
//for (int i = 0; i < 10000; i++)
//{
// ForJudgePoint(bianbian, dian2);
//}

// Debug.Log(Vector3.Angle(v1, v2));
//ForJudgePoint(bianAo, dian10);
//ForJudgePoint(bianAo, dian11);
//SecondJudge(bianAo, dian11);
for (int i = 0; i < 10000; i++)
{
SecondJudge(bianAo, dian10);
}
Debug.Log("times:" + (System.Environment.TickCount - time)); //计时器
//ForJudgePoint(bianSix, dian7);
//SecondJudge(bianSix, dian7);
//ForJudgePoint(bianSix, dian9);
//SecondJudge(bianSix, dian9);
//SecondJudge(bianAoSix, dian12);
//SecondJudge(bianAoSix, dian13);
//SecondJudge(bianAoSix, dian14);
//SecondJudge(bianAoSix, dian15);
//SecondJudge(bianAoSix, dian16);
//SecondJudge(bianAoSix, dian17);
//SecondJudge(bianAoSix, dian18);
//SecondJudge(bianAoSix, dian19);
//SecondJudge(bianAoSix, dian20);

}
//算法二 凹多边形
public void SecondJudge(float[,] dingdian, float[,] point)
{
int bianShu = dingdian.Length / 3;
//bool isOnLine = JudPointOnLine(dingdian, point, bianShu);
//if (isOnLine == true) { Debug.Log("该点在多边形边上"); return; }
List<int> listLeft = new List<int>();
List<int> listRight = new List<int>();
float y = point[0, 1];
float x = point[0, 0];
bool isEqu = false;
float bianX = 0;
for (int i = 0; i < bianShu; i++)
{
if (dingdian[i, 1] == y)
{
isEqu = true;
bianX = dingdian[i, 0];
if (dingdian[i, 0] > x)
{
listRight.Add(i);
listRight.Add(i);
}
else
{
listLeft.Add(i);
listLeft.Add(i);
}
}
}
for (int i = 0; i < bianShu; i++)
{
if (i < bianShu - 1)
{
if (dingdian[i, 1] < y && y < dingdian[i + 1, 1])
{
if (dingdian[i, 0] <= x && dingdian[i + 1, 0] <= x)
{
listLeft.Add(i);
}
else if (dingdian[i, 0] >= x && dingdian[i + 1, 0] >= x)
{
listRight.Add(i);
}
else
{
float midX = (dingdian[i, 0] + dingdian[i + 1, 0]) / 2;
if (x > midX)
{
listLeft.Add(i);
}
else
{
listRight.Add(i);
}
}
}
}
else
{
if (dingdian[i, 1] < y && y < dingdian[0, 1])
{
if (dingdian[i, 0] <= x && dingdian[0, 0] <= x)
{
listLeft.Add(i);
}
else if (dingdian[i, 0] >= x && dingdian[0, 0] >= x)
{
listRight.Add(i);
}
else
{
float midX = (dingdian[i, 0] + dingdian[0, 0]) / 2;
if (midX < x)
{
listLeft.Add(i);
}
else
{
listRight.Add(i);
}
}
}
}
}
for (int i = 0; i < bianShu; i++)
{
if (i < bianShu - 1)
{
if (dingdian[i, 1] > y && y > dingdian[i + 1, 1])
{
if (dingdian[i, 0] <= x && dingdian[i + 1, 0] <= x)
{
listLeft.Add(i);
}
else if (dingdian[i, 0] >= x && dingdian[i + 1, 0] >= x)
{
listRight.Add(i);
}
else
{
float midX = (dingdian[i, 0] + dingdian[i + 1, 0]) / 2;
if (midX < x)
{
listLeft.Add(i);
}
else
{
listRight.Add(i);
}
}
}
}
else
{
if (dingdian[i, 1] > y && y > dingdian[0, 1])
{
if (dingdian[i, 0] <= x && dingdian[0, 0] <= x)
{
listLeft.Add(i);
}
else if (dingdian[i, 0] >= x && dingdian[0, 0] >= x)
{
listRight.Add(i);
}
else
{
float midX = (dingdian[i, 0] + dingdian[0, 0]) / 2;
if (midX < x)
{
listLeft.Add(i);
}
else
{
listRight.Add(i);
}
}
}
}
}
//Debug.Log(listLeft.Count + " " + listRight.Count);
if (isEqu == false)
{
if (listLeft.Count % 2 == 0 || listRight.Count % 2 == 0)
{
//Debug.Log("==不在== 多边形内");
}
else
{
//Debug.Log("==在== 多边形内");
}
}
else
{
if ((bianX > x && listLeft.Count % 2 == 0) || (bianX < x && listRight.Count % 2 == 0))
{
//Debug.Log("=不在= 多边形内");
}
else
{
//Debug.Log("=在= 多边形内");
}
}

}

//判断点是否在多边形边上
public bool JudPointOnLine(float[,] dingdian, float[,] point, int bianshu)
{

for (int i = 0; i < bianshu - 1; i++)
{
//先判断是否在 边所在的直线上
if ((dingdian[i, 0] - point[0, 0]) * (dingdian[i + 1, 1] - point[0, 1]) - (dingdian[i + 1, 0] - point[0, 0]) * (dingdian[i, 1] - point[0, 1]) == 0)
{
//判断X值 与2个点X的值
if ((point[0, 0] > dingdian[i, 0] && point[0, 0] > dingdian[i + 1, 0]) || (point[0, 0] < dingdian[i, 0] && point[0, 0] < dingdian[i + 1, 0]))
{
return false;
}
else
{
return true;
}
}
}
//最后一边
if ((dingdian[bianshu - 1, 0] - point[0, 0]) * (dingdian[0, 1] - point[0, 1]) - (dingdian[0, 0] - point[0, 0]) * (dingdian[bianshu - 1, 1] - point[0, 1]) == 0)
{
//判断X值 与2个点X的值
if ((point[0, 0] > dingdian[bianshu - 1, 0] && point[0, 0] > dingdian[0, 0]) || (point[0, 0] < dingdian[bianshu - 1, 0] && point[0, 0] < dingdian[0, 0]))
{
return false;
}
else
{
return true;
}
}

return false;

}

//算法一
public void ForJudgePoint(float[,] dingdian, float[,] point)
{
int bianShu = dingdian.Length / 3;//三维向量 除以3 = 多边形边数
float[] results = new float[bianShu];
for (int i = 0; i < dingdian.Length / 3 - 1; i++)
{
//判断 多边形 第一个顶点到最后一个顶点 一共边数-1 条边(还剩最后顶点 到 第一个顶点 这条边)
//多边形 第一条边 的向量
float[,] polygonSide = { { dingdian[i, 0] - dingdian[i + 1, 0], dingdian[i, 1] - dingdian[i + 1, 1], dingdian[i, 2] - dingdian[i + 1, 2] } };
//多边形 第一条边向量的起始点 到 点point 的向量
float[,] pointToSide = { { dingdian[i, 0] - point[0, 0], dingdian[i, 1] - point[0, 1], dingdian[i, 2] - point[0, 2] } };
//二维向量叉乘 Z分量 = x1*y2-x2*y1
float res = polygonSide[0, 0] * pointToSide[0, 1] - pointToSide[0, 0] * polygonSide[0, 1];
res = res > 0 ? res = 1 : res = -1;
results[i] = res;
if (i >= 1)
{
if (results[i] != results[i - 1])
{
Debug.Log("点P ==不在== 多边形中!!!");
return;
}
}
}
//最后一条边
float[,] polygonLastSide = { { dingdian[bianShu - 1, 0] - dingdian[0, 0], dingdian[bianShu - 1, 1] - dingdian[0, 1], dingdian[bianShu - 1, 2] - dingdian[0, 2] } };
float[,] pointToLastSide = { { dingdian[bianShu - 1, 0] - point[0, 0], dingdian[bianShu - 1, 1] - point[0, 1], dingdian[bianShu - 1, 2] - point[0, 2] } };
float resLast = polygonLastSide[0, 0] * pointToLastSide[0, 1] - pointToLastSide[0, 0] * polygonLastSide[0, 1];
resLast = resLast > 0 ? resLast = 1 : resLast = -1;
if (resLast != results[0])
{
Debug.Log("点P ==不在== 多边形中!!!");
}
else
{
Debug.Log("点P ==在== 多边形中!!!");
}
}
}

转载于:https://www.cnblogs.com/cocotang/p/5809493.html

判断点是否在一个任意多边形中相关推荐

  1. mysql 查询多边形_mysql中判断一个点是否在多边形中

    1.创建表 CREATE TABLE `c_zone` ( `id` int(11) NOT NULL auto_increment, `name` varchar(100) NOT NULL, `p ...

  2. 一种求任意多边形内部水平方向似最大矩形的算法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在前一篇中,我们探讨了如何求凸多边形中的似最大圆,但是针对实际 ...

  3. java判断线与矩形相交_判断任意多边形与矩形的相交(线段与矩形相交或线段与线段相交)...

    任意多边形与矩形的相交,其实就是判断多条线段是否与这个矩形相交,再简单点就是判断线段是否与矩形的每一条边相交了.那现在,我们先来看看判断一条线段与矩形的其中一条线段的相交的情况(上方水平线): (图形 ...

  4. 点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部

    点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部: function isInPolygon(checkPoint, polygonPoints) {var counter = 0;var ...

  5. 任意多边形费马点点群中位中心求解

    点群中位中心求解 1问题讨论 从上两式不难看出,空间点(x0,y0)可以取空间中任意一点有无穷种可能,因此难以求得精确.只能使用迭代的方式来求无限逼近的解,当然求用一些奇特的方法求近似解也是可以的. ...

  6. Android判断一个点在不在多边形中

    有人问我,怎么判断一个点是不是在多边形内,本来想着把这个多边形分成一个又一个三角形,如图, 然后判断这个点是不是在某个三角形中,如果在,那就肯定在这个多边形中,那问题接下来就转化成判断这个点是不是在三 ...

  7. 已知三个点坐标求 三角形面积 || 求任意多边形面积公式||判断点在直线的左侧还是右侧

    已知三个点坐标求 三角形面积 由A-->B-->C-->A 按逆时针方向转.(行列式书写要求) 设三角形的面积为S 则S=(1/2)*(下面行列式) |x1 y1 1| |x2 y2 ...

  8. [math]判断一个点是否在多边形内的方法

    文章目录 向量叉乘判别法 面积和判别法 夹角和判别法 引射线法 PNPoly算法 多边形的内角是由两条相邻边形成边界之内的角:如果一个多边形的所有内角均小于180°,则该多边形为凸(convex)多边 ...

  9. 求任意多边形内部水平方向似最大矩形算法实现

    背景说明 前段时间有个求点是否在多边形内部的需求,折腾了不少时间,现截取其中的的重点部分--求任意多边形内部水平方向似最大矩形--来搞篇博客. 求点是否在多边形内部这个算法很容易搞,一搜一大把,但数据 ...

最新文章

  1. TI PDK3.0 qt 交叉编译环境设置
  2. rocketMq指定broker ip地址,适合解决云主机部署问题
  3. 3,maven使用入门
  4. Java Web开发入门 - 第5章 Git
  5. 修改linux的最大文件句柄数限制
  6. 百度腾讯中兴华为全部入局Linux Foundation深度学习基金会
  7. 使用HttpClient连接池进行https单双向验证
  8. 出现net.sf.json.JSONException: There is a cycle in the hierarchy异常的解决办法
  9. Android Realm(数据库)
  10. 【图像分割】基于matalb GUI遗传神经网络图像分割【含Matlab源码 659期】
  11. uniapp与微信小程序常用api
  12. Pycharm下了汉化包之后切换回英文界面
  13. 第八章:加载Maya2011模型
  14. 玻璃盖板丝印质量及尺寸在线检测方案
  15. 路由器的两个端口接在同一个交换机上_什么是路由器交换机?路由器交换机介绍!...
  16. 《用图表说话》读后感
  17. PhpSpreadsheet读取单元格内容的坑
  18. JAVA服务器端发送邮件问题:Could not connect to SMTP host: smtp.qq.com, port: 465
  19. python如何微信公众号刷票_问卷星刷票
  20. 柯基数据:先进的知识图谱技术,构建行业知识图谱,助企业打通内部信息孤岛,链接海量数据 |百万人学AI评选

热门文章

  1. Master PDF Editor中文版
  2. 洛谷——P3807 【模板】卢卡斯定理
  3. javascript中的this
  4. Servlet(3):Cookie
  5. Go - interface
  6. Ubuntu 16.04 LTS今日发布
  7. [Google Android] Creating Your Own Spelling Checker Service
  8. DELAY INIT 延迟初始化
  9. 汇编中的数组分配和指针
  10. Java9新特性系列(模块化系统: Jigsaw-Modularity)