HTML5 + WebGL 实现的垃圾分类系统

前言

垃圾分类,一般是指按一定规定或标准将垃圾分类储存、分类投放和分类搬运,从而转变成公共资源的一系列活动的总称。分类的目的是提高垃圾的资源价值和经济价值,力争物尽其用。垃圾在分类储存阶段属于公众的私有品,垃圾经公众分类投放后成为公众所在小区或社区的区域性准公共资源,垃圾分类搬运到垃圾集中点或转运站后成为没有排除性的公共资源。从国内外各城市对生活垃圾分类的方法来看,大致都是根据垃圾的成分、产生量,结合本地垃圾的资源利用和处理方式来进行分类的。到2019年6月25日,生活垃圾分类制度将入法。一套应用于工业物联网的智能一体化的垃圾分类机械臂将随之而来,由此,我应用 HT for Web  的图型化编辑工具打造了一款形象生动的例子:Garbage classification,也借此机会与大家一起分享和学习。

代码实现

(注:gif 的上传大小有限,实际效果与还请参考 demo 链接)

首先,我应用已经精心布置好的 3D 场景,为了有更好的操作体验感,我们要从它的基本设置开始:

gv.setMovableFunc(() => { return false }) // 禁止拖动
gv.getWireframe = (d) => { d.s(‘wf.visible‘, false) }  // 隐藏选中边框
gv.setEye([583, -212, -789]) // 设置眼睛
gv.setCenter([-76, -654, -133]) // 设置中心点
gv.setFar(100000) // 设置远端位置
gv.setNear(10) // 设置近端位置
gv.setInteractors([ new ht.graph3d.MapInteractor(gv) ]) // 设置交互限制
gv.setSkyBox(dm.getDataByTag(‘skyBox‘)) // 设置天空球
window.document.oncontextmenu = () => { return false } // 全局设置右键菜单禁用
gv.scene = { // 复制初始位置
    eye: ht.Default.clone(gv.getEye()),
    center: ht.Default.clone(gv.getCenter()),
    far: ht.Default.clone(gv.getFar()),
    near: ht.Default.clone(gv.getNear()),
}

我复制了一下整个场景的初始视角情况方便我做稍后的处理,我监听了部分鼠标事件来形成自己的操作风格(比如双击背景还原视角以及双击模型拉近视角):

gv.mi(e => {
    let data = e.data
    let kind = e.kind
    if (kind === ‘doubleClickBackground‘) { // 双击背景
        gv.moveCamera(this.gv.scene.eye, this.gv.scene.center, {duration : 1000}) // 恢复视角
    }
    else if (kind === ‘doubleClickData‘) { // 双击模型
        gv.flyTo(data, {animation : {duration : 500}, distance : 800}) // 拉近视角
    }
})

好了,准备工作做好了,下面来实现动画部分,除了了解 垃圾分类 的方式外我还参考了网上很多机械臂的视频,学习它的运动模式和动作细节,对每个结构和部位的动画进行步骤的排序和构思。这里我挑选几处动画的实现方式来展示:

