threejs路径

路径

引用百度百科的解释:

路径通常指存在于多种计算机图形设计软件中的以贝塞尔曲线为理论基础的区域绘制方式。

路径在Canvas、SVG上都有相关定义,一般用来创建形状。在threejs中,也可以用来创建形状,除此之外,还可以用作物体运动的轨迹。下面就说说这两种用法。

在threejs中,Path类代表路径,Path继承自CurvePath(曲线路径),CurvePath继承自Curve(曲线)。CurvePath和Curve都是抽象类,在threejs文档中指出,CurvePath用来连接多条曲线(也就是Curve),其实质上就是一个Curve数组。其实,直接用Path类就可以了,对于CurvePath和Curve,无需关心。

另外还有一个ShapePath类,这个类可以将形状转成一系列路径来表示,比如将svg绘制的图形转成threejs的路径。

使用路径创建形状

关于使用路径创建形状,可以参考【创建平面几何形状一文】,其中的Shape类,就是Path类的子类,这里不多说。

使用路径作为物体运动轨迹

如果我们想要物体沿着某一条曲线运动,有两种办法:
1、算出曲线的公式,动态的计算出物体当前时刻的位置
2、创建一条代表该曲线的路径,然后动态的在该曲线上取点,将其位置赋给物体
一般,路径类会提供多种创建路径的方法,所以,第2种方式通常比较好用。

下面就使用threejs提供的Path类创建一条移动轨迹,然后把相机在这条轨迹上移动。开始的开始,先创建一条路径,如下:

       path = new THREE.Path();path.bezierCurveTo(10,100,20,-30,30,19);path.bezierCurveTo(40,-5,50,150,60,-39);path.closePath();

接着在render循环中动态的从路径中取点,设置成相机的位置:

var progress = 0;
function render(){requestAnimationFrame(render);progress += 0.003;let point = path.getPointAt(progress);if(point){camera.position.set(point.x,point.y,300);}else{progress = 0;}renderer.render(scene,camera);
}

上面的progress是比例,范围从0~1.完整示例请看【完整示例】

将svg形状转成路径

svg是一种矢量图形格式,同时,javascript也有创建和修改这种图形格式的接口。各种表示矢量图形的技术,如Canvas、SVG,本质上是相同或相通的,只不过是实现和接口不一样,所以,是有转化的可能的。

在svg中,下面的代码创建了一条从(0,0)到(100,100)的直线路径:

<path d="M0 0 L 100 100"/>

而在threejs中,使用ShapePath创建一条直线路径使用:

let path = new ShapePath();
path.moveTo(0,0);
path.lineTo(100,100);

可见,两者的形式是相近的,从形式上来看,简单的转换难度也不会很大。下面是一个转换的例子:

