webgl圈中物体

这篇的标题非常不符合我的气质!

但是 如果带上那种 “不可能 姐姐 妹妹 君 套套 不要”等关键字标题的话 其他小伙伴就很难通过搜索引擎到这个地方来了!

所以还是使用这种简短大众的标题得了。。

注意标题中有个“圏” 字 我们讨论的并不是“选”

下面的圈中物体解决方案 其实已经把如何选中一个物体的问题一并搞定了

圈中物体 首先要有一条封闭曲线吧 那条曲线是由n个线段拼接起来的 我们要找到相交的那两条线段和那两条线段之间的所有线段 如图

相交的线段就是这两了 封闭曲线的起始和结束线段就是它们 不过还得截取它们的头或尾 绿色线段起始坐标替换为交点坐标  蓝色线段结束坐标替换为交点坐标

那么如何解决线段相交呢?

有好几种解决方案 我这里提供一种是利用直线参数式来解的 如下

p01=p0+v0*t

p11=p1+v1*s

p0x+v0x*t=p1x+v1x*s

p0y+v0y*t=p1y+v1y*s

可以使用消元法来解 s 和 t 也可以使用 canvas曲线面片1 那种矩阵方法来解

如果 s和t同时大于0并且小于1  说明相交了 把s和t带进去可以计算出交点了

相交代码

Miku.lineCross = function(l1,l2){
      var t1,t2;
      var [v1,v2] = [
        new Miku.Vec(l1.x2-l1.x1 , l1.y2-l1.y1)
        ,new Miku.Vec(l2.x2-l2.x1 , l2.y2-l2.y1)
      ]
      const ar = [
        [v1.x,-v2.x]
        ,[v1.y,-v2.y]
      ];
      const res = Miku.Det2( ar , [l2.x1-l1.x1 , l2.y1-l1.y1]  );

      if(!res) return {cross:0};

      t1 = res[0],t2 = res[1];
      const o = {cross:t1>0&&t1<1&&t2>0&&t2<1,pos:0};
      if(o.cross){
        return o.pos = {
          x : l1.x1 + v1.x*t1
          ,y:l1.y1 + v1.y*t1
          ,xx:l2.x1 + v2.x*t2
          ,yy:l2.y1 + v2.y*t2
        }
        ,o;
      }
      return o;
    }

接下来要解决物体是不是被圈了

物体就是个任意多边形 所以你可以想到与多边形的边来做相交处理是吧。。然而并不能满足所有情况

因为 如果曲线包含了整个物体 但是它没有与任何边相交也算被圈中 又或者曲线全包含在物体内呢?

所以要换种方法了 我这里提供一种叫环绕数的解决方案 如下

想象在上图那个封闭曲线内有一点P Pn是线段的端点 P的环绕数就可通过这个式子给出 如果结果是+=1  那就在内部

其实还可以用点乘给出结果 不过据我观察仅适用于凸边形。。

还有一种情况就是曲线全部在物体内部 那么Pn就是物体的顶点 反过来处理一边。。

环绕数代码(具体的可看后面给的源码)

for(let i = 0,dot;dot = ar[i++];){
  let n = 0;
  for(let j =0,l;l = this.cross_ar[j++];){
    let v1 = (new Miku.Vec(l.x1-dot.x , l.y1-dot.y)).normal();
    let v2 = (new Miku.Vec(l.x2-dot.x , l.y2-dot.y)).normal();
    n += asin(v1.cross(v2))*v;
  }
if(f(abs(n))) return 1;
}

这两关键问题就解决了

不过还要注意 这里用的是webgl接口 所以鼠标坐标还要规范下 代码

Miku(c).on(‘touchmove‘,e=>{
    var [x,y] = [(e.mouse_x-c.cx)/c.cx , -(e.mouse_y-c.cy)/c.cy];
    Xline.setRoute({x,y});
  });

cx cy是中心位置  xy值-1到1

给个 demo

其实 我们可以用上面的方法选中三维物体的

不过 如果要选中它们 首先要对鼠标坐标做投影矩阵的逆变换 把鼠标坐标投到三维上

然后给三维的物体来个包围圆或者是矩形 之后就可以用上面的方法来处理选中了 。。当然了 这不精确 不过也满足很多情况了

还有些其他方法 比如有基于像素的选中  以后相关demo会用上的  以后再说~

时间: 2024-10-12 18:56:30

webgl圈中物体的相关文章

在WebGL场景中使用2DA*寻路

  这篇文章将讨论如何在一个自定义的地面网格上进行简单的2D寻路,以及确定路径后如何使用基于物理引擎的运动方式使物体沿路径到达目标地点.读者需要预先对WebGL和Babylonjs知识有一些了解,可以参考我录制的WebGL入门视频教程和翻译的官方入门文档,当然也可以用自己喜欢的其他方式来学习. 文章主要分成如下几部分: 1.自定义地面网格与寻路矩阵 2.生成Babylon格式3D模型 3.使用pathfinding库进行2D寻路 4.基于cannon.js物理引擎使物体沿路径移动 场景可以通过h