function mechanicalArmAnim1() {
  ht.Default.startAnim({
    duration: 1000,
    easing: (t) => { return t },
    action: (v, t) => {
      postbrachium.r3(degrees(0) + (degrees(20) - degrees(0)) * v, postbrachium.r3()[1], postbrachium.r3()[2]) // 后臂向下移
    },
    finishFunc: () => {
      setTimeout(() => {
        mechanicalArmAnim2()
      }, 300)
    }
  })
}
function mechanicalArmAnim2() {
  ht.Default.startAnim({
    duration: 1000,
    easing: (t) => { return t },
    action: (v, t) => {
      postbrachium.p3(-208 + (-184 + 208) * v, postbrachium.p3()[1], postbrachium.p3()[2]) // 后臂前伸
      hydraulicRod1.r3(degrees(0) + (degrees(8) - degrees(0)) * v, hydraulicRod1.r3()[1], hydraulicRod1.r3()[2]) // 液压杆1倾斜
      extensionRod1.r3(degrees(0) + (degrees(8) - degrees(0)) * v, extensionRod1.r3()[1], extensionRod1.r3()[2]) // 伸长杆1倾斜
      extensionRod1.p3(-169 + (-185 + 169) * v, -516 + (-511 + 516) * v, extensionRod1.p3()[2]) // 伸长杆1伸长
      hydraulicRod2.r3(degrees(0) + (degrees(-8) - degrees(0)) * v, hydraulicRod2.r3()[1], hydraulicRod2.r3()[2]) // 液压杆2倾斜
      extensionRod2.r3(degrees(0) + (degrees(-8) - degrees(0)) * v, extensionRod2.r3()[1], extensionRod2.r3()[2]) // 伸长杆2倾斜
      extensionRod2.p3(-169 + (-185 + 169) * v, -516 + (-511 + 516) * v, extensionRod2.p3()[2]) // 伸长杆2伸长
    },
    finishFunc: () => {
      setTimeout(() => {
        mechanicalArmAnim3()
      }, 300)
    }
  })
}
function mechanicalArmAnim3() {
  let oldValue = antebrachium.r3()[0]
  ht.Default.startAnim({
    duration: 1000,
    easing: (t) => { return t },
    action: (v, t) => {
      hydraulicRod1.r3(degrees(8) + (degrees(7) - degrees(8)) * v, hydraulicRod1.r3()[1], hydraulicRod1.r3()[2]) // 液压杆1倾斜
      extensionRod1.r3(degrees(8) + (degrees(7) - degrees(8)) * v, extensionRod1.r3()[1], extensionRod1.r3()[2]) // 伸长杆1倾斜
      extensionRod1.p3(-185 + (-186 + 185) * v, -511 + (-507 + 511) * v, extensionRod1.p3()[2]) // 伸长杆1伸长
      hydraulicRod2.r3(degrees(-8) + (degrees(-7) - degrees(-8)) * v, hydraulicRod2.r3()[1], hydraulicRod2.r3()[2]) // 液压杆2倾斜
      extensionRod2.r3(degrees(-8) + (degrees(-7) - degrees(-8)) * v, extensionRod2.r3()[1], extensionRod2.r3()[2]) // 伸长杆2倾斜
      extensionRod2.p3(-185 + (-186 + 185) * v, -511 + (-507 + 511) * v, extensionRod2.p3()[2]) // 伸长杆2伸长
      postbrachium.r3(degrees(20) + (degrees(25) - degrees(20)) * v, postbrachium.r3()[1], postbrachium.r3()[2]) // 后臂向下移
      antebrachium.r3(oldValue + (degrees(-40) - oldValue) * v, antebrachium.r3()[1], antebrachium.r3()[2]) // 前臂向下移
      claw1.r3(degrees(-20) + (degrees(-60) - degrees(-20)) * v, claw1.r3()[1], claw1.r3()[2]) // 上爪抓取
      claw2.r3(degrees(-60) + (degrees(-30) - degrees(-60)) * v, claw2.r3()[1], claw2.r3()[2]) // 下爪抓取
    },
    finishFunc: () => {
      mechanicalArmAnim4()
    }
  })
}

这一段动画是机械臂从初始化状态到向下抓取的一个过程,我将每段动画分成函数来写比较方便后续管理,每一处也代表了一个步骤。这其中最复杂且细微的步骤要数液压杆的运动了,为了让动画看起来更加真实,我除了将手臂单独运动的过程中加入了延时执行下一段动画以体现机器运动的特点外,也把液压杆的部分也做了动画,如果不做处理,那么机械臂在上下移动的时候就会有不科学的效果出现。动画函数 在这种 demo 中应用的最广,而且里面也包含了一些缓动函数,有兴趣的博友们可以 点此处 自己亲自动手玩一玩~

这里面的拾取垃圾步骤还应用了我过去介绍过的 吸附 功能,这个方法非常的适合抓取物体的动作,通过 setHost 使节点吸附于宿主,这样就相当于子节点跟随父节点移动,此时只需要对机械臂进行偏移和旋转的操作,垃圾便会随之一起运动了,大大减少了工作量!

还有一部分更酷的属性设置给大家展示一下,可以让 3D 场景整体有更真实的阴影处理效果。首先我们要注意将无关的节点阴影通过 node.s(‘shadow.cast‘, false) 关闭,比如编组用的box,背景,地板和面板等。

最后我们就把阴影的细节做下调整,达到比较好的效果:

gv.enableShadow(true, {
  degreeX : 0,       // 投影 x 轴角度
  degreeZ : -25,      // 投影 z 轴角度
  intensity : 0.3,    // 阴影强度, 1 为黑色
  quality : ‘high‘,  // low / medium / high / ultra / 4096数值, 质量
  type : ‘soft‘,     // none / hard / soft
  radius : 0.2,      // type 为 hard / soft 时,补充的边缘厚度,用来提供更柔和的边缘
  bias : -0.003     // 深度浮点偏差补足
})

总结

更多动画 demo 以及工业化领域的文章请继续关注我的博客,感谢大家的支持!

