javascript 判断一个点是否在多边形内(向量的使用)
2015-09-12 16:32
537 查看
为什么要检测一个点是否在多边形内,恩,主要是想用在canvas里来模拟底层的点击事件.
要知道,canvas实际上是一个非常简单简洁的api,只提供了几个绘图api,非常底层,要利用这些简单的特性制造复杂的应用,需要一个框架,作为一个动画框架,最重要的除了时间线和精灵的概念,莫属于它的事件机制了.
当我们把一个canvas封装成一个框架的时候,canvas里的东西都会被我们当成一个一个的对象,然后为了操作这些对象,我们需要知道我们的鼠标是否点在了这些对象上,是在拖动对象,还是点击了对象,还是离开了对象,我们需要把这些事件封装出来作为借口提供给框架使用者.
然而,canvas没有给你提供任何事件,从底层来说,canvas内所有的事件都只是一个在canvas上触发的事件,例如canvas被点击了,被拖动了.对于在canvas里你点到了什么,点到了哪里,浏览器并没有提供原生的事件api.于是,我们需要自己来封装.
canvas内的对象千奇百怪,但是从二维角度来说,其实任何对象都是又多边形组成的或者就是一个多边形,这个多边形,我们在程序中用它的顶点作为标记来存储.
先看一个demo吧:
点击打开链接
判断一个点是否在多边形内的算法:
有这样一个算法,假设现在有一个点和一个多边形,这个多边形可以是凸多边形也可以是凹多边形.找到这个点,然后从这个点水平往左画一条射线,方向指向左边,然后你找一下这条射线和多边形的各条边是否相交,统计一下相交的次数,如果相交偶数次,说明点在多边形外面,如果相交奇数次,说明点在多边形内.具体可以多画画试试.
下面的程序中,点标识成对象{x:*,y:*},而多边形则表示成点的数组,可以有任意个点组成.
要知道,canvas实际上是一个非常简单简洁的api,只提供了几个绘图api,非常底层,要利用这些简单的特性制造复杂的应用,需要一个框架,作为一个动画框架,最重要的除了时间线和精灵的概念,莫属于它的事件机制了.
当我们把一个canvas封装成一个框架的时候,canvas里的东西都会被我们当成一个一个的对象,然后为了操作这些对象,我们需要知道我们的鼠标是否点在了这些对象上,是在拖动对象,还是点击了对象,还是离开了对象,我们需要把这些事件封装出来作为借口提供给框架使用者.
然而,canvas没有给你提供任何事件,从底层来说,canvas内所有的事件都只是一个在canvas上触发的事件,例如canvas被点击了,被拖动了.对于在canvas里你点到了什么,点到了哪里,浏览器并没有提供原生的事件api.于是,我们需要自己来封装.
canvas内的对象千奇百怪,但是从二维角度来说,其实任何对象都是又多边形组成的或者就是一个多边形,这个多边形,我们在程序中用它的顶点作为标记来存储.
先看一个demo吧:
点击打开链接
判断一个点是否在多边形内的算法:
有这样一个算法,假设现在有一个点和一个多边形,这个多边形可以是凸多边形也可以是凹多边形.找到这个点,然后从这个点水平往左画一条射线,方向指向左边,然后你找一下这条射线和多边形的各条边是否相交,统计一下相交的次数,如果相交偶数次,说明点在多边形外面,如果相交奇数次,说明点在多边形内.具体可以多画画试试.
下面的程序中,点标识成对象{x:*,y:*},而多边形则表示成点的数组,可以有任意个点组成.
//计算向量叉乘 var crossMul=function(v1,v2){ return v1.x*v2.y-v1.y*v2.x; } //javascript判断两条线段是否相交 var checkCross=function(p1,p2,p3,p4){ var v1={x:p1.x-p3.x,y:p1.y-p3.y}; v2={x:p2.x-p3.x,y:p2.y-p3.y}; v3={x:p4.x-p3.x,y:p4.y-p3.y}; v=crossMul(v1,v3)*crossMul(v2,v3); v1={x:p3.x-p1.x,y:p3.y-p1.y}; v2={x:p4.x-p1.x,y:p4.y-p1.y}; v3={x:p2.x-p1.x,y:p2.y-p1.y}; return (v<=0&&crossMul(v1,v3)*crossMul(v2,v3)<=0)?true:false; } //判断点是否在多边形内 var checkPP=function(point,polygon){ var p1,p2,p3,p4; p1=point; p2={x:-100,y:point.y}; var count=0; //对每条边都和射线作对比 for(var i=0;i<polygon.length-1;i++){ p3=polygon[i]; p4=polygon[i+1]; if(checkCross(p1,p2,p3,p4)==true){ count++; } } p3=polygon[polygon.length-1]; p4=polygon[0]; if(checkCross(p1,p2,p3,p4)==true){ count++; } // console.log(count) return (count%2==0)?false:true; }
相关文章推荐
- 【转】获取/设置IFRAME内对象元素的几种JS方法
- javascript高级程序设计---document节点
- javaScript学习(一)
- jsp 行动标签
- JS数据类型之Function类型
- 详解JS的getByclass方法
- Json的知识点全解析,解析json数据的好工具大全
- jsp页面是放在webroot目录下和web-inf下优缺点
- JS实现超精简响应鼠标显示二级菜单代码
- JS对象之间的关系
- js学习笔记(三)数据类型转换
- javascript面向对象开发(一)
- phantomjs rendering
- JS-prototype的掌握
- JSP学习笔记
- JS-return的使用
- 基于Arcgis for javascript实现百度地图ABCD marker的效果
- 分分钟搞懂JS-闭包函数
- ExtJs jsonStore加载的监听
- JS-面向对象-封装