Catmull-Rom P5 ThreeJs与前端

文章目录

    • 问题
      • Echarts 3D如何让曲线变得平滑?
      • Echarts 2D图中平滑效果是如何实现的?
      • 如何在一个Echarts 3D图中画一个圆圈?
      • 如何在Echarts 3D图中画一个立方体?
    • Catmull-Rom插值算法
      • 先来回答第二个问题
      • 回到第一个问题
      • 在Echarts 3D图中画一个圆圈
      • 在Echarts 3D图中画一个立方体

问题

Echarts 3D如何让曲线变得平滑?

假设,你遇到了如下需求:
将如下数据,在Echarts 3D图中展示出来

lineData: [[0, 30, 5],[10, 20, 10],[20, 50, 13],[30, 15, 25],[40, 20, 33],[50, 33, 50],[60, 24, 66],[70, 10, 80],[80, 28, 90],],

这个需求很常规,最终呈现的效果是这样的:
请添加图片描述
可以看到,在Echarts 3D图中,line3D模式下,上述数据集的成图效果是折线。现在再变更一个需求:要求折线数据端点处的过渡要平滑。
于是,我们立刻想到了Echarts 2D图中series中是可以配置smooth: true,这个属性的,通过这个属性,可以让折线在Echarts 2D图上的过渡变得平滑。然而很遗憾,当你在Echarts 3D图中进行上述设置时,并没有任何效果。

Echarts 2D图中平滑效果是如何实现的?

再比如,上述数据集,只取每个元素的前两个数据,不做平滑处理,它在Echarts 2D图上成图效果是这样的:
请添加图片描述
开启数据平滑之后,它的成图效果是这样的:
请添加图片描述
那么,Echarts 2D图中的平滑效果,是如何实现的?

如何在一个Echarts 3D图中画一个圆圈?

如何在Echarts 3D图中画一个立方体?

Catmull-Rom插值算法

先来回答第二个问题

实际上,在Echarts 2D图中,使用的是Catmull-Rom插值算法,它的绘图规则,是每个点 ( P_i ) 的切线方向等于其相邻两个控制点 ( P_{i-1} ) 和 ( P_{i+1} ) 连线的方向。下图为了说明Catmull-Rom插值算法的绘图规则,使用P5js curve方法,绘制的一个有两个控制点c1和c2经过平面上p1和p2的曲线。而P5js curve方法的底层,就是使用的Catmull-Rom插值算法。但是P5js对这个方法的文档描述可能有点问题,后半部分参数对照有问题,参数的意义应该分别是 控制点、途经点、途经点和控制点。
P25 Curve

在这里插入图片描述
回到Echarts 2D图中平滑曲线的实现,为了证明Echarts 2D图中使用的是Catmull-Rom插值算法,我们把smooth:true的配置去掉,然后使用ThreeJs中的SplineCurve构建曲线(SplineCurve使用的是Catmull-Rom插值算法),然后通过增加细分数(也就是调用getPoints(pointCount)方法时,增加pointCount的值),进行验证。

在这里插入图片描述
SplineCurve

const v2Array = this.lineData.map((value) => {return new THREE.Vector2(value[0], value[1]);});
const curve = new THREE.SplineCurve(v2Array);
const points = curve.getPoints(this.pointsCount);
// series
series: [{type: "line",data: points.map((point) => {return [point.x, point.y];}),},
],

在这里插入图片描述
可以看到,当细分数增加时,同样的数据集,最终和Echarts 2D图中平滑曲线的效果是一致的。

回到第一个问题

通过Catmull-Rom插值算法,可以进行二维空间曲线的平滑效果,同样的,在三维空间中,也是可以进行运算的。ThreeJs的CatmullRomCurve3这个曲线,就是进行空间曲线Catmull-Rom插值的对象。

 // 把关键点,变成三维Vector
const keyPoints = this.lineData.map((point) => {
return new THREE.Vector3(point[0], point[1], point[2]);
});
// 根据关键点,生成贝塞尔曲线
const curve = new THREE.CatmullRomCurve3(keyPoints);
// 构建series
series: [{type: "line3D",data: curve.getPoints(300).map((point) => {return [point.x, point.y, point.z];}),lineStyle: {width: 2,color: "red",},},
],

最终呈现的三维空间平滑曲线效果:
在这里插入图片描述

在Echarts 3D图中画一个圆圈

在Echarts 2D图中,我们通过自定义序列和graphic等API,是可以绘制基本几何图形的,然而,在Echarts 3D图中,却没有这个概念。
那么,要想在Echarts 3D图中画出一个圆,我们通过ThreeJs构建一个圆形,然后获取这个圆形每个点的坐标,最终通过line3D的方式,来画出一个圆:

