博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2D空间中求一点是否在多边形内
阅读量:5925 次
发布时间:2019-06-19

本文共 2183 字,大约阅读时间需要 7 分钟。

参考自这篇博文:

 

一开始没仔细看做法,浪费了不少时间。下面是最终实现的效果:

 

大致流程:

1.随便选取多边形上任意一条边,以比较点和边的中心点做一条射线(这里用的伪射线)。

2.用这条射线与其他所有边判断是否相交。

3.将所有与线段相交的数量相加,如果是奇数就在多边形内。

 

特殊情况:

1.刚好在点上或者在线上。实际运用时会有点误差,但不影响。

2.必须是闭合线段,且不能存在包含的情况。但如果是一个数组生成的线段,不会有这种情况

 

代码(Unity3D):

using UnityEngine;using System.Collections;public class Test1 : MonoBehaviour{    const float RAYCAST_LEN = 100000f;    public Transform[] points;    public Transform compare;    bool IsContract(Transform compare)    {        var comparePoint = (points[1].position + points[0].position) * 0.5f;        var originPoint = compare.transform.position;        comparePoint += (comparePoint - originPoint).normalized * RAYCAST_LEN;        Debug.DrawLine(originPoint, comparePoint);        int count = 0;        for (int i = 0; i < points.Length; i++)        {            var a = points[i % points.Length];            var b = points[(i + 1) % points.Length];            var r = IsIntersection(a.position, b.position, originPoint, comparePoint);            if (r) count++;        }        return count % 2 == 1;    }    void OnDrawGizmos()    {        if (compare == null) return;        var oldColor = Gizmos.color;        if (IsContract(compare))            Gizmos.color = Color.red;        for (int i = 0; i < points.Length; i++)        {            var a = points[i % points.Length];            var b = points[(i + 1) % points.Length];            Gizmos.DrawLine(a.position, b.position);        }        Gizmos.color = oldColor;    }    bool IsIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d)    {        var crossA = Mathf.Sign(Vector3.Cross(d - c, a - c).y);        var crossB = Mathf.Sign(Vector3.Cross(d - c, b - c).y);        if (Mathf.Approximately(crossA, crossB)) return false;        var crossC = Mathf.Sign(Vector3.Cross(b - a, c - a).y);        var crossD = Mathf.Sign(Vector3.Cross(b - a, d - a).y);        if (Mathf.Approximately(crossC, crossD)) return false;        return true;    }}

 

 

另外参考的文章中没有说差乘判断两个线段是否相交的具体做法,这里说明一下

 

大致流程:

现在有线段AB和线段CB

用线段AB的方向和C,D两点分别做差乘比较。如果C,D在同侧则return跳出

用线段CD的方向和A,B两点分别做差乘比较。如果A,B在同侧则return跳出

最终返回相交

 

脚本就是上面的IsIntersection函数,最终实现效果(只适用于2D空间,如果是XY轴向要取差乘的z分量做比较):

转载于:https://www.cnblogs.com/hont/p/6105997.html

你可能感兴趣的文章
maven pom聚合与继承
查看>>
排它锁 共享锁的区别
查看>>
三层嵌套oracle数据库记录分页sql语句
查看>>
JAVA图形界面(GUI)之表格
查看>>
Apache Storm 官方文档 —— 基础概念
查看>>
A - Farey Sequence——(筛法求欧拉函数)
查看>>
Compare Keys and multi Hash Stored in Redis
查看>>
(六十九)复合语句
查看>>
Picasso源码阅读笔记四
查看>>
mpvue学习笔记-之微信小程序数据请求的封装
查看>>
Java8之Stream-Stream原理
查看>>
问题总结
查看>>
python错误调试
查看>>
难追难回味
查看>>
如何构建Vue大型应用
查看>>
Leetcode 498:对角线遍历Diagonal Traverse(python3、java)
查看>>
学习jQuery-----(1)
查看>>
RQPro 公募 FOF 策略实例 2——基金投资风格箱、业绩趋势和反转策略、及风险最小化资产配置...
查看>>
解决因为机器性能问题导致docker-compose运行容器超时的问题
查看>>
Java 注解完全解析
查看>>