如何让你的网页链接潇洒地在微信好友和朋友圈中传播

嗨,大家好,我是大花猫! 想必大家都在自己的微信朋友圈看到过别人分享的一些网页链接消息,但是你注意了吗?有些链接的图标是用的微信一张蓝色的默认图片,但是有些链接的图标却有着各自专门的图标(注:公众号的图文消息不在本文讨论行列中.),而且标题也和链接里面网站的标题不一样!(想想前段时间那个风靡朋友圈的贱贱的神经猫吧!)好啦!今天要跟大家分享的就是如何让自己的网页在微信分享朋友圈中拥有一个自己个性的图标以及自定义分享中的描述文字.(开始想着加这个功能是在学习了慕课网的<2048私人定制>以后做了第

ScreenToViewportPoint,WorldToViewportPoint,ViewportToWorldPoint的运用,实现一个简单的对三维中物体的拖拽移动效果

众所周知,我们手机或者手机屏幕上的坐标是一个二维平面的的坐标值,而且这个坐标是一像素为单位的,也就是说这个是会根据你用的设备的不同,你手机或者电脑上的坐标的长宽最大值也就不同. 之前不太了解标题上三个方法的用法,走了不少弯路,然后下来仔细研究了一下,感觉还是挺有收获的. 简单说一下,我们在Unity中屏幕坐标是以坐下为原点,向两边延伸,右上为终点,假定现在我们的分辨率是1920x1080的话,那么简单,四个角对应的值大家可能都能猜到,(假定为横屏)坐下(0,0),右下(1920,0),左上(10

一群人围成一圈从123报数,如果报到3就退出该圈中,直到最后一个人留下来!

package com.pb.demo1; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 一群人围成一圈从123报数,如果报到3就退出该圈中,直到最后一个人留下来! * 约瑟夫的游戏 */ public class Demo1 { public sta

怎么样在【微信会员】朋友圈中获得更多的赞?

微信已经是我们生活中必不可少的生活.交流平台.微信会员在朋友圈中的分享.倾诉更是我们心灵平台,在微信朋友圈中被点赞多的洋洋得意,获赞少的难免失意.怎么样才可以让自己在朋友圈中获得更多的关注和点赞?朋友圈吸赞方式一:自拍如果你是男神或女神,如果你360度自拍无死角,那么发自拍照就足以获得一片“赞”声.那些明恋或暗恋的粉丝就可以顺理成章地用点赞来求关注了.也许点赞还不够,再加一句评论“美爆了”.“帅哭了”来表达激动的心情.请注意,矮矬穷.颜值负分者,请自觉跳过这一招式.朋友圈吸赞方式二:炫富对于一般

谈谈微信针对朋友圈中投放广告的营销方案

鉴于朋友圈的巨大流量和高频的访问,微信终于忍不住要开始朋友圈掘金了,几天前微信已经在朋友圈中插入了广告声明,昨天微信已经正式开始投放广告了. 广告是以类似facebook,微博的信息流的形式展示的,首批广告主分别是宝马.vivo手机和可口可乐.在投放广告之后几个小时之内,朋友圈就宣起了对广告内容和目标群体的广泛讨论.话说是微信是这么搞的:微信后台广告系统通过用户之前的访问日志,访问内容,朋友圈交互频度.自己发布的信息内容.以及地域.性别 甚至 手机客户端类型做了大数据分析,将人分为了三六九等,然

IT公司100题-18-圆圈中最后剩下的数字

问题描述: n个数字(下标为0, 1, …, n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(当前数字从1开始计数).当一个数字被删除后,从被删除数字的下一个数字开始计数,继续删除第m个数字.求这个圆圈中剩下的最后一个数字. 分析: 这是有名的约瑟夫环问题. 最直接的方法: 使用链表来模拟整个删除过程.因为需要n个链表节点,所以空间复杂度为O(n).每删除一个节点,都需要m次运算,所以时间复杂度为O(mn). 实现代码如下所示: 1 // 18_1.cc 2 #include

分割RGB中物体并计算数目

I=imread(im_path); axes(handles.axes1); imshow(I), % title('原始图像'); %计算每个像素点的真实长度 [x,y]=ginput(2); length=str2double(get(handles.edit5,'string')); length_pp=length/(sqrt(((x(1)-x(2))^2+(y(1)-y(2))^2))); %图像变换 [row,col]=size(I); I2=rgb2gray(I); clear

three.js中物体旋转实践之房门的打开与关闭

看这篇博客,默认你已经知道了3D模型实现三维空间内旋转的实现方式(矩阵.欧拉角.四元数). ok,下面正式切入主题,房门的打开和关闭,先上图: 正如你所看到的那样,这个“房门”已经被打开了. 一.three.js中物体的旋转 object.rotation.set(angleX,angleY,angleZ); 这是three.js为object3D类(基本上所有的物体都是继承自这个类的)提供的自旋转API: 为什么叫自旋转呢,就像地球自转和公转一样,自旋转表示绕物体自身中心点(局部坐标系)旋转: