基于WebGL架构的3D可视化平台—新风系统演示

简介: 新风系统是根据在密闭的室内一侧用专用设备向室内送新风,再从另一侧由专用设备向室外排出,在室内会形成“新风流动场”,从而满足室内新风换气的需要。实施方案是:采用高风压、大流量风机、依靠机械强力由一侧向室内送风,由另一侧用专门设计的排风风机向室外排出的方式强迫在系统内形成新风流动场。

新风系统是根据在密闭的室内一侧用专用设备向室内送新风,再从另一侧由专用设备向室外排出,在室内会形成“新风流动场”,从而满足室内新风换气的需要。实施方案是:采用高风压、大流量风机、依靠机械强力由一侧向室内送风,由另一侧用专门设计的排风风机向室外排出的方式强迫在系统内形成新风流动场。在送风的同时对进入室内的空气进过滤、消毒、杀菌、增氧、预热(冬天)。

接下来就用ThingJs平台来搭建一个新风系统
第一步,利用CampusBuilder搭建模拟场景。CampusBuilder的模型库有各种各样的模型,使我们搭建出的场景更逼真。

1 //加载场景代码
2 var app = new THING.App({
3     // 场景地址
4     "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/新风演示2",
5 
6 });

第二步,创建三个数组来保存每个风的模型。

1 var hotWindGroup = [];
2 var coolWindGroup = [];
3 var newWindGroup = [];
4 var wind = null;

第三步,构造一个创建风的函数,为了方便创建风及其位置,我们选取排风设备为风的父物体,将创建出来的风的visiable属性设置为false(这里这个坐标问题可以看一下官网的教程中控制物体中的坐标转换)。

 1 function createWind(parent, x, y, angle, localPosition, color, group) {
 2     rs = app.query(parent)[0];
 3     wind = app.create({
 4         type: 'Thing',
 5         name: 'hotWind',
 6         url: 'http://model.3dmomoda.cn/models/4da706d8a37047298c0318a5b9546abd/0/gltf/',
 7         localPosition: localPosition,
 8         scale: [1, 2, 1],
 9         angle: angle,
10         parent: rs,
11     });
12     wind.style.color = color;
13     wind.visible = false;
14     wind.rotateX(x);
15     wind.rotateY(y);
16     group.push(wind);
17 }

