iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Javascript中怎么生成平滑曲线
  • 223
分享到

Javascript中怎么生成平滑曲线

2023-06-20 15:06:38 223人浏览 安东尼
摘要

这篇文章给大家介绍javascript中怎么生成平滑曲线,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言平滑曲线生成是一个很实用的技术很多时候,我们都需要通过绘制一些折线,然后让计算机平滑的连接起来,先来看下最终效果

这篇文章给大家介绍javascript中怎么生成平滑曲线,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

    前言

    Javascript中怎么生成平滑曲线

    平滑曲线生成是一个很实用的技术

    很多时候,我们都需要通过绘制一些折线,然后让计算机平滑的连接起来,

    先来看下最终效果(红色为我们输入的直线,蓝色为拟合过后的曲线) 首尾可以特殊处理让图形看起来更好:)

    Javascript中怎么生成平滑曲线

    实现思路是利用贝塞尔曲线进行拟合

    贝塞尔曲线简介

    贝塞尔曲线(英语:Bézier curve)是计算机图形学中相当重要的参数曲线。

    二次贝塞尔曲线

    Javascript中怎么生成平滑曲线

    二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t)追踪:

    Javascript中怎么生成平滑曲线

    三次贝塞尔曲线

    Javascript中怎么生成平滑曲线

    对于三次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2,和由二次曲线描述的点R0、R1所建构

    Javascript中怎么生成平滑曲线

    贝塞尔曲线计算函数

    根据上面的公式我们可有得到计算函数

    二阶

        bezier2P(p0: number, p1: number, p2: number, t: number) {    const P0 = p0 * Math.pow(1 - t, 2);    const P1 = p1 * 2 * t * (1 - t);    const P2 = p2 * t * t;    return P0 + P1 + P2;  }        getBezierNowPoint2P(      p0: Point,      p1: Point,      p2: Point,      num: number,      tick: number,  ): Point {    return {      x: this.bezier2P(p0.x, p1.x, p2.x, num * tick),      y: this.bezier2P(p0.y, p1.y, p2.y, num * tick),    };  }        create2PBezier(      p0: Point,      p1: Point,      p2: Point,      num: number = 100,      tick: number = 1,  ) {    const t = tick / (num - 1);    const points = [];    for (let i = 0; i < num; i++) {      const point = this.getBezierNowPoint2P(p0, p1, p2, i, t);      points.push({x: point.x, y: point.y});    }    return points;  }

    三阶

      bezier3P(p0: number, p1: number, p2: number, p3: number, t: number) {    const P0 = p0 * Math.pow(1 - t, 3);    const P1 = 3 * p1 * t * Math.pow(1 - t, 2);    const P2 = 3 * p2 * Math.pow(t, 2) * (1 - t);    const P3 = p3 * Math.pow(t, 3);    return P0 + P1 + P2 + P3;  }        getBezierNowPoint3P(      p0: Point,      p1: Point,      p2: Point,      p3: Point,      num: number,      tick: number,  ) {    return {      x: this.bezier3P(p0.x, p1.x, p2.x, p3.x, num * tick),      y: this.bezier3P(p0.y, p1.y, p2.y, p3.y, num * tick),    };  }        create3PBezier(      p0: Point,      p1: Point,      p2: Point,      p3: Point,      num: number = 100,      tick: number = 1,  ) {    const pointMum = num;    const _tick = tick;    const t = _tick / (pointMum - 1);    const points = [];    for (let i = 0; i < pointMum; i++) {      const point = this.getBezierNowPoint3P(p0, p1, p2, p3, i, t);      points.push({x: point.x, y: point.y});    }    return points;  }

    拟合算法

    Javascript中怎么生成平滑曲线

    问题在于如何得到控制点,我们以比较简单的方法

    取 p1-pt-p2的角平分线 c1c2垂直于该条角平分线 c2为p2的投影点取短边作为c1-pt c2-pt的长度对该长度进行缩放 这个长度可以大概理解为曲线的弯曲程度

    Javascript中怎么生成平滑曲线

    ab线段 这里简单处理 只使用了二阶的曲线生成 -> ? 这里可以按照个人想法处理

    bc线段使用abc计算出来的控制点c2和bcd计算出来的控制点c3 以此类推

        createSmoothLineControlPoint(      p1: Vector2D,      pt: Vector2D,      p2: Vector2D,      ratio: number = 0.3,  ) {    const vec1T: Vector2D = vector2dMinus(p1, pt);    const vecT2: Vector2D = vector2dMinus(p1, pt);    const len1: number = vec1T.length;    const len2: number = vecT2.length;    const v: number = len1 / len2;    let delta;    if (v > 1) {      delta = vector2dMinus(          p1,          vector2dPlus(pt, vector2dMinus(p2, pt).scale(1 / v)),      );    } else {      delta = vector2dMinus(          vector2dPlus(pt, vector2dMinus(p1, pt).scale(v)),          p2,      );    }    delta = delta.scale(ratio);    const control1: Point = {      x: vector2dPlus(pt, delta).x,      y: vector2dPlus(pt, delta).y,    };    const control2: Point = {      x: vector2dMinus(pt, delta).x,      y: vector2dMinus(pt, delta).y,    };    return {control1, control2};  }        createSmoothLine(points: Point[], ratio: number = 0.3) {    const len = points.length;    let resultPoints = [];    const controlPoints = [];    if (len < 3) return;    for (let i = 0; i < len - 2; i++) {      const {control1, control2} = this.createSmoothLineControlPoint(          new Vector2D(points[i].x, points[i].y),          new Vector2D(points[i + 1].x, points[i + 1].y),          new Vector2D(points[i + 2].x, points[i + 2].y),          ratio,      );      controlPoints.push(control1);      controlPoints.push(control2);      let points1;      let points2;      // 首端控制点只用一个      if (i === 0) {        points1 = this.create2PBezier(points[i], control1, points[i + 1], 50);      } else {        console.log(controlPoints);        points1 = this.create3PBezier(            points[i],            controlPoints[2 * i - 1],            control1,            points[i + 1],            50,        );      }      // 尾端部分      if (i + 2 === len - 1) {        points2 = this.create2PBezier(            points[i + 1],            control2,            points[i + 2],            50,        );      }      if (i + 2 === len - 1) {        resultPoints = [...resultPoints, ...points1, ...points2];      } else {        resultPoints = [...resultPoints, ...points1];      }    }    return resultPoints;  }

    案例代码

    const input = [        { x: 0, y: 0 },        { x: 150, y: 150 },        { x: 300, y: 0 },        { x: 400, y: 150 },        { x: 500, y: 0 },        { x: 650, y: 150 },    ]    const s = path.createSmoothLine(input);    let ctx = document.getElementById('cv').getContext('2d');    ctx.strokeStyle = 'blue';    ctx.beginPath();    ctx.moveTo(0, 0);    for (let i = 0; i < s.length; i++) {        ctx.lineTo(s[i].x, s[i].y);    }    ctx.stroke();    ctx.beginPath();    ctx.moveTo(0, 0);    for (let i = 0; i < input.length; i++) {        ctx.lineTo(input[i].x, input[i].y);    }    ctx.strokeStyle = 'red';    ctx.stroke();    document.getElementById('btn').addEventListener('click', () => {        let app = document.getElementById('app');        let index = 0;        let move = () => {            if (index < s.length) {                app.style.left = s[index].x - 10 + 'px';                app.style.top = s[index].y - 10 + 'px';                index++;                requestAnimationFrame(move)            }        }        move()    })

    附录:Vector2D相关的代码

    class Vector2D extends Array {    constructor(x: number = 1, y: number = 0) {    super();    this.x = x;    this.y = y;  }    set x(v) {    this[0] = v;  }    set y(v) {    this[1] = v;  }    get x() {    return this[0];  }    get y() {    return this[1];  }    get length() {    return Math.hypot(this.x, this.y);  }    get dir() {    return Math.atan2(this.y, this.x);  }    copy() {    return new Vector2D(this.x, this.y);  }    add(v) {    this.x += v.x;    this.y += v.y;    return this;  }    sub(v) {    this.x -= v.x;    this.y -= v.y;    return this;  }    scale(a) {    this.x *= a;    this.y *= a;    return this;  }    rotate(rad) {    const c = Math.cos(rad);    const s = Math.sin(rad);    const [x, y] = this;    this.x = x * c + y * -s;    this.y = x * s + y * c;    return this;  }    cross(v) {    return this.x * v.y - v.x * this.y;  }    dot(v) {    return this.x * v.x + v.y * this.y;  }    nORMalize() {    return this.scale(1 / this.length);  }}function vector2dPlus(vec1, vec2) {  return new Vector2D(vec1.x + vec2.x, vec1.y + vec2.y);}function vector2dMinus(vec1, vec2) {  return new Vector2D(vec1.x - vec2.x, vec1.y - vec2.y);}export {Vector2D, vector2dPlus, vector2dMinus};

    关于Javascript中怎么生成平滑曲线就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

    --结束END--

    本文标题: Javascript中怎么生成平滑曲线

    本文链接: https://www.lsjlt.com/news/297854.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Javascript中怎么生成平滑曲线
      这篇文章给大家介绍Javascript中怎么生成平滑曲线,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言平滑曲线生成是一个很实用的技术很多时候,我们都需要通过绘制一些折线,然后让计算机平滑的连接起来,先来看下最终效果...
      99+
      2023-06-20
    • 如何利用Javascript生成平滑曲线详解
      目录前言贝塞尔曲线简介二次贝塞尔曲线三次贝塞尔曲线贝塞尔曲线计算函数拟合算法附录:Vector2D相关的代码总结前言 平滑曲线生成是一个很实用的技术 很多时候,我们都需要通过绘制一...
      99+
      2024-04-02
    • canvas怎么画出平滑的曲线
      这篇文章将为大家详细讲解有关canvas怎么画出平滑的曲线,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。背景概要相信大家平时在学习canvas 或 项目开发中使用canvas的时候应该都遇到过这样的需求:...
      99+
      2023-06-09
    • android怎么实现可以滑动的平滑曲线图
      本文小编为大家详细介绍“android怎么实现可以滑动的平滑曲线图”,内容详细,步骤清晰,细节处理妥当,希望这篇“android怎么实现可以滑动的平滑曲线图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1 att...
      99+
      2023-07-02
    • matlab怎么画出光滑的曲线
      要画出光滑的曲线,可以使用MATLAB中的插值函数。下面是一种常用的方法:1. 首先,创建一个包含X和Y数据的向量,其中X是自变量,...
      99+
      2023-10-08
      matlab
    • javascript怎么删除水平线
      本篇内容介绍了“javascript怎么删除水平线”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
      99+
      2024-04-02
    • JavaScript中怎么生成随机数
      JavaScript中怎么生成随机数,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。代码实例如下:(function(){  &n...
      99+
      2024-04-02
    • SpringCloud服务的平滑上下线怎么实现
      这篇文章主要介绍“SpringCloud服务的平滑上下线怎么实现”,在日常操作中,相信很多人在SpringCloud服务的平滑上下线怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringCloud...
      99+
      2023-06-02
    • 怎么用纯JavaScript生成图片或滑块式验证码功能
      本文小编为大家详细介绍“怎么用纯JavaScript生成图片或滑块式验证码功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用纯JavaScript生成图片或滑块式验证码功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
      99+
      2023-07-04
    • Python中ROC曲线怎么绘制
      本篇内容介绍了“Python中ROC曲线怎么绘制”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!首先以支持向量机模型为例先导入需要使用的包,我...
      99+
      2023-06-22
    • 怎么使用C#最小二乘法拟合曲线成直线
      这篇文章主要介绍了怎么使用C#最小二乘法拟合曲线成直线的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用C#最小二乘法拟合曲线成直线文章都会有所收获,下面我们一起来看看吧。最小二乘法拟合曲线成直线效果拟合前...
      99+
      2023-07-05
    • Python中怎么绘制各种曲线
      本篇文章为大家展示了 Python中怎么绘制各种曲线,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Python 代码如下:import numpy as np ...
      99+
      2023-06-15
    • JavaScript中怎么生成随机验证码
      这篇文章将为大家详细讲解有关JavaScript中怎么生成随机验证码,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。利用canvas制作一个随机验证码:  1...
      99+
      2024-04-02
    • HTML5中怎么用canvas绘制曲线
      本文小编为大家详细介绍“HTML5中怎么用canvas绘制曲线”,内容详细,步骤清晰,细节处理妥当,希望这篇“HTML5中怎么用canvas绘制曲线”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起...
      99+
      2024-04-02
    • Node.JS怎么使用纯JavaScript生成图片或滑块式验证码功能
      本篇内容介绍了“Node.JS怎么使用纯JavaScript生成图片或滑块式验证码功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!有一些N...
      99+
      2023-06-17
    • vue+F2怎么生成折线图
      本篇内容介绍了“vue+F2怎么生成折线图”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!效果图打开命令窗口,通过 npm 安装F2npm&n...
      99+
      2023-06-29
    • 在WPF中怎么实现平滑滚动
      本篇内容介绍了“在WPF中怎么实现平滑滚动”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!WPF实现滚动条还是比较方便的,只要在控件外围加上S...
      99+
      2023-07-02
    • 怎么在pytorch中绘制一个曲线
      本篇文章为大家展示了怎么在pytorch中绘制一个曲线,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体内容如下import torchimport torch.nn.funct...
      99+
      2023-06-07
    • JavaScript怎么生成二维数组
      今天小编给大家分享一下JavaScript怎么生成二维数组的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。JavaScript...
      99+
      2023-07-05
    • pycharm离线激活码怎么生成
      生成离线激活码需要使用 license server:安装 license server创建激活请求将请求发送到 license server 获取激活码返回 pycharm 激活 P...
      99+
      2024-04-03
      pycharm
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作