参考自这篇博文:http://www.cnblogs.com/dabiaoge/p/4491540.html

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

大致流程:

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[].position + points[].position) * 0.5f;
var originPoint = compare.transform.position;
comparePoint += (comparePoint - originPoint).normalized * RAYCAST_LEN; Debug.DrawLine(originPoint, comparePoint); int count = ;
for (int i = ; i < points.Length; i++)
{
var a = points[i % points.Length];
var b = points[(i + ) % points.Length]; var r = IsIntersection(a.position, b.position, originPoint, comparePoint); if (r) count++;
} return count % == ;
} void OnDrawGizmos()
{
if (compare == null) return; var oldColor = Gizmos.color; if (IsContract(compare))
Gizmos.color = Color.red; for (int i = ; i < points.Length; i++)
{
var a = points[i % points.Length];
var b = points[(i + ) % 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分量做比较):

2D空间中求一点是否在多边形内的更多相关文章

  1. 2D空间中判断一点是否在三角形内

    要注意如果是XY坐标轴的2D空间,要取差乘分量z而不是y. 实现原理是,将三角形ABC三个边(AB,BC,CA)分别与比较点判断差乘,如果这3个差乘结果表示的方向一致,说明就在三角形内. 效果: 代码 ...

  2. 2D空间中求两圆的交点

    出处:https://stackoverflow.com/questions/19916880/sphere-sphere-intersection-c-3d-coordinates-of-colli ...

  3. 2D空间中求线段与圆的交点

    出处: https://answers.unity.com/questions/366802/get-intersection-of-a-line-and-a-circle.html 测试脚本(返回值 ...

  4. [译]2D空间中使用四叉树Quadtree进行碰撞检测优化

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity2017.2.0f3 原文出处 : Quick Tip: Use Quadtrees to Detect Lik ...

  5. 2d游戏中求出一个向量的两个垂直向量

    function cc.exports.VerticalVector(vec)--求出两个垂直向量 local result = {} result[1] = cc.p(vec.y/vec.x,-1) ...

  6. 2D和3D空间中计算两点之间的距离

    自己在做游戏的忘记了Unity帮我们提供计算两点之间的距离,在百度搜索了下. 原来有一个公式自己就写了一个方法O(∩_∩)O~,到僵尸到达某一个点之后就向另一个奔跑过去 /// <summary ...

  7. Computer Science Theory for the Information Age-2: 高维空间中的正方体和Chernoff Bounds

    高维空间中的正方体和Chernoff Bounds 本文将介绍高维空间中正方体的一些性质,以及一个非常常见也是非常有用的概率不等式——Chernoff Bounds. 考虑$d$维单位正方体$C=\{ ...

  8. Computer Science Theory for the Information Age-1: 高维空间中的球体

    高维空间中的球体 注:此系列随笔是我在阅读图灵奖获得者John Hopcroft的最新书籍<Computer Science Theory for the Information Age> ...

  9. 为什么很多人坚信“富贵险中求”?

    之家哥 2017-11-15 09:12:31 微信QQ微博 下载APP 摘要 网贷之家小编根据舆情频道的相关数据,精心整理的关于<为什么很多人坚信"富贵险中求"?>的 ...

随机推荐

  1. SQL Server 数据库新建用户

    1.在[安全性]中的[登录名]右键创建登陆用户 2. 输入相关信息 3. 然后去相应的数据库下[安全性]中右键添加用户 4.选择刚刚创建的用户名 5. 选择[默认架构]为 owner 6. 对[拥有的 ...

  2. win10我能ping通他人,但他人ping不同我

    这是防火墙的原因,关闭防火墙即可

  3. 关于oracle的笔记

    1.查看一个表暂用的表空间大小: SELECT bytes/1024/1024||'MB',a.*FROM user_segments a WHERE a.segment_name ='TL_SP_N ...

  4. PowerDesigner 15.2入门学习 二

    PowerDesigner中如何生成主键和自增列 1.SQL Server版本: 第一步,首先要建立与数据库的连接,方法较多,这里举个例子: http://www.cnblogs.com/netsql ...

  5. python的内存管理机制

    先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计数 (3)内存池机制 一.垃圾回收: python不像C++,Java等语言一样,他们可以不用事先声明变量 ...

  6. Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读. 拟牛顿法 数学原理 代码实现 L-BFGS算法中使 ...

  7. innodb_buffer_pool_size 大小建议

    innodb_buffer_pool_size参数大小建议: 查看Innodb_buffer_pool_pages_data大小,即已使用页面 MySQL> SHOW GLOBAL STATUS ...

  8. Java 内存区域划分

            JVM的内存区域划分 学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆.栈以及静态数据区.那么在Java语言当中,内存又是如何划分的 ...

  9. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  10. HTML中div以及span等元素获取焦点

    在js操作html的时候如果想让某个元素获取焦点,一般去掉用其.focus()方法. 但如果为非表单元素的div span等,必须要添加属性tabIndex=1这个属性后调用.focus()方法即可! ...