医疗站(https://www.cnblogs.com/htdaydayup/p/11558748.html

在工业物联网从婴儿走到青年的成熟道路上,一定会有更多的潜力和挑战在等着我们,等待我们去开发,等待我们去创造!相信我们的技术成为国际水准会指日可待!同时在十一国庆后的第一个工作日祝大家精神饱满,工作顺利!

原文地址:https://www.cnblogs.com/xhload3d/p/11676987.html

时间: 2024-08-04 20:34:12

HTML5 + WebGL 实现的垃圾分类系统的相关文章

基于 HTML5 + WebGL 实现的垃圾分类系统

前言 垃圾分类,一般是指按一定规定或标准将垃圾分类储存.分类投放和分类搬运,从而转变成公共资源的一系列活动的总称.分类的目的是提高垃圾的资源价值和经济价值,力争物尽其用.垃圾在分类储存阶段属于公众的私有品,垃圾经公众分类投放后成为公众所在小区或社区的区域性准公共资源,垃圾分类搬运到垃圾集中点或转运站后成为没有排除性的公共资源.从国内外各城市对生活垃圾分类的方法来看,大致都是根据垃圾的成分.产生量,结合本地垃圾的资源利用和处理方式来进行分类的.到2019年6月25日,生活垃圾分类制度将入法.一套应

基于 HTML5 WebGL 的医疗物流系统

前言 物联网( IoT ),简单的理解就是物体之间通过互联网进行链接.世界上的万事万物,都可以通过数据的改变进行智能化管理.ioT 的兴起在医疗行业中具有拯救生命的潜在作用.不断的收集用户信息并且实时的进行诊断,所以未来 iot 肯定在医疗行业的应用会呈覆盖性.下面是我最近做的一个医疗物流系统,用来观察医疗物流过程. ht官网链接:http://www.hightopo.com/cn-index.html demo链接: https://www.hightopo.com/demo/pivas/

基于 HTML5 + WebGL 的 3D 太阳系系统

前言 近年来随着引力波的发现.黑洞照片的拍摄.火星上存在水的证据发现等科学上的突破,以及文学影视作品中诸如<三体>.<流浪地球>.<星际穿越>等的传播普及,宇宙空间中那些原本遥不可及的事物离我们越来越近,人们对未知文明的关注和对宇宙空间的好奇达到了前所未有的高度.站在更高的立足点上,作为人类这个物种中的一员,我们理所应当对我们生活的星球.所在的太阳系有一定的认识,对 8 大行星各自的运行轨道.质量.资源存储量甚至是地形有一定的了解. 本系统采用 Hightopo 的 H

基于 HTML5 + WebGL 实现 3D 可视化地铁系统

前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个地铁站的现实场景,包括地铁的实时运行情况,地铁上下行情况,视频监控,烟雾报警,电梯运行情况等等,帮助我们直观的了解当前的地铁站. 系统中

使用 HTML5 WebGL 实现逼真的云朵效果

这里给大家展示一个使用 HTML5 WebGL 实现超逼真的云朵效果.WebGL 是一项在网页浏览器呈现3D画面的技术,有别于过去需要安装浏览器插件,通过 WebGL 的技术,只需要编写网页代码即可实现3D图像的展示. WebGL 可以为 HTML5 Canvas 提供硬件3D加速渲染,这样 Web 开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了. 您可能感兴趣的相关文章 创意无限!一组网页边栏过渡动画[附源码下载] 真是好东西!13种非常动感的页面加载动画效果 你见过吗?9

HTML5+WebGL 的加油站 3D 可视化监控

前言 随着数字化,工业互联网,物联网的发展,我国加油站正向有人值守,无人操作,远程控制的方向发展,传统的人工巡查方式逐渐转变为以自动化控制为主的在线监控方式,即采用数据采集与监控系统 SCADA.SCADA 系统的推广使用,大大提高了我国加油站的监控效率,本文所讲的则是通过对加油站的可视化建模,结合 HT 的 3D 可视化以及 2D 监控面板来实现对加油站的可视化监控.三维可视化监控系统是将三维的可视化技术和数据采集与监控技术融合,充分发挥了两种技术的核心优势,并通过数据库进行数据共享,共同构成

基于 HTML5 WebGL 构建智能数字化城市 3D 全景

前言 自 2011 年我国城镇化率首次突破 50% 以来,<新型城镇化发展规划>将智慧城市列为我国城市发展的三大目标之一,并提出到 2020 年,建成一批特色鲜明的智慧城市.截至现今,全国 95% 的副省级以上城市.76% 的地级以上城市,总计约 500 多个城市提出或在建智慧城市. 基于这样的背景,本系统采用 Hightopo 的  HT for Web  产品来构造轻量化的 智慧城市 3D 可视化场景,通过三个角度的转换,更清晰让我们感知到 5G 时代下数字化智能城市的魅力 预览地址:HT

基于HTML5 WebGL的工业化3D电子围栏

前言 现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个现代化工厂的现实场景,包括工厂工人的实时位置.电子围栏的范围.现场的安全情况等等,帮助我们直观的了解当前工厂人员的安全状况. 本篇文章通过对工厂可视化场景的搭建和模型的加载,人物实时定位代码的实现.电子围栏和轨

基于 HTML5 WebGL 的智慧城市(一)

前言 中共中央.国务院在今年12月印发了<长江三角洲区域一体化发展规划纲要>(下文简称<纲要>),并发出通知,要求各地区各部门结合实际认真贯彻落实. <纲要>强调,要提升基础设施互联互通水平,打造数字长三角,协同建设新一代信息基础设施,共同推动重点领域智慧应用.大力发展基于物联网.大数据.人工智能的专业化服务,提升各领域融合发展.信息化协同和精细化管理水平.围绕城市公共管理.公共服务.公共安全等领域,支持有条件的城市建设基于人工智能和 5G 物联的城市大脑集群. 城市治