{"id":16778641,"url":"https://github.com/binary-husky/vhmap","last_synced_at":"2025-03-22T00:31:13.660Z","repository":{"id":182975196,"uuid":"669417390","full_name":"binary-husky/vhmap","owner":"binary-husky","description":"一个简洁易用3D场景创建和控制工具。基于ThreeJS。纯Python接口。它适用于科研、多智能体强化学习领域的3D演示、娱乐等应用。","archived":false,"fork":false,"pushed_at":"2023-12-21T09:50:07.000Z","size":26311,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-23T20:15:21.315Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binary-husky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-22T07:55:47.000Z","updated_at":"2024-04-18T04:13:41.000Z","dependencies_parsed_at":"2024-10-13T07:28:26.673Z","dependency_job_id":"6eaae9df-13cd-4d5d-bcff-3a786162e406","html_url":"https://github.com/binary-husky/vhmap","commit_stats":null,"previous_names":["binary-husky/vhmap"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binary-husky%2Fvhmap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binary-husky%2Fvhmap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binary-husky%2Fvhmap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binary-husky%2Fvhmap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binary-husky","download_url":"https://codeload.github.com/binary-husky/vhmap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244890102,"owners_count":20527030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T07:28:18.809Z","updated_at":"2025-03-22T00:31:10.111Z","avatar_url":"https://github.com/binary-husky.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Visual Hybrid Multi-Agent Playground (VHMAP 使用说明书)\n\nvhmap是一个基于ThreeJs+Python的开源项目，提供了一个简洁易用的Python接口，用于创建和控制3D场景的可视化工具。它适用于**科研**、多智能体强化学习领域的3D演示、娱乐等应用。vhmap具有以下特点：\n\n简化的Python接口；客户端渲染，流畅的帧率；占用服务端资源极少；基于ThreeJs，支持拖动和手机触屏；支持透视和投影两种视图切换；支持回放；使用zlib压缩数据流，网络带宽需求小。\n\n通过以上特点，vhmap为用户提供了一个简单高效、具有交互性的3D可视化解决方案。\n\n## 面向场景和特点\n面向场景：\n- 科研，尤其是多智能体强化学习领域\n- 3D演示\n- 2D实验数据搜集和可视化（见[2D文档](README_SCI.md)）\n\n应用特点：\n- Python接口简化到极致\n- 渲染在客户端，自动插帧，纵享丝滑帧率\n- 服务端依赖少\n- 占用服务端资源极少\n- 基于ThreeJs，支持拖动，支持手机触屏\n- 支持透视和投影两种视图的切换\n- 支持回放\n- 使用zlib压缩数据流，网络带宽需求小\n\n## 安装 \n```shell\npip install vhmap\u003e=4.2\n```\n\n## 20行代码-展示VHMAP的简单、丝滑\n实现下图，仅需要20行python代码(含初始化)\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"md_imgs/动画x7.gif\" width=\"700\" \u003e\n\u003c/div\u003e\n\n界面功能、操作介绍：\n- 鼠标右键平移，左键旋转，滚轮缩放\n- 支持触屏，如果你笔记本或手机有触控屏幕\n- 左上角显示渲染刷新率\n- play fps：每秒播放多少关键帧(小于渲染刷新率，则插帧；大于渲染刷新率，则超出部分无效)\n- pause：暂停\n- next frame：暂停并切换下一帧\n- previous frame：暂停并切换上一帧\n- loop to start：播放完所有数据，回到第一帧\n- ppt step：以极慢极慢的速度播放一帧，方便录屏，按下后会卡顿几秒\n- use orthcam：切换透视视图（物体近大远小）/投影视图（工程制图学过没），\n- P.S. 第一次切换到投影视图时，需要用鼠标滚轮放大画面\n\n```python\nfrom vhmap.mcom import mcom\nimport numpy as np\nclass TestVhmap():\n    def render(self, t):\n        if not hasattr(self, 'visual_bridge'):\n            self.visual_bridge = mcom(path='TEMP/v3d_logger/', draw_mode='Threejs')\n            self.visual_bridge.v3d_init()\n            self.visual_bridge.set_style('gray')\n            self.visual_bridge.advanced_geometry_rotate_scale_translate('box', 'BoxGeometry(1,1,1)',   0,0,0,  1,1,1, 0,0,0) \n\n        x = np.cos(t); y=np.sin(t); z= np.cos(t)*np.sin(t)  # 此帧的x,y,z坐标\n        self.visual_bridge.v3d_object(\n            'box|2233|Red|0.1',     # 填入 ‘形状|几何体之ID标识|颜色|大小’即可\n            x, y, z, ro_x=0, ro_y=0, ro_z=np.sin(t),    # 三维位置+欧拉旋转变换，六自由度\n            track_n_frame=20)                           # 显示历史20帧留下的轨迹\n        self.visual_bridge.v3d_show()   # 结束关键帧\n\nif __name__ == '__main__':\n    x = TestVhmap()\n    for step in range(1000): x.render(t=step/np.pi)\n    import time; time.sleep(1000)   # 启动后打开输出的url地址即可\n# 这是第21行，已经写完了 :joy: \n```\n\n## 50行代码-演示3维N体运动(低精度定步长)\n- 代码1详情请见：vhmap/examples/nb.py\n运行方法：\n```\npip install vhmap\n\npython -m vhmap.examples.nb\n```\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"md_imgs/动画9.gif\" width=\"700\" \u003e\n\u003c/div\u003e\n\n## 90行代码-使用dop853求解常微分方程演示三体、N体运动\n- 代码2详情请见：vhmap/examples/nb_3body_specials.py\n- 代码3详情请见：vhmap/examples/nb_nbody_specials.py\n```\npip install vhmap\n\npython -m vhmap.examples.nb_3body_specials\n```\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"md_imgs/动画11.gif\" width=\"300\", height=\"275\"  \u003e\n\u003cimg src=\"md_imgs/动画13.gif\"  width=\"300\" \u003e\n\u003cimg src=\"md_imgs/动画12-1.gif\"  width=\"700\" \u003e\n\u003c/div\u003e\n三体初始值: Xiaoming LI, Shanghai Jiaotong University \nhttps://numericaltank.sjtu.edu.cn/three-body/three-body-movies.htm\n\n## 如何回放\nVHMAP在接收到数据后，会自动地在 TEMP/v3d_logger/ 路径下生成backup.dp数据文件，该文件可以用于回放。\n\n警告：数据文件会在下一次运行时被新的日志文件覆盖，必要时请手动备份！\n```\npython -m vhmap.threejs_replay -f TEMP/v3d_logger/backup.dp.gz -p 8085\n```\n其中-f后面的是回放文件的路径，-p接端口号例如8085，之后打开 http://localhost:8085 即可。\n\n\n## API-中文\n\n引入\n```python\nfrom vhmap.mcom import mcom\n```\n\n### 初始化\n```python\nvisual_bridge = mcom(path='TEMP/v3d_logger/', draw_mode='Threejs')\nvisual_bridge.v3d_init()\n```\n\n### set_style\n```python\nvisual_bridge.set_style('star')       # 布置星空\nvisual_bridge.set_style('grid')       # 布置2维网格\nvisual_bridge.set_style('grid3d')     # 布置3维网格\nvisual_bridge.set_style('earth')      # 在场景中放一个地球\nvisual_bridge.set_style('background', color='White') # 注意不可以省略参数键值'color=' ！\n\n# 如果label要使用中文字符，需要设置字体，否则字符会变成问号'?'（另外如果字体没加载完，或者加载完刷新不及时，也会显示为?）\nvisual_bridge.set_style('font', fontPath='/examples/fonts/ttf/FZYTK.TTF') # 注意不可以省略参数键值'fontPath=' ！\n# 如果label要使用中文字符，而且需要换行，则还需要额外设置行距 fontLineHeight\nvisual_bridge.set_style('font', fontPath='/examples/fonts/ttf/simhei.ttf', fontLineHeight=1500)   \n\n\nvisual_bridge.set_style('skybox', path='/wget/shabby.jpg')    # 设置天空盒子，注意不可以省略参数键值'path='\nvisual_bridge.set_style('skybox6side',    # 设置天空盒子，注意不可以省略参数键值 !!\n    posx='/wget/mars_textures/mars_posx.jpg',   \n    negx='/wget/mars_textures/mars_negx.jpg',   \n    posy='/wget/mars_textures/mars_posy.jpg',\n    negy='/wget/mars_textures/mars_negy.jpg',\n    posz='/wget/mars_textures/mars_posz.jpg',\n    negz='/wget/mars_textures/mars_negz.jpg',\n)\n\n\n```\n\n### 声明几何体\n```\nadvanced_geometry_rotate_scale_translate(自定义几何体名词, 几何体形状, 几何体旋转1, 几何体旋转2, 几何体旋转3, 几何体尺度1, 几何体尺度2, 几何体尺度3, 几何体平移1, 几何体平移2, 几何体平移3)\n```\n\n```python\n# declare geo 'oct1', init with OctahedronGeometry, then (1)rotate \u0026 (2)scale \u0026 (3)translate\nvisual_bridge.advanced_geometry_rotate_scale_translate('oct1', 'OctahedronGeometry(1,0)', 0,0,0,  1,1,1, 0,0,0)   # 八面体\n# 需要换成其他几何体，请把'OctahedronGeometry(1,0)'替换，参考网址 https://threejs.org/docs/index.html?q=Geometry\nvisual_bridge.advanced_geometry_rotate_scale_translate('any_name_you_want', 'TorusGeometry(10,3,16,100)',   0,0,0,  1,1,1, 0,0,0) # 甜甜圈\n# declare geo 'ball'\nvisual_bridge.advanced_geometry_rotate_scale_translate('ball', 'SphereGeometry(1)',   0,0,0,  1,1,1, 0,0,0) # 球体\n# declare geo 'box'\nvisual_bridge.advanced_geometry_rotate_scale_translate('box', 'BoxGeometry(1,1,1)',   0,0,0,  1,1,1, 0,0,0) # 长方体\n# declare geo 'Plane', 使用fbx模型，路径为/vhmap/threejsmod/examples/files/plane.fbx\nvisual_bridge.advanced_geometry_rotate_scale_translate('Plane', 'fbx=/examples/files/plane.fbx', -np.pi/2, 0, np.pi/2,  1,1,1, 0,0,0)   # 八面体\n\n```\n\n### v3d，可用颜色（JS颜色，支持Hex颜色）参考 https://www.w3schools.com/colors/colors_names.asp\n```python\n# 注意不可以省略参数键值\nx=1; y=2; z=3\nvisual_bridge.v3d_object(\n    'ball|8848|MidnightBlue|0.5',  # 填入核心参量： “已声明的形状|几何体的唯一ID标识|颜色|整体大小”\n    x, y, z,                # 三维位置，3/6dof\n    ro_x=0, ro_y=0, ro_z=0, # 欧拉旋转变换，3/6dof\n    # ro_order='XYZ',       # （测试中，勿使用）欧拉旋转顺序，详情见 https://threejs.org/docs/index.html?q=object#api/en/math/Euler\n    opacity=1,              # 透明度，1为不透明\n    renderOrder=0,          # 渲染顺序。合理使用，能解决透明物体异常遮蔽的情况\n    label='',               # 显示标签，空白不显示，用'\\n'换行\n    label_color='White',    # 标签颜色\n    # label_offset=np.array([0,2,2]), # 标签与物体之间的相对位置，实验选项，测试中，勿使用\n    # label_size=0.5, # 测试中，勿使用\n    track_n_frame=3,        # 是否显示轨迹（0代表否），轨迹由最新的track_n_frame次位置连接而成\n    track_tension=0.1,      # 轨迹曲线的平滑度，0为不平滑，推荐设置0不平滑\n    track_color='Green',    # 轨迹的颜色显示，输入js颜色名或者hex值均可\n    )\n```\n其中的“renderOrder”选项比较难以理解，如果没有显示异常，则设置为0，或者干脆删除该键值（默认0）。\n\n用它解决的问题是简单的：\n```\nIf: 一个（透明）物体A 被 一个透明物体B遮挡，但A部分或全部不可见\nThen: 增加B的renderOrder，或者减小A的renderOrder（取值范围0~127）\n\n此外，label标签的渲染顺序renderOrder是128，任意全透明物体的渲染顺序renderOrder是256\n```\n### 发送曲线\n```python\n# 画一条(0,0,0) -\u003e (1,1,0) -\u003e (2,2,0) -\u003e (3,3,0) 的线\n# 注意不可以省略参数键值!!\nvisual_bridge.line3d(\n    'simple|3999|MidnightBlue|0.004', # 填入核心参量： “simple|线条的唯一ID标识|颜色|整体大小”\n    x_arr=np.array([0, 1, 2, 3]),   # 曲线的x坐标列表\n    y_arr=np.array([0, 1, 2, 3]),   # 曲线的y坐标列表\n    z_arr=np.array([0, 0, 0, 0]),   # 曲线的z坐标列表\n    tension=0,  # 曲线的平滑度，0为不平滑，推荐不平滑\n    opacity=1,  # 透明度，1为不透明，不稳定仍然在测试中\n)\n\n# fat 型线条，支持调节宽度、虚线、透明度等，但是不稳定仍然在测试中\n# 注意不可以省略参数键值!!\nvisual_bridge.line3d(\n    'fat|3999|MidnightBlue|0.004', # 填入核心参量： “fat|线条的唯一ID标识|颜色|整体大小”\n    x_arr=np.array([0, 1, 2, 3]),   # 曲线的x坐标列表\n    y_arr=np.array([0, 1, 2, 3]),   # 曲线的y坐标列表\n    z_arr=np.array([0, 0, 0, 0]),   # 曲线的z坐标列表\n    dashScale=20,   # 此数越大，单位长度上的虚线切割越多\n    dashSize=1,     # 虚线切割之实线\n    gapSize=1,      # 虚线切割之实线间隔\n    tension=0,      # 曲线的平滑度，0为不平滑，推荐不平滑\n    opacity=1,      # 透明度，1为不透明\n)\n```\n\n### flash（从几何体src到几何体dst）\n```python\n# 注意不可以省略参数键值!!\nvisual_bridge.flash(\n    'beam',         # 有 beam 和 lightning 两种选择\n    src=index_ID,   # 发射者的几何体的唯一ID标识\n    dst=index_ID2,  # 接收者的几何体的唯一ID标识\n    dur=0.5,        # 光束持续时间，单位秒，绝对时间，不受播放fps的影响\n    size=0.03,      # 光束粗细\n    color='DeepSkyBlue' # 光束颜色\n)\n\n```\n\n\n终结这一帧（并开始下一帧）\n```python\nself.visual_bridge.v3d_show()\n```\n\n\n### 测试中-添加贴图\n```python\nvisual_bridge.advanced_geometry_material('ball', \n    map='/examples/planets/images/earthmap1k.jpg',\n    bumpMap='/examples/planets/images/earthmap1k.jpg',\n    bumpScale = 0.05,\n    specularMap='/examples/images/earthmap1k.jpg',\n    specular='Gray'\n)  \n```\n\n# 展示应用\n\n## 1. RRT算法（3D）\n![vhmap-rrt-half](https://github.com/binary-husky/vhmap/assets/96192199/5242de83-4330-4b1c-8ade-f8f92869a30f)\n![vhmap+rrt_crop mp4](https://github.com/binary-husky/vhmap/assets/96192199/f06158a7-b41a-41e3-8666-947b079b7d7a)\n\n## 2. A*算法（3D）\n![vhmap+Astar-crop mp4](https://github.com/binary-husky/vhmap/assets/96192199/b0740219-7596-4ac8-a0e6-632eb56499ea)\n\n## 3. Dijkstra算法（3D）\n![vhmap+dijkstra-crop mp4](https://github.com/binary-husky/vhmap/assets/96192199/0a518596-cdcf-4c0d-9006-43415b009416)\n\n## 4. N体（3D）\n![vhmap-n-body-crop mp4](https://github.com/binary-husky/vhmap/assets/96192199/15112c3e-8f97-4e3a-980a-cfa02e1ff0b8)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinary-husky%2Fvhmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinary-husky%2Fvhmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinary-husky%2Fvhmap/lists"}