const curve = new THREE.EllipseCurve(40,40, // ax, aY20,20 // xRadius, yRadius);
const points = curve.getPoints(50);
// 构建series
series: [{type: "line3D",data: points.map((point) => {return [point.x, point.y, 40];}),lineStyle: {width: 2,color: "red",},},
],

效果:
在这里插入图片描述
EllipseCurve
注意:这种方法呈现的圆形曲线,是平行与xy平面的,由于Curve没有旋转API的,所以如果需要其他朝向的圆,需要使用其他方式。

在Echarts 3D图中画一个立方体

立方体在3d图中的绘制,如果基础数据齐全(比如知道8个顶点的位置关系),还是比较简单的;但是如果信息有限,8个点的数据,需要间接计算出来(比如只知道几何体几何中心的位置和长宽高,或者需要进行平移,旋转等操作),那就比较繁琐了。Echarts 3D图中,使用ThreeJs,能帮助我们绕开这些繁琐的计算。

 const geometry = new THREE.BoxGeometry(10, 20, 30);geometry.translate(10, 10, 40);//   边信息const linePoints = [];const edges = new THREE.EdgesGeometry(geometry);const lineSegments = new THREE.LineSegments(edges);const lineGeometry = lineSegments.geometry;const xyzValues = lineGeometry.attributes.position.array;const valuesPerLine = 6;for (let i = 0; i < xyzValues.length; i += valuesPerLine) {const chunk = xyzValues.slice(i, i + valuesPerLine);linePoints.push([chunk.slice(0, 3), chunk.slice(3, 6)]);}// 构建series
series: linePoints.map((pointArray) => {return {type: "line3D",data: pointArray.map((point) => {return [point[0], point[1], point[2]];}),lineStyle: {width: 2,color: "red",},};
}),

效果:

在这里插入图片描述

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

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

相关文章

C#关闭程序 CefSharp.BrowserSubprocess.exe,执行控制台命令

执行控制台命令&#xff0c;关闭大量的CefSharp.BrowserSubprocess进程&#xff0c; 控制台命令&#xff1a; taskkill /f /im CefSharp.BrowserSubprocess.exe 有权限要求&#xff1a; 需要设置执行程序为管理员模式&#xff0c;IIS部署的应用程序&#xff0c;设置应用程序池…

git基础命令(三)之远程命令

目录 基础概念origin git clonegit remote add 添加远程存储库git remote 显示远程存储库列表git pushgit pushgit push origin mastergit push origin --allgit push -f origin mastegit push origin --tags git fetch获取远程仓库的更新查看远程分支的更新情况拉取特定远程分…

【Linux】——进程地址空间 Linux2.6内核进程调度队列

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、环境变量的补充 二、进程空间的地址 2.1、程序地址空间 2.2、研究背景 2.3、程序地址空间 来段代码感受一下 2.4、进程地址空间 2.5、如何…

一文搞懂IP

IP 1. 基本介绍2. IP地址定义3. IP地址分类4. 子网掩码5. 全局地址与私有地址 1. 基本介绍 TCP/IP 协议的心脏是网络层&#xff0c;主要“实现节点之间的通信”&#xff0c;即“点对点(end-to-end)通信”。 网络层包含IP(Internet Protocol)及DNS&#xff08;Domain Name Sys…

Linux的基本指令讲解

1 ls指令 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a; 对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项&#xff1a; -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含文件。 -d…

Leetcode 387. First Unique Character in a String

Problem Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1. Algorithm Use two lists: one list is used to count the letters in “s”; the other list is the position where the letter first …

Json Web Token(JWT) 快速入门

推荐视频&#xff1a;【从零开始掌握JWT】 目录 第一章 会话跟踪 01 使用Cookie和Session&#xff0c;jsessionid 02 使用token 例子一&#xff1a;自定义token 例子二&#xff1a;使用redis存储token 第一章 会话跟踪 应用背景 &#xff1a;浏览器访问web应用&#xff…

下拉树级带搜索功能

可以直接复制粘贴到自己的项目里,方法处把接口替换一下 <template><div><el-popoverplacement"bottom"width"200"trigger"click"><el-inputslot"reference"class"mrInput":placeholder"placehol…

天锐绿盾 | 公司内部文件数据 \ 资料加密系统,数据防泄密软件

#防止设计图纸、各种类型文件、各种类型软件、财务数据、客户资料、源代码&#xff0c;数据存储服务器、SVN、Git等商业核心文件数据外泄# 天锐绿盾是一款专业的企业级文件数据及资料加密系统&#xff0c;旨在为企业内部数据安全提供强有力的支持。 德人合科技 | ——天锐绿盾…

生成式人工智能如何改变商业和社会

生成式人工智能是否将带来生产力黄金时代,或在全球经济中摧毁数以百万计的生计?它是否将带人们步入个人充实的新成长道路,或引导他们一步步走入孤独和隔离的死胡同?它是否将 引领人类 走向新的高处,或播下我们集体毁灭的种子? 自ChatGPT上线以来14个月来,人们还没有完全弄清…

B站python爬虫课程笔记(Q11-15)

下面是学习的网址&#xff1a; ​​​​​​【Python爬虫】 目录 11、class定义类别的一些问题 1&#xff09;定义init初始化函数的一些问题 2&#xff09;定义两个不同函数之间要有空行 3&#xff09;print的技巧 12、class定义类别的一些问题2 13、class_inheritance类…

MySQL数据库的基本概念与安装

目录 引言 一、数据库的基本概念 &#xff08;一&#xff09;数据、表与数据库 1.数据(Data) 2.表 3.数据库 &#xff08;二&#xff09;数据库管理系统 &#xff08;三&#xff09;数据库系统 二、数据库的发展 三、主流数据库的介绍 &#xff08;一&#xff09;关…

地理数据表达方式学习——KML与SHP

一、KML-Keyhole Markup Language Keyhole Markup Language (KML)是一种XML符号&#xff0c;用于浏览器中二维地图和三维地球的地理注释和地理可视化&#xff08;地理数据包括点、线、面、多边形、多面体以及模型等&#xff09;。KML是伴随着Google Earth的使用而开发的&#x…

word的第六课笔记

1.排版的六大特点&#xff08;留白、对齐、亲密、对比、重复、可自动更新&#xff09; 先设置页边距为2厘米&#xff0c;左侧装订线考虑2.75厘米。段落间距段前段后设置一个就可以了&#xff0c;如段前0.5行 &#xff08;留白&#xff1a;让文字更加容易阅读&#xff0c;调大页…

AMRT 3D 数字孪生引擎(轻量化图形引擎、GIS/BIM/3D融合引擎):智慧城市、智慧工厂、智慧建筑、智慧校园。。。

AMRT3D 一、概述 1、提供强大完整的工具链 AMRT3D包含开发引擎、资源管理、场景编辑、UI搭建、项目预览和发布等项目开发所需的全套功能&#xff0c;并整合了动画路径、精准测量、动态天气、视角切换和动画特效等工具。 2、轻量化技术应用与个性化定制 AMRT3D适用于快速开…

体验函数式组件简单实现Loading 加载(造轮子篇)

一、前言 最近想着优化一下网站&#xff0c;在文章列表页加一个Loading操作&#xff0c;于是就想到了函数式组件&#xff0c;于是本章就来和大家一起简单探讨下实现思路。 二、Loading设计 这里我想实现的效果是&#xff1a;当我们刷新页面的时候&#xff0c;前端请求接口&…

【MySQL】中位数巧解之给定数字的频率查询中位数

力扣题 1、题目地址 571. 给定数字的频率查询中位数 2、模拟表 Numbers 表&#xff1a; Column NameTypenumintfrequencyint num 是这张表的主键(具有唯一值的列)。这张表的每一行表示某个数字在该数据库中的出现频率。 3、要求 中位数 是将数据样本中半数较高值和半数…

扭矩测量仪行业研究:规模不断扩大市场需求旺盛

一、市场趋势 扭矩测量仪是用于精确测量旋转力矩的精密仪器&#xff0c;广泛应用于汽车、航空航天、机械制造和电子产品等领域。随着工业自动化程度的提升和精密制造的需求增加&#xff0c;扭矩测量仪的市场呈现出稳步增长的趋势。 二、主要竞争者 市场上的主要竞争企业包括德国…

华为OD机试 - 求字符串中所有整数的最小和(Java JS Python C C++)

题目描述 输入字符串s&#xff0c;输出s中包含所有整数的最小和。 说明&#xff1a; 字符串s&#xff0c;只包含 a-z A-Z 合法的整数包括 1&#xff09;正整数&#xff1a;一个或者多个0-9组成&#xff0c;如 0 2 3 002 102 2&#xff09;负整数&#xff1a;负号 – 开头…

Python爬虫之Scrapy框架系列(24)——分布式爬虫scrapy_redis完整实战【XXTop250完整爬取】

目录&#xff1a; 每篇前言&#xff1a;1.使用分布式爬取豆瓣电影信息&#xff08;1&#xff09;settings.py文件中的配置&#xff1a;&#xff08;2&#xff09;spider文件的更改&#xff1a;&#xff08;3&#xff09;items.py文件&#xff08;两个项目一致&#xff01;&…