function createShapes(){let dataString = getSvgData();  //获取svg数据let shape = transformToShapePath(dataString); //转换成ShapePath表示let geometry = new THREE.ShapeGeometry(shape);let material = new THREE.LineBasicMaterial({color:0xff0000});let mesh = new THREE.Line(geometry,material);scene.add(mesh);camera.lookAt(mesh.position);
}//获取svg数据,数据来自w3cschool
function getSvgData(){let svgData = "M153 334 C153 334 151 334 151 334 C151 339 153 344 156 344 C164 344 171 339 171 334 C171 322 164 314 156 314 C142 314 131 322 131 334 C131 350 142 364 156 364 C175 364 191 350 191 334 C191 311 175 294 156 294 C131 294 111 311 111 334 C111 361 131 384 156 384 C186 384 211 361 211 334 C211 300 186 274 156 274";return svgData;
}//转换成ShapePath表示
function transformToShapePath(dataString){let path = new THREE.ShapePath();let dataArr = dataString.split(" ");var currIndex = 0;while(currIndex<dataArr.length){let command = dataArr[currIndex][0];switch(command){case 'M' : {let inc = moveParse(currIndex,dataArr,path);currIndex += inc;break;}case 'C' : {let inc = curveParse(currIndex,dataArr,path);currIndex += inc;break;}default:{//出错处理currIndex++;}}}return path.toShapes()[0];
}/**************下面是各种命令的转换器****************///moveTo命令转换器function moveParse(currIndex,dataArr,path){let paramsLength = 2; //需要的参数个数let data = [dataArr[currIndex].substring(1),dataArr[currIndex+1]];toThreejsCoor(data);path.moveTo(data[0],data[1]);return paramsLength;}//Curve命令转换器function curveParse(currIndex,dataArr,path){let paramsLength = 6; //需要的参数个数let data = [ dataArr[currIndex].substring(1),dataArr[currIndex+1],dataArr[currIndex+2],dataArr[currIndex+3],dataArr[currIndex+4],dataArr[currIndex+5]];toThreejsCoor(data);path.bezierCurveTo(data[0],data[1],data[2],data[3],data[4],data[5]);return paramsLength;}//屏幕坐标转threejs坐标function toThreejsCoor(data){for(let i = 0 ; i < data.length; i += 2){data[i] = data[i] - window.innerWidth/2;data[i+1] = window.innerHeight/2 - data[i+1];}}

上面的代码做了下面这几件事:

  • 从svg中提取图形的定义数据,比如<path>标签的d属性
  • 将所提取数据中的坐标转换成threejs坐标
  • 分析所提取的数据里的操作,用ShapePath执行这些操作
  • 调用ShapePath类的toShapes()方法,获得一个Path对象数组
  • 用这个Path数组中的对象,创建threejs图形。

这也是将svg转成Path的几个基本步奏。经过转换之后,屏幕上会显示出如下图形:

完整效果,请戳【完整示例】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429923.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL ES 纹理设置

纹理过滤纹理采样最近点采样线性纹理采样MIPMAP纹理纹理过滤 纹理拉伸&#xff1a;重复拉伸和截取拉伸 用于指定纹理坐标超过(00.0,1.0)范围时所发生的行为&#xff0c;使用glTexParameterf函数指定&#xff0c;GL_TEXTURE_WRAP_S 定义 s 坐标超出范围[0.0, 1.0]的情况&#xf…

安装kubernetes dashboard时开发环境,运行gulp local-up-cluster任务一直显示wating for a heapster

问题 按照官方教程搭建dashboard的开发环境&#xff0c;运行“gulp local-up-cluster”任务&#xff0c;一直不断显示“waiting for a heapster…”&#xff0c;日志如下&#xff1a; ... [16:37:22] Finished spawn-cluster after 670 ms ... [16:37:22] Finished wait-for-…

react做h5 例子_使用React写一个网站的心得体会

网站是毕业设计的作品&#xff0c;开发这个网站的目的主要用于记录一些笔记&#xff0c;以及聚合一些资讯信息&#xff0c;也算自己在网络世界中的一块静地吧&#xff0c;可以在这里一些技术上想法的实践。网站最初前端使用vue开发&#xff0c;在前段时间由于项目的开发进度已经…

linux命令小常识

作为一个tester我们必须要会linux,也许你会说不用也可以。那么我想问,你部署测试环境在哪里&#xff0c;你下载war包并部署war包呢&#xff0c;你看日志在哪里&#xff1f; 基于测试需要用到liunx&#xff0c;我这里只针对需要用到的&#xff0c;工作就是不断在探索中学习&…

ubuntu联网不稳定,时断时连问题的解决办法

概览 ubuntu联网不稳定&#xff0c;时断时连问题的解决办法现象网络一会儿连上&#xff0c;过一会又自动断开&#xff0c;再等一会儿又断了。问题原因可能是受ipv6的影响解决办法关闭掉ipv6 详细步骤 1、编辑连接&#xff0c;打开“ipv6 settings”&#xff0c;将method设置…

如何根据原理图画封装_常用原理图封装

原理图常用库文件&#xff1a;Miscellaneous Devices.ddbDallas Microprocessor.ddbIntel Databooks.ddbProtel DOS Schematic Libraries.ddbPCB元件常用库&#xff1a;Advpcb.ddbGeneral IC.ddbMiscellaneous.ddb分立元件库部分 分立元件库元件名称及中英对照AND 与门ANTENNA …

搭建GitLab+Jenkins持续集成环境图文教程

GitLab是一个代码仓库&#xff0c;用来管理代码。Jenkins是一个自动化服务器&#xff0c;可以运行各种自动化构建、测试或部署任务。所以这两者结合起来&#xff0c;就可以实现开发者提交代码到GitLab&#xff0c;Jenkins以一定频率自动运行测试、构建和部署的任务&#xff0c;…

随笔-1031

随笔1030 学习第四天 样式表的样式 一、大小宽度width高度height 二、背景1.background-color 背景色2.background-image 背景图片3.background-repeat&#xff1a;no-repeat 背景图的平铺方式4.background-position 背景图的位置 center等5.background-attachment 背景图是否滚…

exception日志 php_PHP 错误与异常的日志记录

提到 Nginx PHP 服务的错误日志&#xff0c;我们通常能想到的有 Nginx 的 access 日志、error 日志以及 PHP 的 error 日志。虽然看起来是个很简单的问题&#xff0c;但里面其实又牵扯到应用配置以及日志记录位置的问题&#xff0c;如果是在 ubuntu 等系统下使用 apt-get 的方…

threejs-经纬度转换成xyz坐标的方法

用threejs做3D应用时&#xff0c;很经常会接触到球状物体&#xff0c;比如说地球&#xff0c;要定义球上的一点&#xff0c;用经纬度是常用的办法。现在&#xff0c;我们要在北京这个地方标一个点&#xff0c;北京的坐标为——北纬39.9”&#xff0c;东经116. 3”&#xff0c;该…

两个tplink路由器有线桥接_TP-Link路由器如何设置有线方式桥接(两个或多个路由器串联上网)图文教程...

第一页&#xff1a;TP-Link路由器有线方式桥接设置图文教程第二页&#xff1a;TP-Link路由器有线方式桥接设置图文教程本文介绍了TP-Link路由器有线桥接的设置方法&#xff0c;路由器有线桥接其实严格上应该叫做&#xff1a;两个(多个)路由器串联上网。主要适用于这样的网络环境…

双内核问题

<meta http-equiv"Content-Type" content"text/html; charsetutf-8"><!--优先使用 IE 最新版本和 Chrome--><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"><!--360浏览器QQ,搜狗等双内核浏览器&am…

dashboard windows 前端开发环境搭建

dashboard是kubernetes的云管平台UI界面&#xff0c;正常情况下&#xff0c;其是在linux下开发的&#xff0c;但是&#xff0c;有些特殊情况下&#xff0c;我们也可能希望在windows上搭建起dashboard的开发环境 这里我们将搭建的开发环境的结构如下&#xff1a; windows上只运…

a pycharm 标记多个_每周分享五个 PyCharm 使用技巧(二)

这是 「PyCharm 技巧分享」系列的第二篇分享。由于上一篇文章得到了大家的一些赞同&#xff0c;所以今天又来给大家推荐一些我平时自己有用的小技巧&#xff0c;大家择需所取即可。先声明下&#xff0c;并不保证对所有的人都是有帮助的&#xff0c;所以请大神嘴下留情&#xff…

Visual Studio2012打开时弹出“遇到异常:这可能是由某个扩展导致的”错误的解决办法...

Visual Studio2012打开时弹出“遇到异常&#xff1a;这可能是由某个扩展导致的”错误的解决办法&#xff1a; 具体问题如下&#xff1a; 分析原因&#xff1a;网上搜集了以下&#xff0c;出现异常的原因是安装了第三方控件&#xff0c;然后删除是没有删除干净&#xff0c;导致日…

python url拼接_详解Python urlencode编码和url拼接方法

urlencode 调用方法urlencode的参数必须是Dictionaryimport urllibd {name1:www.pythontab.com,name2:bbs.pythontab.com}print urllib.urlencode(d)输出&#xff1a;name2bbs.pythontab.com&name1www.pythontab.com相当于拼接两个url参数&#xff0c;这个用法类似于PHP中…

跨域问题及CORS机制

跨域 跨域是指一个资源请求与其不在同一个域&#xff08;源&#xff09;的资源&#xff0c;不在同一个域&#xff08;源&#xff09;是指两个域的协议、域名或端口不同。 同源策略 出于安全考虑&#xff0c;浏览器制定了同源策略&#xff0c; 限制了某些跨域请求。同源策略是…

【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】...

模拟题&#xff0c;可以用树链剖分线段树维护。 但是学了一个厉害的。。树状数组的区间修改与区间查询。。 分割线里面的是转载的&#xff1a; -------------------------------------------------------------------------------- [ 3 ] 上面都不是重点……重点是树状数组的区…

oracle .dbf文件过大_学习这篇Oracle数据库文件坏块损坏的恢复方法,拓展你的知识面...

一、Oracle数据库系统简介&#xff1a;ORACLE数据库系统是美国ORACLE公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一。比如SilverStream就是基于数据库的一种中间…

threejs- z-fighting 问题

Z-Buffer 在threejs中&#xff0c;使用深度缓冲&#xff08;Z-Buffer&#xff09;来完成场景可见性计算&#xff0c;即确定场景哪部分可见&#xff0c;哪部分不可见。深度缓冲&#xff08;Z-Buffer&#xff09;是一个二维数组&#xff0c;其中的每一个元素对应屏幕上的一个像素…