基于 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/htdaydayup/p/11620061.html

时间: 2024-10-13 15:35:14

基于 HTML5 WebGL 的垃圾分类系统的相关文章

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

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

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

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

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

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

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

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

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

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

基于 HTML5 WebGL 的 水泥工厂可视化系统

前言 如今的制造行业,基于数据进行生产策略制定与管理已经成为一种趋势,特别是 工业4.0 的浪潮下,数据战略已经成为很多制造企业的优先战略,而数据可视化以更直观的方式,帮助指导决策,成为数据分析传递信息的重要工具.通过数据可视化系统助力实现数据驱动的工业世界,为 工业4.0 提供更加灵活.敏捷.高效.个性化的数据支撑.今天就给大家带来一个采用 Hightopo 的 HT for Web 产品实现了一个水泥工厂可视化系统. 系统预览 本案例共有七个子系统: 数据概况 -- 展示全厂年月时间单位的各

基于 HTML5 WebGL 的民航客机飞行监控系统

前言 前些日子出差,在飞机上看到头顶的监控面板,除了播放电视剧和广告之外,还会时不时的切换到一个飞机航行的监控系统,不过整个监控系统让人感到有一点点的简陋,所以我就突发奇想制作了一个采用 HT for Web 的升级版监控系统,demo 的效果还行,发出来大家相互学习下. demo 实现过程 云中穿行效果 为了达到飞机云中穿行的效果,最开始我遇到的问题是飞机飞行的层次感,也就通常所说的透视效果,这里我采用的是云通道和云背景以不同的速度流动,制造一种飞行的透视效果. 云我采用的是贴图的方式呈现的,

基于 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