第四步,开始创建风模型,并调整一下摄像机的角度及位置。

 1 app.on('load', function () {
 2     //摄像机角度
 3     app.camera.position = [-22.91452445633646, 30.46296743148116, -23.83548169673341];
 4     app.camera.target = [-13.532807014407252, 5.6565539015865856, -3.3431546399681276];
 5     //hotWind
 6     createWind('空调1', 0, 0, 0, [0, -2, 0], '#FF0000', hotWindGroup);
 7     createWind('空调1', 0, 0, 0, [0, -2, 0.5], '#FF0000', hotWindGroup);
 8     createWind('空调1', 0, 0, 0, [0, -2, 1], '#FF0000', hotWindGroup);
 9     createWind('空调2', 0, 0, 0, [0, -2, 0], '#FF0000', hotWindGroup);
10     createWind('空调2', 0, 0, 0, [0, -2, 0.5], '#FF0000', hotWindGroup);
11     createWind('空调2', 0, 0, 0, [0, -2, 1], '#FF0000', hotWindGroup);
12     //coolWind
13     createWind('空调1', 0, 0, 0, [0, -2, 0], '#0000FF', coolWindGroup);
14     createWind('空调1', 0, 0, 0, [0, -2, 0.5], '#0000FF', coolWindGroup);
15     createWind('空调1', 0, 0, 0, [0, -2, 1], '#0000FF', coolWindGroup);
16     createWind('空调2', 0, 0, 0, [0, -2, 0], '#0000FF', coolWindGroup);
17     createWind('空调2', 0, 0, 0, [0, -2, 0.5], '#0000FF', coolWindGroup);
18     createWind('空调2', 0, 0, 0, [0, -2, 1], '#0000FF', coolWindGroup);
19     //newWind
20     createWind('排风1', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
21     createWind('排风1', -50, 0, 0, [0, -0.5, 4], '#00FF00', newWindGroup);
22     createWind('排风1', -50, 0, 0, [0, -0.5, 6], '#00FF00', newWindGroup);
23     createWind('排风1', -50, 50, 50, [2, -0.5, 7], '#00FF00', newWindGroup);
24     createWind('排风1', -50, 50, 50, [4, -0.5, 8], '#00FF00', newWindGroup);
25     createWind('排风1', -50, 50, 50, [6, -0.5, 9], '#00FF00', newWindGroup);
26     createWind('排风1', -50, 50, 50, [8, -0.5, 12], '#00FF00', newWindGroup);
27     createWind('排风1', -50, 50, 50, [10, -0.5, 15], '#00FF00', newWindGroup);
28     createWind('排风1', -50, 50, 50, [12, -0.5, 18], '#00FF00', newWindGroup);
29     createWind('排风1', -50, 50, 50, [10, -0.5, 9], '#00FF00', newWindGroup);
30     createWind('排风1', -50, 50, 50, [14, -0.5, 9], '#00FF00', newWindGroup);
31     createWind('排风1', -50, 50, 50, [18, -0.5, 9], '#00FF00', newWindGroup);
32     createWind('排风1', -50, 50, 50, [22, -0.5, 9], '#00FF00', newWindGroup);
33     createWind('排风1', -50, 50, 50, [26, -0.5, 9], '#00FF00', newWindGroup);
34     createWind('排风2', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
35     createWind('排风3', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
36     createWind('排风4', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
37     createWind('排风4', -50, 0, 0, [0, -0.5, 4], '#00FF00', newWindGroup);
38     createWind('排风4', -50, 0, 0, [0, -0.5, 6], '#00FF00', newWindGroup);
39     createWind('排风4', -50, 0, 0, [0, -0.5, 8], '#00FF00', newWindGroup);
40     createWind('排风4', -50, 0, 0, [0, -0.5, 10], '#00FF00', newWindGroup);
41     createWind('排风4', -50, 0, 0, [0, -0.5, 12], '#00FF00', newWindGroup);
42     createWind('排风4', -90, 50, 50, [2, -0.6, 12], '#00FF00', newWindGroup);
43     createWind('排风4', -90, 50, 50, [4, -0.7, 12], '#00FF00', newWindGroup);
44     createWind('排风4', -90, 50, 50, [6, -0.8, 13], '#00FF00', newWindGroup);
45     createWind('排风4', -90, 50, 90, [8, -0.8, 11], '#00FF00', newWindGroup);
46     createWind('排风4', -90, 50, 90, [12, -0.8, 9], '#00FF00', newWindGroup);
47     createWind('排风4', -90, 50, 90, [16, -0.8, 7], '#00FF00', newWindGroup);
48     createWind('排风4', -90, 50, 90, [20, -0.8, 5], '#00FF00', newWindGroup);
49     createWind('排风4', -90, 50, 90, [24, -0.8, 3], '#00FF00', newWindGroup);
50     createWind('排风4', -90, 0, 90, [8, -0.8, 13], '#00FF00', newWindGroup);
51     createWind('排风4', -90, 0, 90, [12, -0.8, 13], '#00FF00', newWindGroup);
52     createWind('排风4', -90, 0, 90, [16, -0.7, 13], '#00FF00', newWindGroup);
53     createWind('排风4', -90, 0, 90, [20, -0.6, 13], '#00FF00', newWindGroup);
54     //createWind('排风4', -90, 0, 90, [24, -0.5, 13], '#00FF00', newWindGroup);
55 
56     //热风演示
57     new THING.widget.Button('热风演示', function () {
58         for (let i of coolWindGroup) {
59             i.visible = false;
60         };
61         for (let i of hotWindGroup) {
62             i.visible = true;
63         };
64 
65     });
66 
67     //冷风演示
68     new THING.widget.Button('冷风演示', function () {
69         for (let i of coolWindGroup) {
70             i.visible = true;
71         };
72         for (let i of hotWindGroup) {
73             i.visible = false;
74         };
75     });
76 
77     //新风演示
78     new THING.widget.Button('新风演示', function () {
79         playNewWind();
80     });
81 
82     function playNewWind() {
83         for (var i = 0; i < newWindGroup.length; i++) {
84             if(i==newWindGroup.length-1)
85             return;
86             newWindGroup[i].visible = true;
87             newWindGroup[i].moveTo({
88                 "time": 4000,
89                 "position": newWindGroup[i+1].position,
90             });
91         }
92 });

第五步,运行项目。演示地址

思考与总结:
首先就是空间坐标系下转父物体坐标真是弄晕了,看了官网的教程多少理解了一点。刚开始的时候我一直认为我的子物体以父物体坐标下放置的时候,子物体坐标轴的问题指向的问题。看了教程发现自己的担心多余了,就好像是人戴鸭舌帽帽子不管戴在谁的头上都一样。
其次就是让风动起来,最初是想让一个模型在空间中运动,发现效果不好用。最后就创建了多个模型他们对应着有各自的点,让每一个模型向他下一个模型的位置移动实现运动。

完整代码

//加载场景代码
var app = new THING.App({
    // 场景地址
    "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/新风演示2",

});

var hotWindGroup = [];
var coolWindGroup = [];
var newWindGroup = [];
var wind = null;

function createWind(parent, x, y, angle, localPosition, color, group) {
    rs = app.query(parent)[0];
    wind = app.create({
        type: 'Thing',
        name: 'hotWind',
        url: 'http://model.3dmomoda.cn/models/4da706d8a37047298c0318a5b9546abd/0/gltf/',
        localPosition: localPosition,
        scale: [1, 2, 1],
        angle: angle,
        parent: rs,
    });
    wind.style.color = color;
    wind.visible = false;
    wind.rotateX(x);
    wind.rotateY(y);
    group.push(wind);
}

app.on('load', function () {
    //摄像机角度
    app.camera.position = [-22.91452445633646, 30.46296743148116, -23.83548169673341];
    app.camera.target = [-13.532807014407252, 5.6565539015865856, -3.3431546399681276];
    //hotWind
    createWind('空调1', 0, 0, 0, [0, -2, 0], '#FF0000', hotWindGroup);
    createWind('空调1', 0, 0, 0, [0, -2, 0.5], '#FF0000', hotWindGroup);
    createWind('空调1', 0, 0, 0, [0, -2, 1], '#FF0000', hotWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 0], '#FF0000', hotWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 0.5], '#FF0000', hotWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 1], '#FF0000', hotWindGroup);
    //coolWind
    createWind('空调1', 0, 0, 0, [0, -2, 0], '#0000FF', coolWindGroup);
    createWind('空调1', 0, 0, 0, [0, -2, 0.5], '#0000FF', coolWindGroup);
    createWind('空调1', 0, 0, 0, [0, -2, 1], '#0000FF', coolWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 0], '#0000FF', coolWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 0.5], '#0000FF', coolWindGroup);
    createWind('空调2', 0, 0, 0, [0, -2, 1], '#0000FF', coolWindGroup);

    //newWind
    createWind('排风1', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
    createWind('排风1', -50, 0, 0, [0, -0.5, 4], '#00FF00', newWindGroup);
    createWind('排风1', -50, 0, 0, [0, -0.5, 6], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [2, -0.5, 7], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [4, -0.5, 8], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [6, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [8, -0.5, 12], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [10, -0.5, 15], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [12, -0.5, 18], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [10, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [14, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [18, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [22, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风1', -50, 50, 50, [26, -0.5, 9], '#00FF00', newWindGroup);
    createWind('排风2', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
    createWind('排风3', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 2], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 4], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 6], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 8], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 10], '#00FF00', newWindGroup);
    createWind('排风4', -50, 0, 0, [0, -0.5, 12], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 50, [2, -0.6, 12], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 50, [4, -0.7, 12], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 50, [6, -0.8, 13], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 90, [8, -0.8, 11], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 90, [12, -0.8, 9], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 90, [16, -0.8, 7], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 90, [20, -0.8, 5], '#00FF00', newWindGroup);
    createWind('排风4', -90, 50, 90, [24, -0.8, 3], '#00FF00', newWindGroup);
    createWind('排风4', -90, 0, 90, [8, -0.8, 13], '#00FF00', newWindGroup);
    createWind('排风4', -90, 0, 90, [12, -0.8, 13], '#00FF00', newWindGroup);
    createWind('排风4', -90, 0, 90, [16, -0.7, 13], '#00FF00', newWindGroup);
    createWind('排风4', -90, 0, 90, [20, -0.6, 13], '#00FF00', newWindGroup);
    //createWind('排风4', -90, 0, 90, [24, -0.5, 13], '#00FF00', newWindGroup);

    //热风演示
    new THING.widget.Button('热风演示', function () {
        for (let i of coolWindGroup) {
            i.visible = false;
        };
        for (let i of hotWindGroup) {
            i.visible = true;
            //playWind(i,[0,-0.6499999999999999,0],[0,-0.7234152255572697,0.46352549156242107],[0,-1.2683221215612903,1.2135254915624212],[0,-2.15,1.5])
        };

    });

    //冷风演示
    new THING.widget.Button('冷风演示', function () {
        for (let i of coolWindGroup) {
            i.visible = true;
        };
        for (let i of hotWindGroup) {
            i.visible = false;
        };
    });

    //新风演示
    new THING.widget.Button('新风演示', function () {
        playNewWind();
    });

    function playNewWind() {
        for (var i = 0; i < newWindGroup.length; i++) {
            if(i==newWindGroup.length-1)
            return;
            newWindGroup[i].visible = true;
            newWindGroup[i].moveTo({
                "time": 4000,
                "position": newWindGroup[i+1].position,
            });
        }
    }

});

 

目录
打赏
0
0
0
0
3960
分享
相关文章
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
159 3
基于SCA的软件无线电系统的概念与架构
软件通信体系架构(SCA)是基于软件定义无线电(SDR)思想构建的开放式、标准化和模块化平台,旨在通过软件实现通信功能的灵活配置。SCA起源于美军为解决“信息烟囱”问题而推出的联合战术无线电系统(JTRS),其核心目标是提升多军种联合作战通信能力。 上海介方信息公司的OpenSCA操作环境严格遵循SCA4.1/SRTF标准,支持高集成、嵌入式等场景,适用于军用通信、雷达等领域。 SCA体系包括目标平台资源层(TRL)、环境抽象层(EAL)、SRTF操作环境(OE)及应用层(AL)。其中,SRTF操作环境包含操作系统、运行时环境(RTE)和核心框架(CF),提供波形管理、资源调度等功能。
【YashanDB知识库】如何排查YMP报错:”OCI版本为空或OCI的架构和本地系统的架构不符“
【YashanDB知识库】如何排查YMP报错:”OCI版本为空或OCI的架构和本地系统的架构不符“
【YashanDB知识库】如何排查YMP报错:”OCI版本为空或OCI的架构和本地系统的架构不符“
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
81 2
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
MCP与A2A协议比较:人工智能系统互联与协作的技术基础架构
本文深入解析了人工智能领域的两项关键基础设施协议:模型上下文协议(MCP)与代理对代理协议(A2A)。MCP由Anthropic开发,专注于标准化AI模型与外部工具和数据源的连接,降低系统集成复杂度;A2A由Google发布,旨在实现不同AI代理间的跨平台协作。两者虽有相似之处,但在设计目标与应用场景上互为补充。文章通过具体示例分析了两种协议的技术差异及适用场景,并探讨了其在企业工作流自动化、医疗信息系统和软件工程中的应用。最后,文章强调了整合MCP与A2A构建协同AI系统架构的重要性,为未来AI技术生态系统的演进提供了方向。
673 62
深圳农商银行三代核心系统全面投产 以云原生架构筑牢数字化转型基石
深圳农商银行完成第三代核心系统全面上云,日均交易超3000万笔,峰值处理效率提升2倍以上。扎根深圳70余年,与阿里云共建“两地三中心”分布式云平台,实现高可用体系及全栈护航。此次云原生转型为行业提供可复制样本,未来将深化云计算与AI合作,推动普惠金融服务升级。
256 17
MCP 实践:基于 MCP 架构实现知识库答疑系统
文章探讨了AI Agent的发展趋势,并通过一个实际案例展示了如何基于MCP(Model Context Protocol)开发一个支持私有知识库的问答系统。
MCP 实践:基于 MCP 架构实现知识库答疑系统
JeecgBoot 低代码平台 v3.7.4 发布,后台架构大升级
JeecgBoot 是一款基于 SpringBoot2.x/3.x 和 SpringCloud Alibaba 的企业级 AI 低代码平台,采用前后端分离架构(Ant Design & Vue3),支持 Mybatis-plus 和 Shiro。它集成了强大的代码生成器,可一键生成前后端代码,无需手动编写,大幅减少重复工作。平台支持 DeepSeek、ChatGPT 和 Ollama 等主流大模型,提供 AI 对话
237 9
中小医院云HIS系统源码,系统融合HIS与EMR功能,采用B/S架构与SaaS模式,快速交付并简化运维
这是一套专为中小医院和乡镇卫生院设计的云HIS系统源码,基于云端部署,采用B/S架构与SaaS模式,快速交付并简化运维。系统融合HIS与EMR功能,涵盖门诊挂号、预约管理、一体化电子病历、医生护士工作站、收费财务、药品进销存及统计分析等模块。技术栈包括前端Angular+Nginx,后端Java+Spring系列框架,数据库使用MySQL+MyCat。该系统实现患者管理、医嘱处理、费用结算、药品管控等核心业务全流程数字化,助力医疗机构提升效率和服务质量。
247 4
布谷直播系统源码开发实战:从架构设计到性能优化
作为山东布谷科技的一名技术研发人员,我参与了多个直播系统平台从0到1的开发和搭建,也见证了直播行业从萌芽到爆发的全过程。今天,我想从研发角度,分享一些直播系统软件开发的经验和心得,希望能对大家有所帮助。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问